【问题标题】:Display error message on the view from controller asp.net mvc 5在控制器 asp.net mvc 5 的视图上显示错误消息
【发布时间】:2017-09-19 13:09:59
【问题描述】:

我是 Web 开发的新手,正在尝试学习 ASP.Net MVC 5。如果找不到记录,我正在数据库中查找一条记录,然后我想向用户显示一条错误消息。以下是我的尝试:

控制器

    [HttpGet]
    public ActionResult Search()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Search(ForgotPasswordMV viewModel)
    {
        if (Temp.Check(viewModel.Email))
            return RedirectToAction("VerifyToken", new { query = viewModel.Email });
        else
        {
            ViewBag.ErrorMessage = "Email not found or matched";
            return View();
        }
    }

查看:

<p>@ViewBag.ErrorMessage</p>

视图模型

public class ForgotPasswordMV
{
    [Display(Name = "Enter your email"), Required]
    public string Email { get; set; }
}

但是我在某处读到我应该在我的视图模型中放置一个属性并在该属性上设置错误消息。我现在很困惑,如何实现以及如何在 View 中显示错误呢?推荐/最佳做法是哪一种?

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-mvc-5


    【解决方案1】:

    但我在某处读到我应该在我的视图模型中放置一个属性 并在该属性上设置错误消息。我现在很迷茫,怎么办 实现这一点以及如何在 View 中显示错误呢?还有哪一个 是推荐/最佳做法吗?

    最佳做法是更改控制器的 ModelState 字典属性,如下所示:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Search(ForgotPasswordMV viewModel)
    {
        // ... 
        else
        {
            ModelState.AddModelError(nameof(ForgotPasswordMV.Email), "Email not found or matched");
            return View(viewModel);
        }
    }
    

    然后在您的视图中,在您的电子邮件字段旁边添加以下行;

    @Html.ValidationMessageFor(m => m.Email)
    

    【讨论】:

    • 我喜欢这个解决方案,因为它使用 Html Helper,所以我不需要照顾其他东西。所以。我应该遵循这种方法作为最佳实践。但是这个问题的另一个答案更倾向于将错误属性添加到模型中。你能解释一下 ModelState.AddModelError 实际上在做什么。我知道如果我们将一个字段设置为[Required],然后我们检查modelstate.isvalid,那么我们可以在那里捕获错误。这 AddError 是不是在做同样的事情,但它更加定制?
    • 是的,没错。这是最佳实践,因为假设您的模型上有许多属性,您最终会为每个模型属性创建许多错误消息属性,这最终会使您的模型膨胀。使用ModelState.AddModelError 有助于避免此类事情。
    • 有一件事我注意到 KeyName 应该与属性名称相同,以便它可以绑定到该特定属性。所以基本上AddModelError 中的第一个参数有点告诉我们的哪个属性我们需要将此错误消息绑定到的模型。如果我错了,请纠正我。但无论如何,谢谢你的回答。 :)
    • 是的。您也可以将空字符串作为键,以便将错误消息与整个模型相关联。如果您使用 thiat 解决方案,则必须使用此行 @Html.ValidationSummary(true, "The following error has occured:")
    • @CodeNotFound,我有类似的情况,你的解决方案对我来说就像一个魅力。非常感谢!
    【解决方案2】:

    但我在某处读到我应该在我的视图模型中放置一个属性并在该属性上设置错误消息。

    没错。您可以将错误消息添加到您的视图模型中:

    public class ForgotPasswordMV
    {
        [Display(Name = "Enter your email"), Required]
        public string Email { get; set; }
    
        public string ErrorMessage { get; set; }
    }
    

    然后在你的视图模型上设置这个属性并将视图模型传递给视图:

    ...
    else
    {
        viewModel.ErrorMessage = "Email not found or matched";
        return View(viewModel);
    }
    

    最后在强类型视图中使用模型上的属性:

    @model ForgotPasswordMV
    ...
    <p>@Model.ErrorMessage</p>
    

    所以基本上我们在这里将ViewBag 的使用替换为强类型视图模型。

    【讨论】:

    • 这是推荐的做法吗?如果你不得不这样做,你会怎么做?模型视图中的视图包或属性?
    • 您能否看到下面的答案,让我知道这是否是使用辅助方法的最佳做法
    • @Darin Dimitrov 我已经尝试过了,但页面加载时出现 NullReferenceException?
    【解决方案3】:

    如果有人正在寻找一个简单的修复程序并且没有什么永久性的,请随意使用这个答案,因为这帮助了我。如果您必须担心应用程序的安全性,请勿使用此修复程序。

    在您的控制器中:

    TempData["Message"] = "This is my Error";
    

    在您的 Error.cshtml 文件中:

    <h3><strong>@TempData["Message"]</strong></h3>
    

    结果:

    【讨论】:

      【解决方案4】:

      就我而言,接受的 anwser 不是最佳实践。我们可以处理注释中的所有错误。
      在我们的 ViewModel 中,我们为属性指定 ErrorMessages。

      public class UserLoginViewModel
      {
          [Required(ErrorMessage = "User name is required")]
          [Display(Name = "User name")]
          [StringLength(500, ErrorMessage = "User name is too short", MinimumLength = 3)]
          public string Login { get; set; }
      
          [Required(ErrorMessage = "Password is required")]
          [Display(Name = "Password")]
          public string Password { get; set; }
      }
      

      在我们的控制器中

      [HttpPost]
      [ValidateAntiForgeryToken]
      public ActionResult Login(UserLoginViewModel model)
      {
          if (!this.ModelState.IsValid)
          {
              return this.View();
          }
          ...
      }
      

      我们的观点

      @Html.ValidationMessageFor(model => model.Login)
      @Html.EditorFor(model => model.Login)
      @Html.ValidationMessageFor(model => model.Password)
      @Html.EditorFor(model => model.Password)
      

      【讨论】:

      • 这里我们讨论的是来自业务逻辑的错误,而不是标准错误。
      • 哇,对。所以也许远程验证对某人有用。您还可以使用 RV 检查电子邮件匹配/查找。
      【解决方案5】:

      我也花了很多时间来寻找最佳解决方案。这很简单。在您的控制器中,您可以发送这样的消息。

              if (UnitCount >= 1000)
              {
                  TempData["MsgChangeStatus"] = "Only 1000 units are allowed to modify at the same time!";
                  return RedirectToAction("ChangeStatus");
              }
      

      这很重要,在你使用 TempData 命令后,你必须立即使用 Return View() 或 return RedirectToAction(),因为这些命令可以将你的消息发送到 View。

      视图中,您必须添加以下部分。

       @{
      ViewBag.Title = "UnitState Change";
      Layout = "~/Views/Shared/_Layout.cshtml";
      var message = TempData["MsgChangeUS"] ?? string.Empty;
      }
      
      
      <script type="text/javascript">
      var message = '@message';
      if(message)
          alert(message);
      </script>
      

      【讨论】:

        猜你喜欢
        • 2017-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-27
        相关资源
        最近更新 更多