在这一点上,这更多是一个理论上的问题,但是无论如何在这里还是有问题的。
简短版本:
有什么方法可以使我自己的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();
}
}
我认为您可以为编辑者使用相同的技术