我正在使用Visual Studio 2015社区版进行ASP.net MVC项目测试, 这是我的简单模型:
public class TestModel
{
[Required]
public string Name { get; set; }
[UIHint("EnumList")]
public TestState State { get; set; }
}
public enum TestState
{
eNone,
eNew,
eFinished,
}
这是一个通用的html - EnumList.cshtml
@model Enum
@Html.DropDownListFor(m => m, Enum.GetValues(Model.GetType()).OfType<Enum>()
.Select(m =>
{
string enumVal = Enum.GetName(Model.GetType(), m);
return new SelectListItem()
{
Selected = (Model.ToString() == enumVal),
Text = enumVal,
Value = enumVal
};
})
)
如果在Test视图中使用以下版本接受TestModel作为模型,则它可以正常工作。
@Html.EditorForModel()
但是,当我尝试通过以下具体操作使用上面的EnumList.cshtml时:
@Html.Action("Enum", new { pState = Model.State }); <-- used in View html
// below action will be called by above method
[ChildActionOnly]
public PartialViewResult Enum(TestState? pState)
{
return PartialView("~/Views/Shared/EditorTemplates/EnumList.cshtml", pState.HasValue ? pState.Value : TestState.eNone);
}
我遇到以下错误:
值不能为null或为空。 参数名称:名称
下面的来自堆栈跟踪:
[ArgumentException:Value不能为null或为空。
参数名称:名称]
System.Web.Mvc.Html.SelectExtensions.SelectInternal(HtmlHelper htmlHelper,ModelMetadata metadata,String optionLabel,String name,IEnumerable 1 selectList, Boolean allowMultiple, IDictionary
2 htmlAttributes)+589
System.Web.Mvc.Html.SelectExtensions.DropDownListFor(HtmlHelper 1 htmlHelper, Expression
1表达式,IEnumerable 1 selectList, String optionLabel, IDictionary
2 htmlAttributes)+95
System.Web.Mvc.Html.SelectExtensions.DropDownListFor(HtmlHelper 1 htmlHelper, Expression
1表达式,IEnumerable`1 selectList)+60
在c:\ visual studio 2015 \ Projects \ Test \ Test1 \ Views \ Shared \ EditorTemplates \ EnumList.cshtml中的ASP._Page_Views_Shared_EditorTemplates_EnumList_cshtml.Execute():3
System.Web.WebPages.WebPageBase.ExecutePageHierarchy()+197
System.Web.Mvc.WebViewPage.ExecutePageHierarchy()+ 105
如果在测试视图中直接调用DropDownListFor()并使用“m =&gt; m.State”之类的更改,那么它是有效的,所以我认为这个错误与“m =&gt; m”有关,但是什么是正确的表达呢?
提前感谢。
答案 0 :(得分:0)
首先,您对DropDownListFor的使用是错误的(来自DropDownListFor帮助程序的MSDN描述):
使用指定的列表项为指定表达式表示的对象中的每个属性返回HTML select元素。
您将其用于模型本身而不是模型属性!
解释为什么您的方法适用于将TestModel作为模型接受并且不能作为单独的部分视图工作的视图:
默认情况下,编辑器模板为其输入生成id和name属性,作为父前缀(请参阅示例)与当前模型属性名称的组合。例如,当您使用TestModel
作为视图的主模型并使用@Html.EditorForModel()
时,您选择的名称和ID将为State
:
<select name="State" id="State">....
例如,如果您的TestModel
属于ParentTestModel
的属性:
public class ParentTestModel
{
public TestModel TestModelProperty {get;set;}
}
然后您的编辑器模板将呈现为
<select name="TestModelProperty.State" id="TestModelProperty_State">...
将模板渲染为部分视图时,Enum
为模型
m => m
表达式基本上不选择任何属性所以FullHtmlFieldName
是null
。所以这段代码(SelectList助手的内部实现)引发了一个异常:
private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata,
string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple,
IDictionary<string, object> htmlAttributes)
{
string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
if (String.IsNullOrEmpty(fullName))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
} ...