如何停止标记生成器转义单引号ASP.NET MVC 2?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (42)

我有下面的HtmlHelper方法,我想创建一个按钮,用JavaScript重定向:

public static string JavaScriptButton(this HtmlHelper helper, string value,
                        string action, string controller, object routeValues = null, object htmlAttributes = null)
{
    var a = (new UrlHelper(helper.ViewContext.RequestContext))
                            .Action(action, controller, routeValues);

    var builder = new TagBuilder("input");
    builder.Attributes.Add("type", "submit");
    builder.Attributes.Add("value", value);
    builder.Attributes.Add("class", "button");
    builder.Attributes.Add("onclick", string.Format("javascript:location.href='{0}'", a));
    builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));

    return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing)).ToString();         
}

问题在于创建onclick处理程序的行被tagbuilder转义,结果html为:

<input class="button" onclick="javascript:location.href=&#39;&#39;" type="submit" value="Return to All Audits" />

无论如何,我可以阻止这种行为吗?

提问于
用户回答回答于

这实际上是.NET 4.0的一个问题。要修复它,你需要重写属性编码过程。

public class HtmlAttributeNoEncoding : System.Web.Util.HttpEncoder
{
    protected override void HtmlAttributeEncode(string value, System.IO.TextWriter output)
    {
        output.Write(value);
    }
}

然后把这个放在你的web.config文件的<system.web>元素下:

<httpRuntime encoderType="HtmlAttributeNoEncoding"/>

我在这里找到

用户回答回答于

问题是TagBuilder在对MergeAttributes()的调用期间对字符串进行编码。对于按钮链接中所需的Javascript,这会影响单引号和空格。

所需扩展方法的最后一步是返回MvcHtmlString(不再接收进一步编码),因此在创建该对象之前对字符串进行一些简单的文本更正(以撤消编码)是完全合理的。

return new MvcHtmlString(tb.ToString(TagRenderMode.Normal).Replace("&#39;", "\'").Replace("&#32;"," "));

下面显示了一个完整的ActionLinkBut​​ton帮助器:

public static class ActionLinkButtonHelper
{
    public static MvcHtmlString ActionLinkButton(this HtmlHelper htmlHelper, string buttonText, string actionName, object routeValuesObject = null, object htmlAttributes = null)
    {
        return ActionLinkButton(htmlHelper, buttonText, actionName, "", routeValuesObject, htmlAttributes);
    }
    public static MvcHtmlString ActionLinkButton(this HtmlHelper htmlHelper, string buttonText, string actionName, string controllerName, object routeValuesObject = null, object htmlAttributes = null)
    {
        if (string.IsNullOrEmpty(controllerName))
        {
            controllerName = HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString();
        }
        RouteValueDictionary routeValues = new RouteValueDictionary(routeValuesObject);
        RouteValueDictionary htmlAttr = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        TagBuilder tb = new TagBuilder("button");
        tb.MergeAttributes(htmlAttr, false);
        string href = UrlHelper.GenerateUrl("default", actionName, controllerName, routeValues, RouteTable.Routes, htmlHelper.ViewContext.RequestContext, false);

        tb.MergeAttribute("type", "button");
        tb.SetInnerText(buttonText);
        tb.MergeAttribute("value", buttonText);
        tb.MergeAttribute("onclick", "location.href=\'"+ href +"\';return false;");
        return new MvcHtmlString(tb.ToString(TagRenderMode.Normal).Replace("&#39;", "\'").Replace("&#32;"," "));
    }
}

这样可以完成添加按钮链接所需的所有工作,具有最有用的重载,ActionLink并且通过更改属性编码过程可能不会导致意外的应用程序范围更改。

扫码关注云+社区