@ Html.ValidationSummary适用于错误页面

时间:2016-12-30 20:24:10

标签: c# asp.net-mvc razor

使用asp.net核心剃须刀。我当前的if语句是错误的,但它是获取错误消息的唯一方法。当前的if语句是否为ModelState无效返回视图。在新视图中,它显示错误消息。但是,我想要的是如果ModleState无效重定向到Index.cshtml页面并显示错误。当我翻转if条件时,错误消息不会显示在Index.cshtml页面中。

这是我的控制器。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using quotingDojo.Models;

namespace quotingDojo.Controllers
{
    public class HomeController : Controller
    {
        // GET: /Home/
        [HttpGet]
        [Route("")]
        public IActionResult Index()
        {
            return View();
        }

       [HttpPost]
        [Route("quotes")]
        public IActionResult Quotes(Home model)
        {
            if(!ModelState.IsValid)
            {
                return View();
            }
        //continue your code to save
        return RedirectToAction("Index");
        }    
    }
}

这是我的Index.cshtml

@model quotingDojo.Models.Home
<h1>Welcome to the Quoting Dojo</h1>
@using(Html.BeginForm("Quotes","Home"))
{
    <p>@Html.ValidationSummary()</p>
    <p>
        <label>Your Name</label>
        @Html.TextBoxFor(s=>s.Name)
        @Html.ValidationMessageFor(s => s.Name)
    </p>
    <p>
        <label>Your Quote</label>
        @Html.TextAreaFor(d=>d.Quote)
    </p>
    <input type="submit" name="submit" value="Add my quote!"/>

}
<form action="quotes" method="get">
    <input type="submit" name="submit" value="Skip to quotes!"/>
</form>

以下是我的Quotes.cshtml,其中显示了当前显示的错误消息。

<h1>Test</h1>
 <p>@Html.ValidationSummary()</p>

这是我的模特页面 使用System.ComponentModel.DataAnnotations;

namespace quotingDojo.Models
{
    public class Home
    {
        [Required(ErrorMessage ="Please enter your name")]
        [DataType(DataType.Text)]
        [MinLength(3)]
        public string Name {get; set;}

        [Required]
        [MinLength(5)]
        public string Quote{get; set;}
    }
}

2 个答案:

答案 0 :(得分:1)

您的问题在这里:

return View();

由于您的操作方法名为Quotes(这是MVC约定),因此将返回名为“Quotes”的视图。您也不会将模型传递给它,因此即使视图存在,它也不会知道错误。

解决问题的两种方法:

<强> 1

您必须将模型传递到Index视图,因此您需要明确返回Index视图。

if(!ModelState.IsValid)
{
    return View("Index", model);
}

<强> 2

我个人更喜欢这种方法。将您的第一个操作命名为与您发布的原始表单相同的操作,然后您可以执行此操作(注意:您还需要重命名视图):

// GET: /Home/
[HttpGet]
[Route( "" )]
public IActionResult Quotes() {
   return View();
}

[HttpPost]
[Route( "quotes" )]
public IActionResult Quotes(Home model) {
   if( !ModelState.IsValid ) {
      return View(model);
   }
   //continue your code to save
   return RedirectToAction( "Index" );
}

这样他们都返回名为Quotes的视图,因此您不必明确提及它。

答案 1 :(得分:0)

标准做法是,如果模型状态无效,则返回相同的视图(用户提交的用户),您将在其中显示验证错误消息。您只需将Quotes操作方法更改为Index操作方法即可。

[HttpPost]
[Route("quotes")]
public IActionResult Index(Home model)
{
   if (!ModelState.IsValid)
        return View(); 
   // to do :continue saving
}

请务必更新您的表单以发布此操作。

不确定为什么要重定向到要显示错误的其他页面。

如果您绝对想在通过RedirectToAction方法调用加载的另一个视图中显示错误消息(因此是一个全新的GET调用),您需要使用TempData来传输错误。

 public ActionResult Quotes(Home model)
 {
     if (!ModelState.IsValid)
     {
        List<string> errors = new List<string>();
        foreach (var modelStateVal in ViewData.ModelState.Values)
        {
            foreach (var error in modelStateVal.Errors)
            {
                errors.Add(error.ErrorMessage);
            }
        }
        TempData["errors"] = errors;
        return RedirectToAction("Index");
      }
        //continue your code to save

 }

在索引视图中,

@if (TempData["errors"] != null)
{
    var errors = (List<string>) TempData["errors"];
    foreach (var error in errors)
    {
      <span class="alert warning">@error</span>
    }
}