有没有办法在输出中使用扩展方法扩展基本的html助手(TextBoxFor
,TextAreaFor
等),而不是仅仅重写整个方法?例如,添加...
@Html.TextBoxFor( model => model.Name ).Identity("idName")
我知道我已经可以使用以下内容实现这一目标了。
@Html.TextBoxFor( model => model.Name, new { @id = "idName" })
但是,当您必须开始添加大量属性时,管理变得笨拙和令人沮丧。是否有任何方法可以为这些内容添加扩展,而无需为每个小细节传递htmlAttributes
?
答案 0 :(得分:9)
正如@AaronShockley所说,因为TextBoxFor()
返回MvcHtmlString
,因此开发修改输出的“流体API”风格的唯一选择是对返回的MvcHtmlString
进行操作通过辅助方法。执行此操作的一种略微不同的方式,我认为接近您所使用的将是使用“属性构建器”对象,如下所示:
public class MvcInputBuilder
{
public int Id { get; set; }
public string Class { get; set; }
}
...并设置如下的扩展方法:
public static MvcHtmlString TextBoxFor<TModel, TProp>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProp>> expression,
params Action<MvcInputBuilder>[] propertySetters)
{
MvcInputBuilder builder = new MvcInputBuilder();
foreach (var propertySetter in propertySetters)
{
propertySetter.Invoke(builder);
}
var properties = new RouteValueDictionary(builder)
.Select(kvp => kvp)
.Where(kvp => kvp.Value != null)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
return htmlHelper.TextBoxFor(expression, properties);
}
然后,您可以在视图中执行以下操作:
@this.Html.TextBoxFor(
model => model.Name,
p => p.Id = 7,
p => p.Class = "my-class")
这为您提供了输入属性的强类型和智能感知,您可以通过向适当的MvcInputBuilder子类添加属性来为每个扩展方法自定义。
答案 1 :(得分:6)
所有基本的html助手都返回System.Web.Mvc.MvcHtmlString
类型的对象。您可以为该类设置扩展方法。这是一个例子:
public static class MvcHtmlStringExtensions
{
public static MvcHtmlString If(this MvcHtmlString value, bool check)
{
if (check)
{
return value;
}
return null;
}
public static MvcHtmlString Else(this MvcHtmlString value, MvcHtmlString alternate)
{
if (value == null)
{
return alternate;
}
return value;
}
}
然后您可以在以下视图中使用这些:
@Html.TextBoxFor(model => model.Name)
.If(Model.Name.StartsWith("A"))
.Else(Html.TextBoxFor(model => model.LastName)
要制作修改呈现的HTML标记上的属性的扩展方法,您必须将结果转换为字符串,然后查找并替换您要查找的值。
using System.Text.RegularExpressions;
public static MvcHtmlString Identity(this MvcHtmlString value, string id)
{
string input = value.ToString();
string pattern = @"(?<=\bid=")[^"]*";
string newValue = Regex.Replace(input, pattern, id);
return new MvcHtmlString(newValue);
}
public static MvcHtmlString Name(this MvcHtmlString value, string id)
{
string input = value.ToString();
string pattern = @"(?<=\bname=")[^"]*";
string newValue = Regex.Replace(input, pattern, id);
return new MvcHtmlString(newValue);
}
id
和name
属性总是由html助手添加,但是如果你想使用可能不存在的属性(你必须添加它们而不是仅仅替换它们)他们),你需要修改代码。