ASP.NET MVC-расширение TextBoxFor без перезаписи метода
есть ли какой-либо возможный способ расширить базовые HTML-помощники (TextBoxFor
, TextAreaFor
и т. д.), Используя методы расширения на их выходе, а не просто переписывая все методы полностью? Например, добавление ...
@Html.TextBoxFor( model => model.Name ).Identity("idName")
Я знаю, что могу достичь этого, используя следующее..
@Html.TextBoxFor( model => model.Name, new { @id = "idName" })
но это становится неуклюжим и неприятным для управления, когда вам нужно начать добавлять много свойств. Есть ли способ добавить расширения для них по своей сути, не просто проходя в htmlAttributes
за каждую мелочь?
2 ответов
как говорит @AaronShockley, потому что TextBoxFor()
возвращает MvcHtmlString
, ваш единственный вариант для разработки стиля "fluid API" для изменения вывода будет работать на MvcHtmlString
s возвращается вспомогательными методами. Немного другой способ сделать это, который, я думаю, приближается к тому, что вам нужно, - использовать объект "Property builder", например:
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")
это дает вам сильную типизацию и intellisense для входных свойств, которые вы можете настроить для каждого метода расширения, добавив свойства в соответствующий подкласс MvcInputBuilder.
все основные 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-помощники, но если вы хотите работать с атрибутами, которых может не быть (и вам придется добавлять их вместо того, чтобы просто заменять их), вам нужно будет изменить код.