当没有将模型类的实例传递给视图时,如何避免Create.cshtml中的EditorFor(x = x.Prop)生成的null异常?

时间:2011-03-23 08:45:54

标签: c# asp.net asp.net-mvc asp.net-mvc-3

约束:

  1. 我不想使用Nullable类型。
  2. 我不想在HttpGet - 处理Create操作方法中实例化模型类。
  3. 模特课程:

    namespace MvcTest.Models
    {
        public enum Gender { Male, Female }
        public class Person
        {
            public Gender Gender { get; set; }
        }
    }
    

    模板化编辑助手(Gender.cshtml):

    @using MvcTest.Models
    @model Gender
    @{
        var genders = from Gender g in Enum.GetValues(typeof(Gender))
                      select new { Value = g, Text = g.ToString() };
    
        var sl = new SelectList(genders, "Value", "Text", Model);
    }
    @Html.DropDownList(string.Empty, sl, "--Select--")
    

    控制器:

    using System.Web.Mvc;
    using MvcTest.Models;
    
    namespace MvcTest.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Create()
            {
                //Person p = new Person();
                //return View(p);
    
                return View();
            }
    
        }
    }
    

    查看:

    @model MvcTest.Models.Person
    @using (Html.BeginForm())
    {
    
        @Html.EditorFor(x => x.Gender)
        <p>
            <input type="submit" value="Create" />
        </p>
    }
    

    错误:

    Server Error in '/' Application.
    
    The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type 'MvcTest.Models.Gender'.
    
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
    
    Exception Details: System.InvalidOperationException: The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type 'MvcTest.Models.Gender'.
    
    Source Error: 
    
    
    Line 3:  {
    Line 4:      
    Line 5:      @Html.EditorFor(x => x.Gender)
    Line 6:      <p>
    Line 7:          <input type="submit" value="Create" />
    
    Source File: e:\MvcTest\MvcTest\Views\Home\Create.cshtml    Line: 5 
    
    Stack Trace: 
    
    
    [InvalidOperationException: The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type 'MvcTest.Models.Gender'.]
       System.Web.Mvc.ViewDataDictionary`1.SetModel(Object value) +143
       System.Web.Mvc.ViewDataDictionary..ctor(ViewDataDictionary dictionary) +377
       System.Web.Mvc.WebViewPage`1.SetViewData(ViewDataDictionary viewData) +27
       System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +99
       System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +115
       System.Web.Mvc.Html.TemplateHelpers.ExecuteTemplate(HtmlHelper html, ViewDataDictionary viewData, String templateName, DataBoundControlMode mode, GetViewNamesDelegate getViewNames, GetDefaultActionsDelegate getDefaultActions) +584
       System.Web.Mvc.Html.TemplateHelpers.TemplateHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName, String templateName, DataBoundControlMode mode, Object additionalViewData, ExecuteTemplateDelegate executeTemplate) +1027
       System.Web.Mvc.Html.TemplateHelpers.TemplateHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName, String templateName, DataBoundControlMode mode, Object additionalViewData) +66
       System.Web.Mvc.Html.TemplateHelpers.TemplateFor(HtmlHelper`1 html, Expression`1 expression, String templateName, String htmlFieldName, DataBoundControlMode mode, Object additionalViewData, TemplateHelperDelegate templateHelper) +118
       System.Web.Mvc.Html.TemplateHelpers.TemplateFor(HtmlHelper`1 html, Expression`1 expression, String templateName, String htmlFieldName, DataBoundControlMode mode, Object additionalViewData) +100
       System.Web.Mvc.Html.EditorExtensions.EditorFor(HtmlHelper`1 html, Expression`1 expression) +57
       ASP._Page_Views_Home_Create_cshtml.Execute() in e:\MvcTest\MvcTest\Views\Home\Create.cshtml:5
       System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +207
       System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +81
       System.Web.WebPages.StartPage.RunPage() +19
       System.Web.WebPages.StartPage.ExecutePageHierarchy() +65
       System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +76
       System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +220
       System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +115
       System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +303
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
       System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +23
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +260
       System.Web.Mvc.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b() +19
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +177
       System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
       System.Web.Mvc.Controller.ExecuteCore() +116
       System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
       System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
       System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
       System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
       System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
       System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
       System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
       System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
       System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
       System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
       System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
       System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862381
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
    
    Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.225
    

    问题: 当没有将模型类的实例传递给视图时,如何避免Create.cshtml中的EditorFor(x = x.Prop)生成的null异常?

1 个答案:

答案 0 :(得分:2)

AFAIK您需要使用可空的枚举才能实现此目的。这也是有意义的,因为当未选择值(--SELECT--)时,枚举必须为空。这是关于有用扩展方法的nice blog post