Constraints:
- I don't want to use
Nullable
types. - I don't want to instantiate a model class in the
HttpGet
-handlingCreate
action method.
Model class:
namespace MvcTest.Models
{
public enum Gender { Male, Female }
public class Person
{
public Gender Gender { get; set; }
}
}
Templated Editor Helper (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--")
Controller:
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();
}
}
}
View:
@model MvcTest.Models.Person
@using (Html.BeginForm())
{
@Html.EditorFor(x => x.Gender)
<p>
<input type="submit" value="Create" />
</p>
}
Errors:
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
开发者_Python百科 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
Question: How to avoid null exception generated by EditorFor(x=x.Prop) in Create.cshtml when no instance of model class is passed to the view?
AFAIK you need to use nullable enums in order to achieve this. It would also make sense because when a value is not selected (--SELECT--
) the enum must be null. Here's a nice blog post about useful extension methods.
精彩评论