MVC 4 TextBoxFor和其他人自动调用HttpUtility.HtmlAttributeEncode

时间:2013-09-05 17:29:32

标签: c# asp.net-mvc razor

问题

我正在尝试在MVC中实现HTML5 / jQuery模型,并且遇到了一个我以前从未遇到的问题;它出现使用Html.TextBoxFor,Html.PasswordFor和其他人都自动编码传递的任何HTML属性。

示例

以以下行为例:

@Html.TextBoxFor(m => m.Pin, new { data_regexp="<\\d{4}>" })

此代码将用于验证信用卡上的PIN码,我需要使用data-regexp模式传递适当的正则表达式。我希望输出如下:

<input data-regexp="<\d{4}>" id="Pin" type="text" />

相反,它似乎是在内置扩展程序中调用HtmlAttributeEncode(http://msdn.microsoft.com/en-us/library/wdek0zbf.aspx),从而产生以下 编码 输出:

<input data-regexp="&lt;\d{4}>" id="Pin" type="text" />

所需解决方案注意事项

除了编写自己的扩展程序外,我还有其他选择吗?使用其他形式的验证不是一个选项,这个例子只是为了显示手头的问题 - 我还有其他一些例子,我需要打印原始HTML,而不是编码版本。

编辑: 使用Html.Raw或HttpUtility.Decode没有任何影响。在应用任何这些之后进行编码。

3 个答案:

答案 0 :(得分:2)

想出来。我添加了以下课程:

namespace MyProjectName.Extensions
{
    public class HtmlAttributeNoEncoding : HttpEncoder
    {
        protected override void HtmlAttributeEncode(string value, TextWriter output)
        {
            output.Write(value);
        }
    }
}

修改了我的网络配置:

<system.web>
    ...
    <httpRuntime targetFramework="4.5" encoderType="MyProjectName.Extensions.HtmlAttributeNoEncoding"/>
    ... 
</system.web>

答案 1 :(得分:1)

尝试使用此自定义HTMLHelper扩展程序:

自定义HtmlHelper扩展程序:

using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace MvcApplication.Extensions
{
    public static class HtmlHelperExtensions
    {
        public static IHtmlString MyTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, object dataAttribute)
        {
            MvcHtmlString textBoxFor = InputExtensions.TextBoxFor<TModel, TProperty>(htmlHelper, expression, htmlAttributes);

            string stringDataAttributes = string.Empty;
            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(dataAttribute))
            {
                stringDataAttributes+= string.Format("data-{0}=\"{1}\" ", property.Name, property.GetValue(dataAttribute));
            }

            string textBoxForText = textBoxFor.ToHtmlString();
            string textBoxWithData = textBoxForText.Insert(textBoxForText.IndexOf("/>"), stringDataAttributes);

            return htmlHelper.Raw(textBoxWithData);
        }
    }
}

CSHTML:

@Html.MyTextBoxFor(m => m.Pin, null, new { regexp = "<\\d{5}>" })

结果:

<input id="Pin" name="Pin" type="text" value="" data-regexp="<\d{5}>" />

答案 2 :(得分:0)

如果在模型上使用数据注释,它将起作用。

[RegularExpression(@"\d{4}", ErrorMessage="4 digit PIN required")]
public string Pin { get; set; }

然后您可以使用TextboxFor而不传递额外的属性:

@Html.TextBoxFor(m => m.Pin)

这会将html返回为:

data-val-regex="4 digit PIN required" data-val-regex-pattern="\d{4}"