0

Ok I have looked a while for some answers to my question but seems like the accepted answers works for some but for me isn't.

Below is my current implementation to check if @Model.ListImages is not null

var img = @((Model != null && Model.ListImages != null).ToString().ToLower());
if (img) {
    if (@Model.ListImages.Count() + this.files.length > 8) {
        this.removeFile(file);
        $('#errorMessage').html("Cannot upload more then 8 images for a product.");
        $("#errorDiv").show();
        window.scrollTo(0, 0);
     }
}

The Model

public class ProductVM
{
    [Required]
    public int Id { get; set; }

    [Required]
    [Display(Name = "Category")]
    public int IdCategory { get; set; }

    [Required]
    [Display(Name = "Collection")]
    public int IdCollection { get; set; }

    [Required]
    [Range(0.1, 20000, ErrorMessage = "Please enter a value between 0 and 20000")]
    public decimal Price { get; set; }

    [Required]
    [Display(Name = "Product Name")]
    [StringLength(100, ErrorMessage = "Product name must contain at least {2} characters", MinimumLength = 6)]
    public string Name { get; set; }

    [Required]
    [Display(Name = "Product Description")]
    [StringLength(500, ErrorMessage = "Product name must contain at least {2} characters", MinimumLength = 25)]
    public string Description { get; set; }

    public HttpPostedFileBase[] Listfiles { get; set; }


    public virtual IEnumerable<SelectListItem> Categories { get; set; }
    public virtual IEnumerable<SelectListItem> Collections { get; set; }
    public virtual IEnumerable<Reviews> ListReviews { get; set; }
    public virtual ICollection<Images> ListImages { get; set; }

}
7
  • 2
    And what’s your issue? What error are you given? Commented Mar 16, 2019 at 20:18
  • @DavideVitali There is not an error in my code, it's just going inside the if where I indeed get an error, specifically @Model.ListImages.Count - this will throw the exception Value cannot be null Commented Mar 16, 2019 at 20:27
  • Is that supposed to be JavaScript code with a Razor-inserted value? If // some code is throwing an exception you'll need to share that with us along with a definition for your Model. Commented Mar 16, 2019 at 20:37
  • @Jasen I don't know how can this helps but ok Commented Mar 16, 2019 at 20:44
  • Have you tried ‘img != false’? Commented Mar 16, 2019 at 20:53

3 Answers 3

1

The problem is you are mixing JavaScript and Razor which ought to be avoided. It can be done if done carefully but it leads to hard to read i.e. hard to debug and maintain.

Your code is assuming the Razor will not execute based on JavaScript evaluation. However, this is not the case and the Razor statement will always attempt to evaluate.

// this looks like JavaScript with in-lined Razor.
// The Razor is executed before this JavaScript is executed.
var img = @((Model != null && Model.ListImages != null).ToString().ToLower());

// this is a JavaScript conditional based on a run-time value
if (img) {
    // @Model.ListImages.Count() is evaluated by Razor BEFORE
    // (and in a different context) the if(img) above.
    // But there isn't a Razor condition preventing the execution of .Count()
    // if ListImages is not initialized.
    if (@Model.ListImages.Count() + this.files.length > 8) {
         this.removeFile(file);
   }
}

So you need an Razor conditional to output different JavaScript code.

@* Razor evaluated on the server while rendering the view *@
@if (Model != null && Model.ListImages != null)
{
    var count = Model.ListImages.Count;
    <script>
        // JavaScript evaluated in the client
        var images = @count;  // "hardcoded" count on the server
        if (images > 0)
        {
            removeFile()
        }
    </script>
}

A cleaner way to avoid the mixing is to encode the Razor value into an HTML element.

<div id="image"
     data-count="@((Model != null && Model.ListImages != null) ? Model.ListImages.Count : 0)">
</div>

Then get the value in JavaScript which could run without dynamically outputting different js code.

var count = $("#image").data("count");
if  (count > 0) {
    removeFile();
}
Sign up to request clarification or add additional context in comments.

2 Comments

Yes that should work , but I want to avoid this solution as for me is not suitable because it would imply to duplicate code
The solution I choosed was just to instantiate the object and so will get rid off null exception
0
var length = "@(Model.ListImages.Count())";
if(length > 0){
   // do something
}

3 Comments

Really? How can you acces Count() property if a list or an object is null?
Code only answers are discouraged. Please add some explanation as to how this solves the problem, or how this differs from the existing answers. From Review
I just told that you can do this. You can do what ever stuff you want. If model is null then first check that and then you can do this.
0

JavaScript has a tricky (if you don’t know it) way of checking conditions for truthy and falsy values. When you check for a variable directly in the condition like you did

if (img)

it doesn’t actually check if the value of the variable you provided is false or true, but if that object exists. So, even if img is false, your code will go there and you’ll get a null reference exception.

Try a simple

if (img != false)

but, as suggested in the other answer,

if (@Model && @Model.ListImages && @Model.ListImages.Count() > 0)

is better

8 Comments

Actually that line of code is giving the exception @Model.ImagesList.Count() ,that's why I am trying not to get through that line of code...
@GabrielCostin right, I forgot to check for Model. Edited.
Davide @Model is not null but the property ListImages it is null
@GabrielCostin well, at this point should be clear that to check existence of an object in JavaScript you just have to reference it directly, btw I have edited my answer as to your last comment
Already tried what your answer even before asking the question here
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.