Asp.net mvc ASP.NET MVC 2-HTML.EditorFor()和自定义EditorTemplates

Asp.net mvc ASP.NET MVC 2-HTML.EditorFor()和自定义EditorTemplates,asp.net-mvc,templates,preview,Asp.net Mvc,Templates,Preview,随着MVC 2添加了HtmlHelper EditorFor(),不可能为给定的模型对象创建强类型显示和编辑器模板,在处理它之后,我有点困惑于如何在不丢失编辑器控件的强类型的情况下将额外的模型数据传递给编辑器 经典示例:产品具有类别。ProductEditor有一个包含所有类别名称的类别下拉列表。ProductEditor是产品的强类型,我们需要传入类别的SelectList以及产品 使用标准视图,我们将以新类型包装模型数据,并将其传递。在EditorTemplate中,如果传入一个包含多个对象

随着MVC 2添加了HtmlHelper EditorFor(),不可能为给定的模型对象创建强类型显示和编辑器模板,在处理它之后,我有点困惑于如何在不丢失编辑器控件的强类型的情况下将额外的模型数据传递给编辑器

经典示例:产品具有类别。ProductEditor有一个包含所有类别名称的类别下拉列表。ProductEditor是产品的强类型,我们需要传入类别的SelectList以及产品

使用标准视图,我们将以新类型包装模型数据,并将其传递。在EditorTemplate中,如果传入一个包含多个对象的混合模型,我们将失去一些标准功能(我注意到的第一件事是,所有LabelFor/TextBoxFor方法都生成实体名称,如“Model.object”,而不仅仅是“object”)


是我做错了还是Html.EditorFor()应该有一个额外的ViewDataDictionary/Model参数?

您可以创建一个同时具有这两个属性的自定义ViewModel,或者您需要使用ViewData来传递信息。

我仍在学习,但我遇到了一个类似的问题,为此我制定了一个解决方案。 我的类别是一个枚举,我使用一个模板控件来检查枚举以确定Select标记的内容

它在视图中用作:

<%= Html.DropDownList
            (
            "CategoryCode",
            MvcApplication1.Utility.EditorTemplates.SelectListForEnum(typeof(WebSite.ViewData.Episode.Procedure.Category), selectedItem)
            ) %>
SelectListForEnum使用枚举定义和当前选定项的索引构造选定项的列表,如下所示:

        public static SelectListItem[] SelectListForEnum(System.Type typeOfEnum, int selectedItem)
    {
        var enumValues = typeOfEnum.GetEnumValues();
        var enumNames = typeOfEnum.GetEnumNames();
        var count = enumNames.Length;
        var enumDescriptions = new string[count];
        int i = 0;
        foreach (var item in enumValues) 
        {
            var name = enumNames[i].Trim();
            var fieldInfo = item.GetType().GetField(name);
            var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            enumDescriptions[i] = (attributes.Length > 0) ? attributes[0].Description : name;
            i++;
        }
        var list = new SelectListItem[count];
        for (int index = 0; index < list.Length; index++)
        {
            list[index] = new SelectListItem { Value = enumNames[index], Text = enumDescriptions[index], Selected = (index == (selectedItem - 1)) };
        }
        return list;
    }
public static SelectListItem[]SelectListForEnum(System.Type typeOfEnum,int selectedItem)
{
var enumValues=typeOfEnum.GetEnumValues();
var enumNames=typeOfEnum.GetEnumNames();
var count=enumNames.Length;
变量enumDescriptions=新字符串[计数];
int i=0;
foreach(枚举值中的变量项)
{
var name=enumNames[i].Trim();
var fieldInfo=item.GetType().GetField(名称);
var attributes=(DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute),false);
enumDescriptions[i]=(attributes.Length>0)?属性[0]。描述:名称;
i++;
}
var list=新建SelectListItem[计数];
for(int index=0;index
最终的结果是一个表现良好的DDL


希望这有帮助。如果您对更好的方法有任何意见,我们将不胜感激。

请尝试使用ViewData.ModelMetadata。它包含您的所有类注释


优秀的文章

这当然有道理,但我不得不注意,将模型放置在自定义ViewModel中会导致表单字段名称以自定义ViewModel中对象的属性名称作为前缀。这并不是一个问题,但它确实为更新模型添加了另一个步骤。我可能是在发不必要的牢骚,嗯?非常感谢。我已经找了好几天了,上次偶然发现时忘了加书签。
        public static SelectListItem[] SelectListForEnum(System.Type typeOfEnum, int selectedItem)
    {
        var enumValues = typeOfEnum.GetEnumValues();
        var enumNames = typeOfEnum.GetEnumNames();
        var count = enumNames.Length;
        var enumDescriptions = new string[count];
        int i = 0;
        foreach (var item in enumValues) 
        {
            var name = enumNames[i].Trim();
            var fieldInfo = item.GetType().GetField(name);
            var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            enumDescriptions[i] = (attributes.Length > 0) ? attributes[0].Description : name;
            i++;
        }
        var list = new SelectListItem[count];
        for (int index = 0; index < list.Length; index++)
        {
            list[index] = new SelectListItem { Value = enumNames[index], Text = enumDescriptions[index], Selected = (index == (selectedItem - 1)) };
        }
        return list;
    }