Остановить построитель тегов, избегая одинарных кавычек ASP.NET MVC 2 - PullRequest
16 голосов
/ 13 октября 2010

У меня есть следующий 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" />

Есть ли в любом случае, я могу остановить это поведение?

Ответы [ 4 ]

14 голосов
/ 13 октября 2010

Это на самом деле проблема с .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"/>

Я нашел это здесь .

9 голосов
/ 10 июля 2013

Хотя решение, предоставленное Райаном, может работать, это все равно, что использовать молоток, чтобы ударить муху.

Проблема заключается в том, что TagBuilder кодирует строки во время вызовов MergeAttributes (). Для необходимого Javascript в ссылке кнопки это влияет на одинарные кавычки и пробелы.

Последним шагом требуемого метода расширения является возврат MvcHtmlString (который не получает дальнейшей кодировки), поэтому вполне разумно внести некоторые простые текстовые исправления в строку (чтобы отменить кодировку) перед созданием этого объект.

, например

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

Полный помощник ActionLinkButton показан ниже:

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, и не может привести к неожиданным изменениям в масштабах всего приложения путем изменения процесса кодирования атрибута.

0 голосов
/ 20 января 2016

Я немного опоздал на дискотеку, но вы могли бы расшифровать HTML перед возвратом:

return new MvcHtmlString(System.Web.HttpUtility.HtmlDecode(tb.ToString(TagRenderMode.Normal));
0 голосов
/ 23 мая 2015

TagBuilder не кодирует строку во время MergeAttribute, так как непосредственно манипулирует свойством Атрибуты, а затем получение строкового представления с помощью ToString() также исключает символы. Скорее всего, кодировка происходит во время ToString().

Класс ниже решает проблему с JavaScript:

public class JavaScriptTagBuilder : TagBuilder
{
    public string OnClick { get; set; }

    public JavaScriptTagBuilder(string tagName)
        : base(tagName)
    {
    }

    public override string ToString()
    {
        string openingTag = "<" + TagName;
        return base.ToString().Replace(openingTag, string.Format("{0} onclick=\"{1}\"", openingTag, OnClick));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...