Question

I've got a model like this:

public class ParentViewModel
{
   public class ChildViewModel { get; set; }
   // other properties
}

Then in the view for ParentViewModel, i do this:

@Html.EditorFor(model => model.ChildViewModel)

And it executes my custom editor template, even when Model.ChildViewModel is null. Why? I thought MVC was smart enough to only render the view/template when it has a value. (e.g the default template for null is to not render anything).

Because at the moment, i would have to wrap the HTML in my custom editor template with:

@if (Model != null)

Which seems very silly.

Is this a known problem?

I'm on ASP.NET MVC 3, Razor.

Était-ce utile?

La solution

Rather than testing for null before your partial or inside it you can use a new extension method. This also gives you more options for how to deal with a null model. Here's the extensions I use, it will test for null and either return an empty string or a different partial on a null result. This can be particularly helpful on things like pagers where the page is out of range as you can have a separate partial with your "no results" information.

namespace System.Web.Mvc.Html
{
    public static class nullpartials
    {
        public static MvcHtmlString NullPartial(this HtmlHelper helper, string Partial, object Model)
        {
            if (Model == null)
                return MvcHtmlString.Empty;
            else
                return helper.Partial(Partial, Model);
        }

        public static MvcHtmlString NullPartial(this HtmlHelper helper, string Partial, string NullPartial, object Model)
        {
            if (Model == null)
                return helper.Partial(NullPartial);
            else
                return helper.Partial(Partial, Model);
        }

        public static MvcHtmlString NullPartial(this HtmlHelper helper, string Partial, object Model, ViewDataDictionary viewdata)
        {
            if (Model == null)
                return MvcHtmlString.Empty;
            else
                return helper.Partial(Partial, Model, viewdata);
        }

        public static MvcHtmlString NullPartial(this HtmlHelper helper, string Partial, string NullPartial, object Model, ViewDataDictionary viewdata)
        {
            if (Model == null)
                return helper.Partial(NullPartial, viewdata);
            else
                return helper.Partial(Partial, Model, viewdata);
        }

        public static void RenderNullPartial(this HtmlHelper helper, string Partial, object Model)
        {
            if (Model == null)
            {
                return;
            }
            else
            {
                helper.RenderPartial(Partial, Model);
                return;
            }
        }

        public static void RenderNullPartial(this HtmlHelper helper, string Partial, string NullPartial, object Model)
        {
            if (Model == null)
            {
                helper.RenderPartial(NullPartial);
                return;
            }
            else
            {
                helper.RenderPartial(Partial, Model);
                return;
            }
        }

        public static void RenderNullPartial(this HtmlHelper helper, string Partial, object Model, ViewDataDictionary viewdata)
        {
            if (Model == null)
            {
                return;
            }
            else
            {
                helper.RenderPartial(Partial, Model, viewdata);
                return;
            }
        }

        public static void RenderNullPartial(this HtmlHelper helper, string Partial, string NullPartial, object Model, ViewDataDictionary viewdata)
        {
            if (Model == null)
            {
                helper.RenderPartial(NullPartial, viewdata);
                return;
            }
            else
            {
                helper.RenderPartial(Partial, Model, viewdata);
                return;
            }
        }
    }
}

Edit

Sorry I misready the question being about EditorTemplates. However I see no reason that the same approach can't work for EditorFor, you just have a few more method signatures to replicate.

Autres conseils

I don't think MVC is that smart. It expects if you call a render method (displayFor, EditFor, Partial) and send it a model, then that model will have a value (else NullReferenceException). Your choices as far as I know are:

  1. Either have 2 different views (perhaps 2 different view models?)
  2. Do you model != null check
  3. Use a renderAction method passing a parameter from your primary model that lets that action know if you should return a view/partial view or return nothing.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top