How to handle NullReferenceException with Lambda

6

I have a class to search for DisplayName of my entities, where I pass the entity and class returns a list with the actual values and name of each entity attribute.

My problem is when I search, and some attribute in the entity does not have the DisplayName annotation. I get the error of 'System.NullReferenceException' .

I tried to put where to when I find some value null does not list, but my error occurs when instantiating DisplayName :

.Where(p => p.GetCustomAttribute<DisplayNameAttribute>().DisplayName != null)

How can I solve this problem? because I will have entities with some attributes without displayname and I do not want them to be selected.

Follow the codes:

Advanced Search

public class PesquisaAvancada
{
    public String Valor { get; set; }
    public String Texto { get; set; }

    public static List<PesquisaAvancada> camposPesquisa<T>()
    {
        return typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
                       BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Where(p => p.GetCustomAttribute<DisplayNameAttribute>().DisplayName != null).
                                                                             Select(p => new PesquisaAvancada()
                                                                            {
                                                                                Valor = p.Name,
                                                                                Texto = p.GetCustomAttribute<DisplayNameAttribute>().DisplayName
                                                                            }).ToList();
    }
}

Client Entity

public class Cliente
{
    [Key]
    [DisplayName("Identificador do Cliente")]
    public Guid ClienteId { get; set; }

    [Required]
    // aqui removi o display name e acusa o erro
    public String Nome { get; set; }
    [Required]
    [DisplayName("Nome Fantasia")]
    public String Fantasia { get; set; }
}

Error:

  An unhandled exception of type 'System.NullReferenceException'   occurred in Model.dll

Image for better understanding:

    
asked by anonymous 25.04.2017 / 03:43

3 answers

5

What is happening is that you are trying to access a property of a null object

p.GetCustomAttribute<DisplayNameAttribute>().DisplayName != null

The right thing is to check that GetCustomAttribute returns a valid object, so its where condition is:

.Where(p => p.GetCustomAttribute<DisplayNameAttribute>()!= null)

In the above code all the properties that have the DisplayName attribute are returned.

    
25.04.2017 / 06:07
6

Just use null-conditional operator for C #.

If the return of p.GetCustomAttribute<DisplayNameAttribute>() is null the attempt will not be made to access the property DisplayName and the result will be null .

.Where(p => p.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName != null)

Two questions that might be interesting to take a look at:

  • What is the "."? operator.

  • What is the meaning of the "??" operator

  • See the example below working in .NET Fiddle.

    using static System.Console;
    
    public class Program
    {
        public static void Main()
        {
            var customAttrName = GetCustomAttribute()?.DisplayName; 
            // Isto não estoura erro, ao invés disto, 'customAttrName' recebe null
    
            WriteLine(customAttrName ?? "Null"); //Null será a saída
        }
    
        public static CustomAttr GetCustomAttribute()
        {
            return null;
        }
    }
    
    public class CustomAttr
    {
        public string Name;
        public string DisplayName;
    }
    
        
    25.04.2017 / 13:46
    1

    Does this DisplayName return a string or am I wrong?

    Try to replace:

    p => p.GetCustomAttribute<DisplayNameAttribute>().DisplayName != null
    

    by:

    p => !string.IsNullOrEmpty( p.GetCustomAttribute<DisplayNameAttribute>().DisplayName));
    
        
    25.04.2017 / 04:48