在这一点上,这更多是一个理论上的问题,但是无论如何在这里还是有问题的。

简短版本:
有什么方法可以使我自己的html helper替换标准的html helper(如EditBoxFor),而无需进行全部替换路由(覆盖默认的helper?)或将VS中的全部替换功能限制为仅视图?

长版:
我们构建了一个具有许多视图的MVC应用程序,但是现在我们的客户希望我们添加一些功能,使他可以更改应用程序中的各种文本。它与诸如输入标签,占位符之类的东西有关。我已经写了我自己的EditBoxFor的html helper替代品(它仍然使用和EditBoxFor),它从数据库中加载占位符等,然后将其放入缓存等。我给它起了名字(非常巧妙)EditBoxFor2,它的输入与EditBoxFor相同,因此在视图中,我可以将2添加到助手名称中,并支持此新文本功能。 EditBoxFor已在系统中多次使用,它不是我们正在修改的唯一html帮助器。我可能可以用EditBoxFor替换所有EditBoxFor(或者最好用Html.EditBoxFor(替换Html.EditBoxFor2(),而不用手动更改几千行代码,但是很有可能我会破坏一些view \ controllers \其他辅助对象(我可能忘记了在EditBoxFor中实现Html.EditBoxFor2的一些变体)。所以我想知道是否有某种方式可以用我自己的默认助手来覆盖(使用相同的名称和相同的输入参数)?

最佳答案

您可以通过定义显示模板或编辑器模板(可以在Google上搜索的关键字)来做到这一点。

长话短说,您在〜/ Views / Shared文件夹中创建一个文件夹“ DisplayTemplates”和一个文件夹“ EditorTemplates”。这是一个惯例。

然后,在这些文件夹中,可以为每个默认编辑器添加一个模板。

例如,我用它来为我的电话号码提供模板。

PhoneNumber.cshtml(应为您的班级名称)

@model MyProject.Common.Models.PhoneNumber
<div class="editor-field">
    @Html.DisplayFor(model => model.PhoneNumberType)
    @Html.DisplayFor(model => model.Phone)
</div>


我也用它来显示我的枚举

DisplayTemplates / String.cshtml

@using MyProject.Website.Helpers

@{
    var type = Nullable.GetUnderlyingType(ViewData.ModelMetadata.ModelType) ?? ViewData.ModelMetadata.ModelType;

    @(typeof(Enum).IsAssignableFrom(type) ? EnumViewsHelpers.GetResourceValueForEnumValue(Model) : Model)
}


这样,每次我要显示枚举类型的字段时,它将调用我的助手来显示它。助手将在resources.resx中搜索适当的字符串。

关于编辑器,它将显示一个下拉列表以选择所需的枚举

EditorTemplates / String.cshtml

@using System.Web.Mvc.Html
@using MyProject.Website.Helpers

@{
    var type = Nullable.GetUnderlyingType(ViewData.ModelMetadata.ModelType) ?? ViewData.ModelMetadata.ModelType;

    @(typeof(Enum).IsAssignableFrom(type) ? Html.ExtEnumDropDownListFor(x => x) : Html.TextBoxFor(x => x))
}


这是帮手

public static class EnumViewsHelpers
{
    public static IHtmlString ExtEnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> html, Expression<Func<TModel, TEnum>> expression)
    {
    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);

    var enumType = Nullable.GetUnderlyingType(metadata.ModelType) ?? metadata.ModelType;

    var enumValues = Enum.GetValues(enumType).Cast<object>();

    var items = from enumValue in enumValues
                select new SelectListItem
                {
                    Text = GetResourceValueForEnumValue(enumValue),
                    Value = ((int)enumValue).ToString(),
                    Selected = enumValue.Equals(metadata.Model)
                };

    return html.DropDownListFor(expression, items, string.Empty, null);
}

public static string GetResourceValueForEnumValue<TEnum>(TEnum enumValue)
{
    var key = string.Format("{0}_{1}", enumValue.GetType().Name, enumValue);

    return Resource.ResourceManager.GetString(key) ?? enumValue.ToString();
    }
}


我认为您可以为编辑者使用相同的技术

08-06 19:47