自定义 Helper Method

摘自小牛之路

自定义 Helper Method 模板

前面我们简要介绍了 Helper Method 模板根据 Model 元数据生成 Html 元素的便捷之处。但有时候MVC提供的模板并不能满足我们的需求,这时我们可以为 Model 对象的某个属性自定义一个 Helper Method 模板。

在前文中我们知道,使用 Html.DropDownList(For) 可以为我们创建一个下拉列表,但这个方法有一点不好使,每次使用都需要给它构造器的第二个参数指定数据源,很是不方便。对于频繁使用的下拉列表,我们可以把它做成模板。下面我将通过为 Role 枚举类型(前文有定义)做一个下拉列表模板来演示如何自定义。

按照约定,MVC框架会在 /Views/Shared/EditorTemplates 文件夹下查找自定义的模板。因此我们需要先添加一个EditorTemplates 文件夹,然后在该文件夹下添加一个 Role.cshtml 文件,代码如下:

@model MvcApplication1.Models.Role

@Html.DropDownListFor(m => m, new SelectList(Enum.GetNames(Model.GetType()), Model.ToString()))

这样就做好了一个模板,我们可以像下面这样在一个View中使用它:

@model MvcApplication1.Models.Person

@Html.EditorFor(m => m.Role)

除了 EditorFor,调用任何一个模板化的Helper Method 为 Role 类型的属性呈现元素时都会显示为一个下拉列表,效果如下:

为了让这个功能更通用,使所有枚举类型都可以显示为这样的下拉列表,我们再改造一下这个功能。

删除原来的 Role.cshtml 文件,在同一目录下再新建一个 Enum.cshtml 分部视图,代码参考如下:

@model Enum

@Html.DropDownListFor(m => m, Enum.GetValues(Model.GetType()).Cast<Enum>()
    .Select(m => {
        string enumVal = Enum.GetName(Model.GetType(), m);
        return new SelectListItem() {
            Selected = (Model.ToString() == enumVal),
            Text = enumVal,
            Value = enumVal
        };
    })
)

然后我们可以在 Model 中通过 UIHint 特性来应用它,如下:

public class Person {
    public int PersonId { get; set; }
    ...
    [UIHint("Enum")]
    public Role Role { get; set; }
}

再运行程序看到的效果是和上面一样的。

注意,MVC 是根据属性的类型在 /Views/Shared/EditorTemplates 目录下找自定义的模板的,所以一定要保证模板的文件名和属性类型名一致(或用UIHint特性指定为模板的名称)。

另外,如果自定义的模板和内置的模板同名,MVC会使用自定义的。可以根据这个特点来用自定义的模板替换系统内置的。例如,如果在 EditorTemplates 文件夹下创建一个 Boolean.cshtml,当MVC要为 Boolean 类型的属性呈现 Html 元素时,它会使用自定义的 Boolean.cshtml 分部视图来呈现。 

原文地址:https://www.cnblogs.com/wuyiran/p/6074108.html