ASP .Net MVC:Razor 视图忽略或跳过验证 ViewBag

ASP .Net MVC: Razor view ignores or skips validation ViewBag

我正在尝试验证我的搜索选项字段,该字段位于 Index.cshtml :

当我输入名称时,它工作正常并显示 DetailsBySurname.cshtml 中的所有匹配结果:

这是DetailsBySurname.cshtml

这个 Razor 视图应该根据 ViewBag 内部的内容显示验证成功或错误消息,但是当它从 Controller IActionResult 重定向到我的 Razor 视图并在 ViewBag 中显示错误消息时,它会跳过(我认为)代码块if 语句并直接进入 foreach 循环,该循环应该仅在没有错误消息时才被激活。然后我得到这个错误:

这是 Razor 视图的代码 DetailsBySurname.cshtml:

@model IEnumerable<codeRed_Capstone.Models.Employee>

@{
    ViewData["Title"] = "DetailsBySurname";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@if (ViewBag.Message != null)
    {
        <p class="alert-@(ViewBag.Error != null ? "danger" : "success")">@(ViewBag.Message)</p>
        if (ViewBag.Error != null)
        {
            <ul>
                @foreach (Exception e in ViewBag.Exception.ValidationExceptions)
                {
                    <li class="alert-danger">@(e.Message)</li>
                }
            </ul>
        }
    }
<h1>Details</h1>

<div>
    <h4>Employee</h4>
    <hr />
    @foreach (var item in Model)
    {
        <dl class="row">

            <dt class="col-sm-2">
                @Html.DisplayNameFor(item => item.FirstName)
            </dt>
            <dd class="col-sm-10">
                @Html.DisplayFor(modelItem => item.FirstName)
            </dd>
            <dt class="col-sm-2">
                @Html.DisplayNameFor(model => item.LastName)
            </dt>
            <dd class="col-sm-10">
                @Html.DisplayFor(modelItem => item.LastName)
            </dd>
       </dl>
    }
</div>

这是控制器中用于 IAction 结果的代码块 DetailsBySurname:

public async Task<IActionResult> DetailsBySurname(string lastName)       
        {
            if (Request.Query.Count > 0)
            {
                try
                {

                    ValidationException exception = new ValidationException();
                    lastName = !string.IsNullOrWhiteSpace(lastName) ? lastName.Trim() : null;

                    using (CompanyContext context = new CompanyContext())
                    {
                        if (string.IsNullOrWhiteSpace(lastName))
                        {
                            exception.ValidationExceptions.Add(new Exception("Last Name Not Provided"));
                        }

                        // Category ID fails parse.
                        // Common validation points (5) and (5a).
                        int n;
                        bool isNumeric = int.TryParse(lastName, out n);
                        if (isNumeric)
                        {
                            exception.ValidationExceptions.Add(new Exception("ID Not Valid string"));
                        }
                        else
                        {
                            // Category ID exists.
                            // Common validation point (7).
                            if (!context.Employees.Any(x => x.LastName == lastName))
                            {
                                exception.ValidationExceptions.Add(new Exception("Last Name Does Not Exist"));
                            }
                        }

                        if (exception.ValidationExceptions.Count > 0)
                        {
                            throw exception;
                        }

                    }

                    var employees = _context.Employees.Where(m => m.LastName == lastName);
       
                    ViewBag.Message = $"Successfully Found {lastName}!";

                    return View(employees);

                }

                // Catch ONLY ValidationException here.
 
                catch (ValidationException e)
                {
                    ViewBag.LastName = lastName;
                    ViewBag.Message = "There exist problem(s) with your submission, see below.";
                    ViewBag.Exception = e;
                    ViewBag.Error = true;

                    return View(e);
                }
            }
            return View();
        }

最后是 Index.cshtml 视图中搜索字段的代码:

@model IEnumerable<codeRed_Capstone.Models.Employee>

@{
    ViewData["Title"] = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <a class="navbar-brand" href="#">Navbar</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item active"> 
            </li>    
            <li class="nav-item dropdown">          
                <form action="/Employee/Index" method="get">
                    <lable for="filter"> Show Laid of Staff</lable>
                    <input type="checkbox" id="filter" name="filter" value="laidoff" />
                    <input class="btn btn-outline-success my-2 my-sm-0" type="submit" value="Go!" />
                </form>
            </li>
        </ul>
        <form action="/Employee/DetailsByEmail" method="get" class="form-inline my-2 my-lg-0">
            <input id="email" name="email" data-val="true" data-val-required="Email is required" class="form-control mr-sm-2" type="search" placeholder="Search by Email" aria-label="Search">
            <span class="field-validation-valid" data-valmsg-for="email" data-valmsg-replace="true"></span>
            <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
        </form>
        <form action="/Employee/DetailsBySurname" method="get" class="form-inline my-2 my-lg-0">
            <input id="lastName" name="lastName" data-val="true" data-val-required="Last Name is required" class="form-control mr-sm-2" type="search" placeholder="Search by Last Name" aria-label="Search">
            <span class="field-validation-valid" data-valmsg-for="lastName" data-valmsg-replace="true"></span>
            <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
        </form>
    </div>
</nav>

我看到调试一直按预期进行,直到最后,只有当它跳转到 Razor View 时,它才会给我上面提到的这个错误。 我还创建了 Class 来处理所有验证异常,但它工作正常。我确定问题出在 Controller 和 Razor 视图之间。或者可能是其他地方的问题,我是 ASP .Net MVC 的新手,有什么建议吗?

我用不同的验证方法修复了它。 对于 DetailsBySurname 我删除了 if(ViewBag... 并添加了不同的 if(ViewData... - 语句来检查返回的结果是否为 null 然后不要 运行 foreach 循环). 要捕获错误消息,请使用另一个 if 语句 @if(!ViewData.ModelState.IsValid) ,如下所示:

@model IEnumerable<codeRed_Capstone.Models.Employee>

@{
    ViewData["Title"] = "DetailsBySurname";
    Layout = "~/Views/Shared/_Layout.cshtml";
}


<h1>Details</h1>

<div>
    @if (ViewData.ModelState.IsValid)
    {
        <h4>Employee</h4>
        <hr />
        @foreach (var item in Model)
        {
            <dl class="row">

                <dt class="col-sm-2">
                    @Html.DisplayNameFor(item => item.FirstName)
                </dt>
                <dd class="col-sm-10">
                    @Html.DisplayFor(modelItem => item.FirstName)
                </dd>
                <dt class="col-sm-2">
                    @Html.DisplayNameFor(item => item.LastName)
                </dt>
                <dd class="col-sm-10">
                    @Html.DisplayFor(modelItem => item.LastName)
             </dl>
         }
    }
</div>
<div class="form-row">
        <div class="form-group col-md-2">
        
            @if (!ViewData.ModelState.IsValid)
            {
                <span class="field-validation-error">@ViewData.ModelState["LastName"].Errors[0].ErrorMessage</span>
            }
        </div>
</div>

然后在 IAction 结果 DetailsBySurname 的控制器中,我将验证方法更改为内置验证,如下所示:

 public async Task<IActionResult> DetailsBySurname(string lastName)
        {
            lastName = !string.IsNullOrWhiteSpace(lastName) ? lastName.Trim() : null;

            if (string.IsNullOrWhiteSpace(lastName))
            {
                ModelState.AddModelError("LastName", "Last Name not Provided");
                //exception.ValidationExceptions.Add(new Exception("Last Name Not Provided"));
            }

            bool exists;
            if (!(exists = _context.Employees.Any(m => m.LastName == lastName)))
            {
                //return NotFound(new Exception("Email not found"));
                ModelState.AddModelError("LastName", "Last Name not found");

            }

            if (!ModelState.IsValid)
            {
                return View();
            }
            else
            {
                var employee = _context.Employees.Where(m => m.LastName == lastName);
                return View(employee);
            }
}