由于表达式的原因DropDownListFor在局部视图中失败

我正在使用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
        };
    })
)

如果在接受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);
}

我有以下错误:

值不能为空或空白。 参数名称:名称

下面是来自栈跟踪:

[ArgumentException:值不能为空或空。 参数名称:名称] System.Web.Mvc.Html.SelectExtensions.SelectInternal(HtmlHelper htmlHelper,ModelMetadata元数据,字符串optionLabel,字符串名称,IEnumerable 1 selectList, Boolean allowMultiple, IDictionary 2 htmlAttributes)+589 System.Web.Mvc.Html。 SelectExtensions.DropDownListFor(HtmlHelper 1 htmlHelper, Expression 1 expression,IEnumerable 1 selectList, String optionLabel, IDictionary 2 htmlAttributes)+95 System.Web.Mvc.Html.SelectExtensions.DropDownListFor(HtmlHelper 1 htmlHelper, Expression 1 expression,IEnumerable`1 selectList) +60 ASP._Page_Views_Shared_EditorTemplates_EnumList_cshtml.Execute()in c: visual studio 2015 Projects Test Test1 Views Shared EditorTemplates EnumList.cshtml:3 System.Web.WebPages.WebPageBase.ExecutePageHierarchy()+197 System.Web .Mvc.WebViewPage.ExecutePageHierarchy()+105

如果上面的DropDownListFor()直接在测试视图中调用,并且像“m => m.State”这样的变化,那么它就会起作用,所以我相信这个错误与“m => m”有关,但是什么是正确的表达呢?

提前致谢。


首先,您对DropDownListFor的使用是错误的(从DropDownListFor帮助器的MSDN描述中):

使用指定的列表项为指定表达式表示的对象中的每个属性返回一个HTML select元素。

您将其用于模型本身,而不是用于模型属性!

解释为什么你的方法使用视图接受TestModel作为模型,不能作为单独的局部视图工作:

默认情况下,编辑器模板为其输入生成id和name属性,作为父前缀(参见示例)与当前模型属性名称的组合。 例如,当您使用TestModel作为视图的主模型并使用@Html.EditorForModel() ,您选择的名称和ID将为State

<select name="State" id="State">....

例如,如果您的TestModelParentTestModel的属性:

public class ParentTestModel
{
    public TestModel TestModelProperty {get;set;}
}

然后你的编辑模板将被渲染为

<select name="TestModelProperty.State" id="TestModelProperty_State">...

当您使用Enum作为模型将模板呈现为局部视图时

  • 父母前缀为空 - 通常,部分视图不保留这些前缀,在这种特殊情况下根本没有前缀,因为它的顶级模型和
  • 属性名称为空 - 因为m => m表达式,它基本上不选择任何属性
  • 所以FullHtmlFieldNamenull 。 所以这段代码(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");
                } ...
    
    链接地址: http://www.djcxy.com/p/19089.html

    上一篇: DropDownListFor failed in partial view due to expression

    下一篇: 5: Show Full Names