2011-03-23 14 views
0

約束:如何避免模型類的實例傳遞給視圖時CreateFshtml中EditorFor(x = x.Prop)生成的null異常?

  1. 我不想使用Nullable類型。
  2. 我不想在HttpGet -handling Create操作方法中實例化模型類。

模型類:

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 

問: 如何避免EditorFor(X = x.Prop)在Create.cshtml時產生的空異常沒有模型類的實例被傳遞給視圖?

+0

您的第二個要求是與絕佳的良好實踐以及視圖模型的強類型視圖的矛盾。 – 2011-03-23 08:55:13

+0

@Darin:因爲我希望下拉控件默認使用'--Select - '填充,而不是使用'Male'或'Female'填充。 – LaTeX 2011-03-23 08:57:26

+0

@Darin:我放棄了,我應該使用可爲空的枚舉:D – LaTeX 2011-03-23 09:36:35

回答

2

AFAIK您需要使用可爲空的枚舉才能實現此目的。這也是有意義的,因爲當沒有選擇一個值時(--SELECT--),枚舉必須爲空。這是關於有用的擴展方法的nice blog post

+0

@Darin:你確定編輯器模板可以用於'Edit'動作方法嗎?在問這個問題之前,我已經嘗試過了。下拉控件將​​在'Edit.cshtml'中被選中。下拉列表控件不反映性別屬性。 – LaTeX 2011-03-23 09:04:57

+0

@Administrator,你是對的。我的初始答案不適用於編輯操作,它不會根據模型在下拉列表中預選正確的值。你找到的解決方案應該可以工作,但我會堅持使用可爲空的枚舉,因爲它們在語義上會更適合這種情況。 – 2011-03-23 09:14:47

+0

@Darin:請參閱我的更新,我將您以前的解決方案與@ Branislav的''結合使用? :'操作員。 – LaTeX 2011-03-23 09:18:02

相關問題