views:

87

answers:

6

This is a question about style and design rather than syntax.

I have domain models that have several (for lack of a better term) navigation properties. So in my strongly typed details view of Foo which has a property of type Bar I could do the following:

<%: Foo.Bar.Name %>

However, sometimes Bar is Null, so I end up with something like:

<%: Foo.Bar == null ? String.Empty : Foo.Bar.Name %>

In other cases, because the convenience of the navigation properties I could do even more chaining. The downside, however, is the introduction of more null checking in my View.

As an alternative, I could do all the null checking in a ViewModel so that I've passed off something "clean" to the View. I'm looking for some ideas or common sense guidelines for avoiding excessive null checking in my views.

P.S. I'm using ASP.NET MVC, but I think this question may be relevant to other MVC frameworks.

A: 

Create a helper that checks for null and returns an appropriate default.

For example if you have a phone number field, you pass it the field and a constant PHONE. the helper checks if null and displays "No phone number Available" if it is null.

This way you keep all your null checking in one place.

Byron Whitlock
A: 

One option is using a helper, as described here.

RandomNoob
That link only shows how to check for null strings, the answer even says.. "Of course if it's UserModified that's null and not UserName then you'll need some different logic"
Rohan West
A: 

You could provide lazy initialization for your navigation properties in you model. That way you could minimize the risk of encountering null values.

public class Foo
{
    private Bar _bar;

    public Bar Bar
    {
        get
        {
            if (_bar == null)
            {
                _bar = new Bar();
            }
            return _bar;
        }
    }
}

public class Bar
{
    public string Name { get; set; }
}
Rohan West
I certainly could do that, but in some cases a null value is the correct value. Encountering null simply because I haven't loaded the property is a different concern.
Larsenal
Thats why you should use a Null object pattern. Model that valid null value as a NullBar and then add the logic to deal with the nullness inside the NullBar class for ex. logging etc.
Unmesh Kondolikar
A: 

Not sure whether it really makes sense in your context, but when you are bothered by an excess of null-checks, you should contemplate the Null Object pattern.

Don Roby
+2  A: 

You already answered it yourself:

As an alternative, I could do all the null checking in a ViewModel so that I've passed off something "clean" to the View.

That's it, use a ViewModel.

eglasius
Is this good practice? Would that be reason alone to use a ViewModel if otherwise my pure domain Model would suffice?
Larsenal
@Larsenal while there are other reasons to use a ViewModel, a very good reason I use them is to keep code off the views. The scenario you posted happens to be one that benefits from it, but you'll definitely see more scenarios where views can have less conditional checks by moving code to the view models.
eglasius
Another reason to use it is because its very effective + simple in reducing what you allow to be posted to your controllers. Additionally you can put asp.net some attributes in there that would otherwise make it to your original model. All that said, in very small projects I usually switch between using models and view models, as sometimes the model just fits the bill.
eglasius
A: 

First consider whether in your model an instance of Foo is valid if Bar is null. If no then you should put a guard clause in the constructor and\or the setter of the Bar property.

public class Foo{

        public BarClass _bar;

        public BarClass Bar{
            get{return _bar; }
            set{
                if(value == null)
                   throw new ArgumentNullException();
                _bar = value; } 
            } 

           public Foo(BarClass bar){
              if(bar == null) throw new ArgumentNullException();
              _bar = bar;
          } 
        }

Secondly, too many and duplicated null checks is a code smell. You should use the refactoring Replace Conditional with Polymorphism. You can create a Null object according to the Null Object Pattern. Then make sure that the Bar property is always initialized with NullBar.

public class Foo{

    public BarClass _bar;

    public BarClass Bar{
        get{return _bar ?? new NullBar(); }
        set{ _bar = value ?? new NullBar(); } 
    } 

       public Foo(){
          Bar = new NullBar(); // initialization
       } 
    }

Then Bar will never be null.

Unmesh Kondolikar