【问题标题】:How to display html elements like links in errors rendered via Html.ValidationSummary()如何在通过 Html.ValidationSummary() 呈现的错误中显示 html 元素,如链接
【发布时间】:2011-08-13 10:27:23
【问题描述】:

我的一条错误消息呈现了一个链接。但是,Html.ValidationSummary() 对其进行了编码,因此显示如下:

您指定的手机或电子邮件帐户已存在。 如果您忘记了密码,请重置它。

相反,它应该呈现为:

您指定的手机或电子邮件帐户已存在。 如果您忘记了密码,请重新设置。

错误添加到ModelState里面的view如下:

if (...)
{
    ViewData.ModelState.AddModelError(string.Empty, string.Format("An account with the mobile or email you have specified already exists. If you have forgotten your password, please {0} it.", Html.ActionLink("Reset", "Reset")));
}

简而言之,我应该如何防止Html.ValidationSummarry() 在错误中选择性/完全编码 html。

【问题讨论】:

标签: c# asp.net-mvc-3 razor


【解决方案1】:

当前用于显示错误消息的 HTML 帮助程序不支持此功能。但是,您可以编写自己的 HTML 帮助程序来显示错误消息而不用 HTML 对其进行转义,即它们会将错误消息视为原始 HTML。

作为起点,您可以使用 Codeplex 的 ASP.NET MVC 源代码,特别是 ValidationExtensions 类的 ValidationSummary 方法:

    public static string ValidationSummary(this HtmlHelper htmlHelper, string message, IDictionary<string, object> htmlAttributes) {
        // Nothing to do if there aren't any errors
        if (htmlHelper.ViewData.ModelState.IsValid) {
            return null;
        }

        string messageSpan;
        if (!String.IsNullOrEmpty(message)) {
            TagBuilder spanTag = new TagBuilder("span");
            spanTag.MergeAttributes(htmlAttributes);
            spanTag.MergeAttribute("class", HtmlHelper.ValidationSummaryCssClassName);
            spanTag.SetInnerText(message);
            messageSpan = spanTag.ToString(TagRenderMode.Normal) + Environment.NewLine;
        }
        else {
            messageSpan = null;
        }

        StringBuilder htmlSummary = new StringBuilder();
        TagBuilder unorderedList = new TagBuilder("ul");
        unorderedList.MergeAttributes(htmlAttributes);
        unorderedList.MergeAttribute("class", HtmlHelper.ValidationSummaryCssClassName);

        foreach (ModelState modelState in htmlHelper.ViewData.ModelState.Values) {
            foreach (ModelError modelError in modelState.Errors) {
                string errorText = GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, null /* modelState */);
                if (!String.IsNullOrEmpty(errorText)) {
                    TagBuilder listItem = new TagBuilder("li");
                    listItem.SetInnerText(errorText);
                    htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal));
                }
            }
        }

        unorderedList.InnerHtml = htmlSummary.ToString();

        return messageSpan + unorderedList.ToString(TagRenderMode.Normal);
    }

然后您可以更改此方法以将错误消息视为原始 HTML。

虽然有两个警告:

  1. 您正在更改 ModelState 类的某些属性的含义。虽然您现在可以使用自己的 HTML 帮助程序,但未来版本的 ASP.NET MVC 可能会引入不再适用于这种方法的更改。

  2. 请务必小心不要使用未正确转义的错误消息,以免您的 Web 应用程序遭受 XSS 攻击。某些标准验证注释可能不再起作用,因为它们不会 HTML 转义错误消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多