【问题标题】:Adding same classes to all html.textbox on asp.net mvc将相同的类添加到 asp.net mvc 上的所有 html.textbox
【发布时间】:2014-04-24 12:53:20
【问题描述】:

我有一个使用 ASP.NET MVC 4 的项目,最近使用 Bootstrap 进行了视觉改进。

虽然我很满意,但也有人觉得我不是很满意。

我不得不添加

new { @class = "form-control input-sm" } 

我所有的 Html.TextBox 助手调用。我想知道是否有更优雅的方式来做到这一点......也许会覆盖默认的 TextBox 帮助器?

对此的任何见解将不胜感激。

【问题讨论】:

    标签: asp.net asp.net-mvc twitter-bootstrap


    【解决方案1】:

    编辑

    它实际上是可行的 - 覆盖扩展方法。参考见:How to override an existing extension method

    视图在“ASP”命名空间中创建;因此,为了让您的扩展方法覆盖 System.Web.Mvc.Html(即静态类 InputExtensions)中的默认扩展方法,您还必须在“ASP”命名空间中声明您的覆盖。因此,在您的 MVC 项目中,像这样定义类 InputExtensionOverride.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq.Expressions;
    using System.Web.Mvc;
    
    namespace ASP {
      public static class InputExtensionsOverride {
        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
          return InputExtensionsOverride.TextBoxFor<TModel, TProperty>(htmlHelper, expression, (string)null);
        }
    
        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {
          return InputExtensionsOverride.TextBoxFor<TModel, TProperty>(htmlHelper, expression, (string)null, htmlAttributes);
        }
    
        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
          var dictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
          return InputExtensionsOverride.TextBoxFor<TModel, TProperty>(htmlHelper, expression, (string)null, dictionary);
        }
    
        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string format) {
          return InputExtensionsOverride.TextBoxFor<TModel, TProperty>(htmlHelper, expression, format, ((IDictionary<string, object>)null));
        }
    
        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string format, IDictionary<string, object> htmlAttributes) {
          htmlAttributes = SetCommonAttributes<TModel, TProperty>(htmlHelper, expression, ref htmlAttributes);
          return System.Web.Mvc.Html.InputExtensions.TextBoxFor(htmlHelper, expression, format, htmlAttributes);
        }
    
        private static IDictionary<string, object> SetCommonAttributes<TModel, TProperty>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, ref IDictionary<string, object> htmlAttributes) {
          if (htmlHelper == null) {
            throw new ArgumentNullException("htmlHelper");
          }
    
          if (expression == null) {
            throw new ArgumentNullException("expression");
          }
    
          if (htmlAttributes == null) {
            htmlAttributes = new Dictionary<string, object>();
          }
    
          if (!htmlAttributes.ContainsKey("class")) {
            htmlAttributes.Add("class", "form-control input-sm");
          }
    
          return htmlAttributes;
        }
      }
    
    }
    

    在您看来没有变化 - 即:

    @using (Html.BeginForm()) {
       @Html.TextBoxFor(m => m.SomeProperty)
    }
    

    将使用您的“form-control input-sm”css 类生成文本框。

    【讨论】:

    • 这可能是一个不错的选择,但是我想将解决方案扩展到我们所有的项目,并且我想让它对我们的其他开发人员尽可能透明,并且当然,尽量简化自己的工作。那么,有没有办法可以改变实际 TextBox 的方法行为?如果可以的话,我只需将更改复制到其余项目和我们的通用框架中,所有内容都会更新,而无需更改更多代码。
    • 这正是我想要的。我已经对其进行了测试并且可以完美运行。我认为可能是常见问题的绝佳解决方案。
    • 强调 ASP 命名空间。在 MVC5 中非常适合添加 Bootstrap 3 类。谢谢!
    【解决方案2】:

    我认为你应该简单地使用 jquery 为输入字段添加类。

    $('input[type=text]').addClass('form-control input-sm');
    

    为文本框添加自定义帮助器类不会有帮助,因为您必须在许多地方再次更改代码。

    例如,如果这是您的自定义帮助文本框

    public static class MyHtmlHelpers
    {
        public static MvcHtmlString MyTextBoxFor<TModel, TProperty>(
             this HtmlHelper<TModel> helper, 
             Expression<Func<TModel, TProperty>> expression)
        {
            return helper.TextBoxFor(expression, new { @class = "form-control input-sm" }) 
        }
    }
    

    您必须将TextBoxFor 转换为MyTextBoxFor

    @Html.MyTextBoxFor(model => model.FirstName) 
    

    【讨论】:

    • 这正是我想知道覆盖实际方法的原因。我喜欢在我们所有的项目中使用 Bootstrap 的想法,并且我希望它对其他开发人员来说是透明的,所以如果我在我们的通用项目中更改 TextBox 方法的行为,他们现在只会看到我们的输入更“用户友好”。您的解决方案是个好主意,而且看起来很公平,但是在接受之前我会深入研究一下我的第一个选项。
    • 似乎没有办法覆盖保持相同签名的 Html Helper,除非在不同的命名空间上完全重建整个库,因此您的解决方案是最干净的。不是我想申请的,但肯定是有效且无忧的!
    • 经过编辑后,我已将答案更改为 Ondrej 的答案,因为他终于找到了我想要的答案。您的答案也是有效的(并且涉及的代码更少),但是我认为他的答案更清晰。我想批准这两个作为有效答案:(
    猜你喜欢
    • 1970-01-01
    • 2012-01-19
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多