4

I have the following code:

protected IEnumerable<string> GetErrorsFromModelState() {

    var exceptions = ModelState.SelectMany(x => x.Value.Errors
        .Select(error => error.Exception.Message));

    var errors = ModelState.SelectMany(x => x.Value.Errors
        .Select(error => error.ErrorMessage));

    return exceptions.Union(errors);
}

Is there a way that I could stop this giving a nullReference Exception if:

error.Exception is null  or if error.Exception.Message is null

Both cases are giving me problems and I'm not sure how I can code this with a IsNullOrEmpty check for both cases.

4 Answers 4

2

How about

protected IEnumerable<string> GetErrorsFromModelState()
{        
    var exceptions = ModelState.SelectMany(x => x.Value.Errors
                            .Where(error => (error != null) && 
                                            (error.Exception != null) &&
                                            (error.Exception.Message != null))
                            .Select(error => error.Exception.Message));

    var errors = ModelState.SelectMany(x => x.Value.Errors
                            .Where(error => (error != null) && 
                                            (error.ErrorMessage != null))
                            .Select(error => error.ErrorMessage));

    return exceptions.Union(errors);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. this works good. Couple of spelling errors with Exeception :-)
I would leave out the Exception.Message check. If an exception somewhere is having its message set to null, I want to know about that bug so I can track it down at source.
2

Add in a .Where(error.Exception != null && error.Exception.Message != null) before your select to only include ones where the values you want are not null.

1 Comment

Then add that to I, before what I answered with
2

You could use May be Monad, First write an static class and put With extension method in that class, then simply use With method. In the link there are some other similar types which are also helpful.

public static TResult With<TInput, TResult>(this TInput o, 
       Func<TInput, TResult> evaluator)
       where TResult : class where TInput : class
{
  if (o == null) return null;
  return evaluator(o);
}

And use it simply:

var exceptions = ModelState.SelectMany(x => x.With(y=>y.Value).With(z=>z.Errors))
        .Select(error => error.With(e=>e.Exception).With(m=>m.Message));

Update: for making more clear (similar sample also exists in link), assume you have Person class hierarchy:

public class Person
{
   public Address Adress{get;set;}
}

public class Address
{
   public string PostCode{get;set;}
}

Now you want to get person's related post code and you don't know input person is null or not:

var postCode = 
// this gives address or null, if either person is null or its address
person.With(x=>x.Address) 
// this gives post code or returns null, 
// if previous value in chain is null or post code is null 
      .With(x=>x.PostCode);

Comments

1

To filter out the nulls, then .Where(error => error.Exception != null) (the Exception object should always have a non-null message, so I'd count it as a bug to detect and fix there if there's an exception).

To behaved differently in such a case, then e.g. .Select(error => error.Exception == null ? "No Error" : error.Exception.Message).

Comments

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.