ASP.NET MVC - 扩展 TextBoxFor 而不重写方法

发布于 2024-11-12 04:57:49 字数 418 浏览 0 评论 0原文

有没有可能的方法来扩展基本的 html 帮助器(TextBoxForTextAreaFor 等),在其输出上使用扩展方法,而不是完全重写整个方法?例如,添加...

@Html.TextBoxFor( model => model.Name ).Identity("idName")

我知道我已经可以使用以下方法实现此目的..

@Html.TextBoxFor( model => model.Name, new { @id = "idName" })

但是,当您必须开始添加大量属性时,管理起来会变得笨拙且令人沮丧。有没有什么方法可以在本质上添加扩展,而不只是为每个小细节传递 htmlAttributes

Is there any possible way to extend the basic html helpers (TextBoxFor, TextAreaFor, etc) using extension methods on their output, instead of just re-writing the entire methods completely? For instance, adding in ...

@Html.TextBoxFor( model => model.Name ).Identity("idName")

I know I can achieve this using the following, already..

@Html.TextBoxFor( model => model.Name, new { @id = "idName" })

But that gets clunky and frustrating to manage when you have to start adding a lot of properties. Is there any way to add extensions to these inherently without just passing in htmlAttributes for every little detail?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海夕 2024-11-19 04:57:49

正如 @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 子类来自定义每个扩展方法。

As @AaronShockley says, because TextBoxFor() returns an MvcHtmlString, your only option for developing a 'fluid API' style of amending the output would be to operate on the MvcHtmlStrings returned by the helper methods. A slightly different way of doing this which I think approaches what you're after would be to use a 'property builder' object, like this:

public class MvcInputBuilder
{
    public int Id { get; set; }

    public string Class { get; set; }
}

...and to set up extension methods like this:

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);
}

You can then do stuff like this in your View:

@this.Html.TextBoxFor(
    model => model.Name,
    p => p.Id = 7,
    p => p.Class = "my-class")

This gives you strong typing and intellisense for input properties, which you could customise for each extension method by adding properties to an appropriate MvcInputBuilder subclass.

我的黑色迷你裙 2024-11-19 04:57:49

所有基本 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);
}

idname 属性始终由 html 帮助器添加,但如果您想使用可能不存在的属性(并且您必须添加它们)只是替换它们),您需要修改代码。

All of the basic html helpers return an object of type System.Web.Mvc.MvcHtmlString. You can set up extension methods for that class. Here is an example:

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;
    }
}

Then you can use these in a view like:

@Html.TextBoxFor(model => model.Name)
     .If(Model.Name.StartsWith("A"))
     .Else(Html.TextBoxFor(model => model.LastName)

To make extension methods that modify attributes on the rendered HTML tag, you'll have to convert the result to a string, and find and replace the value you're looking for.

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);
}

The id and name attributes are always added by the html helpers, but if you want to work with attributes that may not be there (and you'll have to add them instead of just replacing them), you'll need to modify the code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文