1

I am using MVC3, Razor, C#.

I have a some Razor code which include some LINQ. It tries to get a value from a List. Sometimes the List is null. At present the application is raising a null exception due to this ie "myCustomers" is null.

The code:

Model.myCustomers.First().Name

Basically "myCustomers" is defined as:

public List<Customer> myCustomers

And populated by a "LINQ to Entity" Query.

If "myCustomers" is null, how can I ensure the razor code does not crash. I do not want to write lots of "if (Name!=null)" type blocks for each property. I cannot iterate through all the properties due to layout design issues. So I need to alter:

Model.myCustomers.First().Name

in some way.

Hopefully this question is not too confusing !

many thanks in advance.

EDIT 1

I like the logic with not returning nulls, but empty lists. I tried using something like

return this._myCustomers ?? Enumerable.Empty<Customers>().ToList(); 

It would be ideal to have someway to test this in the one line of LINQ in the Razor page for being empty rather than in an "IF" block.

EDIT 2

    public static TValue SafeGet<TObject, TValue>(
        this TObject obj,
        Func<TObject, TValue> propertyAccessor)
    {
        return obj == null ? default(TValue) : propertyAccessor(obj);
    }

So:

   Model.myCustomers.FirstOrDefault().SafeGet(m=>m.Name)
1
  • Could myCustomers also be an empty list? If that's possible you'd also have to check for that or else the First() will throw an exception. Commented Oct 3, 2013 at 21:44

3 Answers 3

2

Collection or enumerable should never return null value for best practice.

Once you make sure that myCustomers is not null, you will only need to check myCustomers's first item is not null.

var customer = Model.myCustomers.FirstOrDefault();
if (customer != null)
{
   var name = customer.Name;
}
Sign up to request clarification or add additional context in comments.

4 Comments

I like the logic here, and have added EDIT 1 with code. Just trying to test this "empy" code in the one line rather than an "if" block. Is this not possible? Many thanks.
return this._myCustomers ?? new List<Customers>(); is also fine.
OK, thanks for this. Yes I discovered this. How could I use my one liner in the Razor view which could check for empty lists that this would produce. If found then perhaps write out nothing. I was rather hoping to not use an "if" block, but rather something more succinct?
I used an extension method that I forgot I had, but originally sourced from SO, so I have posted it under EDIT2. Interestingly, since I was writing a Razor View, there was the option of just creating 2 block of HTML, one with to process when records present and the other when records absent. So clearly a choice between clever LINQ or copy/paste HTML although the later is simple it does seem more duplicated and less eloquent. Thanks again. Learnt much from this question
1

I cannot iterate through all the properties due to layout design issues.

I'm not exactly clear on what this means, but could you not do something like this?

@if (Model.myCustomers == null || !Model.myCustomers.Any())
{
    <p>No customer found.</p>
}
@else
{
    [ put the markup for each property here ]
}

1 Comment

Thanks for this. This did give me the idea of copying and pasting 2 bits of HTML, one for records present, and the other when absent. However the code could get a bit duplicated. Thanks again.
1

If your collection is not null, then in your razon view you can use

 Model.myCustomers.Any() ? Model.myCustomers.First().Name : string.Empty;

If for some reason you can not avoid your collection to be null, I guess you can do something like this.

 Model.myCustomers == null ? string.Empty : Model.myCustomers.Any() 
       ? Model.myCustomers.First().Name : string.Empty;

1 Comment

Thanks for this. Totally get the logic. I ended up going with an extension method which makes it more succinct. Thanks again.

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.