我想添加一个ModelState错误,如下所示:
ModelState.AddModelError("", "Some message, <a href="/controller/action">click here</a>)
但是,链接不会被编码,因此显示为文本。我尝试使用
<%= Html.ValidationSummary(true, "Some message")
而不是
<%: Html.ValidationSummary(true, "Some message")
但没有运气。
任何人都知道如何让这个工作?
干杯
答案 0 :(得分:19)
最简单的方法(也适用于MVC 4):
在控制器中:
ModelState.AddModelError("", "Please click <a href=\"http://stackoverflow.com\">here</a>");
在视图中:
if (ViewData.ModelState.Any(x => x.Value.Errors.Any()))
{
@Html.Raw(HttpUtility.HtmlDecode(Html.ValidationSummary().ToHtmlString()))
}
答案 1 :(得分:5)
ValidationSummary助手会自动对所有邮件进行HTML编码。一种可能的解决方法是编写自定义验证摘要助手,该助手不对消息进行HTML编码:
public static class HtmlExtensions
{
public static MvcHtmlString MyValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors, string message)
{
var formContext = htmlHelper.ViewContext.ClientValidationEnabled ? htmlHelper.ViewContext.FormContext : null;
if (formContext == null && htmlHelper.ViewData.ModelState.IsValid)
{
return null;
}
string messageSpan;
if (!string.IsNullOrEmpty(message))
{
TagBuilder spanTag = new TagBuilder("span");
spanTag.SetInnerText(message);
messageSpan = spanTag.ToString(TagRenderMode.Normal) + Environment.NewLine;
}
else
{
messageSpan = null;
}
var htmlSummary = new StringBuilder();
TagBuilder unorderedList = new TagBuilder("ul");
IEnumerable<ModelState> modelStates = null;
if (excludePropertyErrors)
{
ModelState ms;
htmlHelper.ViewData.ModelState.TryGetValue(htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix, out ms);
if (ms != null)
{
modelStates = new ModelState[] { ms };
}
}
else
{
modelStates = htmlHelper.ViewData.ModelState.Values;
}
if (modelStates != null)
{
foreach (ModelState modelState in modelStates)
{
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.InnerHtml = errorText;
htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal));
}
}
}
}
if (htmlSummary.Length == 0)
{
htmlSummary.AppendLine(@"<li style=""display:none""></li>");
}
unorderedList.InnerHtml = htmlSummary.ToString();
TagBuilder divBuilder = new TagBuilder("div");
divBuilder.AddCssClass((htmlHelper.ViewData.ModelState.IsValid) ? HtmlHelper.ValidationSummaryValidCssClassName : HtmlHelper.ValidationSummaryCssClassName);
divBuilder.InnerHtml = messageSpan + unorderedList.ToString(TagRenderMode.Normal);
if (formContext != null)
{
// client val summaries need an ID
divBuilder.GenerateId("validationSummary");
formContext.ValidationSummaryId = divBuilder.Attributes["id"];
formContext.ReplaceValidationSummary = !excludePropertyErrors;
}
return MvcHtmlString.Create(divBuilder.ToString());
}
private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState)
{
if (!String.IsNullOrEmpty(error.ErrorMessage))
{
return error.ErrorMessage;
}
if (modelState == null)
{
return null;
}
string attemptedValue = (modelState.Value != null) ? modelState.Value.AttemptedValue : null;
return String.Format(CultureInfo.CurrentCulture, "The value {0} is invalid.", attemptedValue);
}
}
然后:
<%= Html.MyValidationSummary(true, "Some message") %>
当然,通过这样做,您应该小心,因为您将这些错误消息放入文本中,因为它们现在不会被HTML编码。这意味着,如果您想在邮件中使用<
,>
,&
等特殊字符,则需要自行对其进行HTML编码,否则标记会中断。
答案 2 :(得分:4)
<div class="validation-summary-errors">
<ul>
<% foreach(var error in ViewData.ModelState.Where(s => s.Value.Errors.Count!=0).SelectMany(s => s.Value.Errors)) { %>
<li><%= error.ErrorMessage %></li>
<% } %>
</ul>
</div>
或剃须刀:
<div class="validation-summary-errors">
<ul>
@foreach(var error in ViewData.ModelState.Where(s => s.Value.Errors.Count!=0).SelectMany(s => s.Value.Errors)) {
<li>@Html.Raw(error.ErrorMessage)</li>
}
</ul>
</div>
答案 3 :(得分:1)
使用其他答案中建议的HttpUtility.HtmlDecode或@ Html.Raw会引起XSS问题,因为用户输入反映为错误消息的一部分。
默认情况下,ASP.NET Framework将阻止HTML并返回不反映原始值的验证错误,即ParameterName不允许使用HTML
但是 仅对字符串属性执行此操作。
对于没有String数据类型,AttemptedValue在被反映之前已被编码;应用HttpUtility.HtmlDecode或以其他方式将自己的HTML注入到验证消息中,并编写自定义代码以在 any 验证消息中呈现HTML,如果您没有任何字符串,则会引入一个反映的XSS错误参数具有默认验证。
宁可禁用内置行为,也不用担心将来会在哪里设置消息,您应该编写一个自定义ValidationSummary帮助程序,该帮助程序汇总ModelState错误和您知道包含的一组自定义验证错误HTML,最重要的是您知道它不包含任何用户输入。