Asp.net

停止標籤生成器轉義單引號 ASP.NET MVC 2

  • January 20, 2016

我有以下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 處理程序的行被標記生成器轉義,生成的 html 是:

<input class="button" onclick="javascript:location.href=''" 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);
   }
}

然後將其放在<system.web>元素下的 web.config 文件中:

<httpRuntime encoderType="HtmlAttributeNoEncoding"/>

我在這裡找到了這個。

雖然 Ryan 提供的解決方案可能有效,但它有點像用錘子打蒼蠅。

問題是 TagBuilder 在呼叫 MergeAttributes() 期間對字元串進行編碼。對於按鈕連結中所需的 Javascript,這會影響單引號和空格。

所需擴展方法的最後一步是返回 an MvcHtmlString(它不接收進一步的編碼),因此在創建該對象之前對字元串進行一些簡單的文本更正(以撤消編碼)是完全合理的。

例如

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

一個完整的 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("'", "\'").Replace(" "," "));
   }
}

這完成了添加按鈕連結所需的一切,具有您使用的最有用的重載,ActionLink並且不會通過更改屬性編碼過程而潛在地導致意外的應用程序範圍的更改。

引用自:https://stackoverflow.com/questions/3924861