【问题标题】:MVC3 - passing NEW-LINE to ModelState.AddModelErrorMVC3 - 将 NEW-LINE 传递给 ModelState.AddModelError
【发布时间】:2011-11-16 18:10:41
【问题描述】:

当后端发生错误时,MVC控制器通过
ModelState.AddModelError("", "message");返回消息

我想让那个“消息”分两行显示,所以我想输入一个"\r\n"
或介于两者之间的 "<br />"

我正在使用 Razor 显示消息,使用 @Html.ValidationSummary();
但是视图的 HTML 输出显示为 <br/>

在消息上传递换行符并在 HTML 输出级别将其解释为真正的
标记的最佳方法是什么?

=================================
控制器代码:

ModelState.AddModelError("", "Line one <br /> Line two.");
return Request.IsAjaxRequest() ? (ActionResult) PartialView("ViewName", model) 
            : View(model);

查看代码:

@using (Ajax.BeginForm("Index", "Home", new AjaxOptions { UpdateTargetId = "tv" })) 
{
    @if (Html.ValidationSummary() != null)
        @Html.Raw(Server.HtmlDecode(Html.ValidationSummary(true).ToString()))   

    ....
}

【问题讨论】:

  • 请提供更多信息,您想做什么?
  • ValidationSummary 助手自动对消息进行 HTML 编码。如果你想实现这一点,你将不得不编写一个自定义助手。

标签: asp.net-mvc-3


【解决方案1】:

ValidationSummary 帮助器 HTML 对错误消息进行编码,这是设计使然。这意味着您不能使用 HTML 标签,因为它们将被编码。所以你可以编写一个不编码的自定义助手:

public static class ValidationExtensions
{
    public static IHtmlString MyValidationSummary(this HtmlHelper htmlHelper)
    {
        var formContextForClientValidation = htmlHelper.ViewContext.ClientValidationEnabled ? htmlHelper.ViewContext.FormContext : null;
        if (htmlHelper.ViewData.ModelState.IsValid)
        {
            if (formContextForClientValidation == null)
            {
                return null;
            }
            if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled)
            {
                return null;
            }
        }

        var stringBuilder = new StringBuilder();
        var ulBuilder = new TagBuilder("ul");

        ModelState modelState;
        if (htmlHelper.ViewData.ModelState.TryGetValue(htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix, out modelState))
        {
            foreach (ModelError error in modelState.Errors)
            {
                string userErrorMessageOrDefault = error.ErrorMessage;
                if (!string.IsNullOrEmpty(userErrorMessageOrDefault))
                {
                    var liBuilder = new TagBuilder("li");
                    liBuilder.InnerHtml = userErrorMessageOrDefault;
                    stringBuilder.AppendLine(liBuilder.ToString(TagRenderMode.Normal));
                }
            }
        }

        if (stringBuilder.Length == 0)
        {
            stringBuilder.AppendLine("<li style=\"display:none\"></li>");
        }
        ulBuilder.InnerHtml = stringBuilder.ToString();

        TagBuilder divBuilder = new TagBuilder("div");
        divBuilder.AddCssClass(htmlHelper.ViewData.ModelState.IsValid ? HtmlHelper.ValidationSummaryValidCssClassName : HtmlHelper.ValidationSummaryCssClassName);
        divBuilder.InnerHtml = ulBuilder.ToString(TagRenderMode.Normal);
        if (formContextForClientValidation != null)
        {
            if (!htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled)
            {
                divBuilder.GenerateId("validationSummary");
                formContextForClientValidation.ValidationSummaryId = divBuilder.Attributes["id"];
                formContextForClientValidation.ReplaceValidationSummary = false;
            }
        }
        return new HtmlString(divBuilder.ToString(TagRenderMode.Normal));
    }
}

然后:

@Html.MyValidationSummary()

这是我们自定义帮助程序中明确不进行 HTML 编码的以下行:

liBuilder.InnerHtml = userErrorMessageOrDefault;

在原来的助手中是这样的:

liBuilder.SetInnerText(userErrorMessageOrDefault);

【讨论】:

  • 如果每次你的一个答案帮助我解决了达林问题,我都能得到一个美元,我现在就不会工作了。
  • B E 实用!谢谢达林。
  • 感谢 ans Darin!完美运行!
【解决方案2】:

尝试将验证摘要包含在 Html.RawServer.HtmlDecode 中,如下所示:

@Html.Raw(Server.HtmlDecode(Html.ValidationSummary().ToString()))

【讨论】:

  • 当我放那行代码时,它甚至没有显示局部视图。它给了我一个“500 内部服务器错误”。
  • 我修改了我的答案。我测试了修改后的代码,当我在错误消息中包含&lt;br /&gt; 时,它返回了带有换行符的错误消息。
  • 问题出在@Html.ValidationSummary;我尝试用 ViewBag.Temp 替换它。它确实有效。因此,在我们开始考虑完全替换它之前,我们需要找出如何使 ValidationSummary 工作。
  • 也许我在 Ajax.BeginForm 中有验证。那会有区别吗?
  • 为我工作! @Html.Raw(Server.HtmlDecode(Html.ValidationSummary(true, "", new { @class = "text-danger" }).ToString()))
【解决方案3】:

控制器:

ModelState.AddModelError("MyError", "Line 1" + Environment.NewLine + "Line 2");

剃须刀:

<span style="white-space: pre-line">@Html.ValidationSummary()</span>

【讨论】:

  • 此处建议的插入 Environment.NewLine 对我不起作用。
  • @levteck 对为什么它对我有用而不是你有什么想法吗?
  • @MarioLevesque 为我工作。确保像示例中那样对 span 元素进行样式化。
【解决方案4】:

这是一个较晚的答案,但这是我 Google 时的最佳结果,所以我的解决方案可能会对某人有所帮助。

我解决了这个问题,并为每个错误消息行添加了一个单独的行。显示精美。

控制器代码:

    public ActionResult Edit(EditModel model)
    {
            try
            {
                //... do update
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains(Environment.NewLine))
                {
                    var messages = ex.Message.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var message in messages)
                    {
                        this.ModelState.AddModelError(string.Empty, message);
                    }
                }
                else
                {
                    this.ModelState.AddModelError(string.Empty, ex.Message);
                }
            }
        //...

        return this.View(model);
    }

【讨论】:

  • 如果您使用 AddModelError 中的第一个参数键来引用输入,这将不起作用
猜你喜欢
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 2012-10-21
  • 2012-12-05
  • 1970-01-01
  • 2015-01-07
相关资源
最近更新 更多