.NET Core MVC 中的表单验证

Posted

技术标签:

【中文标题】.NET Core MVC 中的表单验证【英文标题】:Form Validation in .NET Core MVC 【发布时间】:2020-10-18 09:27:25 【问题描述】:

我正在尝试向我的一些字段添加一些表单验证。我有一个下拉菜单和一个输入框。两个输入都需要验证。我的目标是如果其中任何一个无效,则向用户显示错误消息。该表单允许用户使用新作者创建现有书籍的副本。下拉列表包含数据库中的书籍列表,用户在文本框中输入新作者的姓名。提交按钮会创建一个包含新作者的现有图书的副本。

使用 jQuery、jquery.validate.js 和 jquery.validate.unobtrusive.js 我能够完成向用户显示错误消息,但是一旦页面加载就会进行检查,因此错误消息显示为页面加载后。 (也许我需要一个隐藏字段,或者我必须修改我的 HttpGet 处理程序)。

现在,如果用户尝试在不选择一本书和/或输入作者姓名的情况下提交表单,则路径保持不变,但表单消失了,屏幕上会显示一个 json 对象,并带有400 状态,它显示“书名字段是必需的”和“作者字段是必需的”。我只想要输入字段旁边的红色文本,说明它们不能留空,我该怎么做?谢谢!

我的模特:

public int ID  get; set; 
[Required]
public string bookName  get; set; 
[Required]
public string Author  get; set; 

我的cshtml

<form method="post" asp-controller="Index" asp-action="Index" role="post">
    <div class="form-group">
        <label asp-for="bookName"></label>
        <select name="bookName" asp-items="@(new SelectList(ViewBag.message, "ID", "bookName"))">
</select>
        <span asp-validation-for="bookName">Please select a book.</span>
    </div>
    <div class="form-group">
        <label asp-for="Author"></label>
        <input asp-for="Author" class="form-control" />
        <span asp-validation-for="Author">Please type in the author's name.</span>
    </div>
    <div class="form-group">
        <input type="submit" value="Submit" class="btn btn-primary" />
    </div>
</form>

我的控制器:

[HttpGet("[action]")]
[Route("/Index")]
[Produces("application/json")]
public IActionResult Index()

  return View();


[HttpPost("[action]")]
[Route("/Index")]
[Produces("application/json")]
public async Task<IActionResult> Index([FromForm] bookModel model)

  if(ModelState.IsValid)
   
      //do stuff
      return View(model)
   
   else
   
     //display an error message & remain on same page
   

【问题讨论】:

试过这个吗? if (!ModelState.IsValid)return Page(); @naveen 您好,感谢您的回复!我正在为这个应用程序使用 MVC,所以我的应用程序后面没有 cshtml.cs 代码。如果我没记错的话,我不能返回页面,只能返回视图。 【参考方案1】:

如果您的控制器预期从视图返回 html,则不需要属性 [Produces("application/json")]。所以应该去掉这个属性。

您的验证span 也应该具有asp-validation-for 属性您有as-validation-for,它不会正确链接验证脚本。

正确:

<span asp-validation-for="bookName">Please select a book.</span>

修复此问题应该使错误消息仅在输入控件失去焦点后显示。

【讨论】:

您好 Rosco,感谢您的回复!我将更多地研究 Produces 属性。我删除了该属性,但如果我尝试在没有填写下拉列表和输入框的情况下提交表单,我仍然会收到该 json 对象作为响应。有什么建议吗?为什么会这样?将Required 属性添加到我的模型似乎会使一切都失败。如果Required 属性存在,我的HttpPost 将不起作用。【参考方案2】:

您是否想在单击按钮时显示验证消息?如果是,您可以更改模型中的错误消息,并删除您的&lt;span asp-validation-for=xxx&gt;&lt;/span&gt; 中的消息这是一个演示:

型号:

public class bookModel
    
        public int ID  get; set; 
        [Required(ErrorMessage = "Please select a book.")]
        public string bookName  get; set; 
        [Required(ErrorMessage = "Please type in the author's name.")]
        public string Author  get; set; 
    

控制器:

public class BookController : Controller
    
        public ActionResult Index()
        
            ViewBag.message = addMessage();

            return View();
        
       [HttpPost]
        public ActionResult Index(bookModel model) 
            ViewBag.message = addMessage();
            return View();
        
        public static List<SelectListItem> addMessage() 
            List<SelectListItem> list = new List<SelectListItem>();
            SelectListItem s1 = new SelectListItem  Text = "book1", Value = "b1" ;
            SelectListItem s2 = new SelectListItem  Text = "book2", Value = "b2" ;
            SelectListItem s3 = new SelectListItem  Text = "book3", Value = "b3" ;
            list.Add(s1);
            list.Add(s2);
            list.Add(s3);
            return list;
        

       
    

查看:

@
    ViewData["Title"] = "Index";

@model bookModel
<h1>Index</h1>
<form method="post">
    <div class="form-group">
        <label asp-for="bookName"></label>
        <select asp-for="bookName" asp-items="@ViewBag.message"></select>
        <span asp-validation-for="bookName" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Author"></label>
        <input asp-for="Author" class="form-control" />
        <span asp-validation-for="Author" class="text-danger"></span>
    </div>
    <div class="form-group">
        <input type="submit" value="Submit" class="btn btn-primary" />
    </div>
</form>

结果:

【讨论】:

【参考方案3】:

我建议使用名为 FormHelper 的外部库。在 ASP.NET Core 上创建表单并使用它进行验证非常容易。您不需要为 ajax 表单编写 javascript 代码。只需将 asp-formhelper="true" 属性添加到您的表单标签。

https://nuget.org/packages/FormHelper

您可以从 github 页面查看其文档: https://github.com/sinanbozkus/formhelper

【讨论】:

以上是关于.NET Core MVC 中的表单验证的主要内容,如果未能解决你的问题,请参考以下文章

如何支持 NTLM 身份验证并回退到 ASP.NET MVC 中的表单?

将 asp.net WebForms 应用程序中的组合表单/Windows 身份验证迁移到 asp.net MVC 应用程序

在 asp.net mvc razor 页面中验证 jquery 中的特定表单字段

表单身份验证、ASP.NET MVC 和 WCF RESTful 服务

在 Asp.net Core 中使用 Ajax 的验证表单

ASP.Net MVC 3客户端验证,带有3个选项卡表单