如果成员无效,则无法验证模型对象

时间:2019-04-12 10:26:13

标签: c# asp.net-core asp.net-mvc-validation

我正在编写一个ASP.NET Core Web应用程序。我正在使用MVC的模型验证框架,并且有一个“表单”模型,其中包含一个Product对象和一个IsCreationMode布尔值。

我想验证Product,但是我也想确保,如果要创建产品,则该SKU尚不存在任何产品。因此,我定义了一个自定义验证属性,如果IsCreationMode为true并且可以在数据库中找到产品SKU,则返回一个验证错误。我在模型类本身上使用了此属性,并且可以正常工作。

[ProductIsUnique]
public class ProductForm
{
    public Product Product { get; set; }
    public bool IsCreationMode { get; set; }
}

但是,如果产品对象无效,则然后将不验证模型对象(这意味着它始终被视为“有效”)。 (我尚未测试是否确实没有对任何对象(并非其所有成员都有效)进行验证。)

这意味着用户可能会看到有关产品某个属性的错误(例如,“名称过长”),然后进行修正,提交并得到另一个错误,因为整个模型都未经首次验证,但如果经过检查,将被视为无效。

是否有此配置设置?在我看来,“无论如何验证”都不是不受欢迎或不推荐的选择...

编辑

这是一个最小的例子。

创建一个新的ASP.NET Core MVC项目:

dotnet new mvc

将其放在HomeController.cs文件中:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Stack.Models;
using System.ComponentModel.DataAnnotations;

namespace Stack.Controllers
{
    public class HomeController : Controller
    {
        [HttpGet]
        public IActionResult Index()
        {
            ProductForm model = new ProductForm() 
            {
                IsCreationMode = true
            };
            return View(model);
        }

        [HttpPost]
        public IActionResult Index(ProductForm model)
        {
            if (!ModelState.IsValid)
                return BadRequest(ModelState);
            return Ok();
        }
    }

    public class Product
    {
        public int ID { get; set; }
        [StringLength(50, MinimumLength = 3)]
        public string Name { get; set; }
    }

    [ProductIsUnique]
    public class ProductForm
    {
        public Product Product { get; set; }
        public bool IsCreationMode { get; set; }
    }

    public class ProductIsUniqueAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            ProductForm productForm = validationContext.ObjectInstance as ProductForm;

            if (productForm.IsCreationMode && productForm.Product.ID == 10)
            {
                return new ValidationResult(string.Format("A Product with ID '{0}' already exists. You cannot create another one.", productForm.Product.ID), new string[] 
                    {
                        "Product.ID"
                    });
            }

            return ValidationResult.Success;
        }
    }
}

将此内容放入Views / Home / Index.cshtml:

@model Stack.Controllers.ProductForm

<form method="post">
    <p>ID: @Html.TextBoxFor(m => m.Product.ID)</p>
    <p>Name: @Html.TextBoxFor(m => m.Product.Name)</p>
    @Html.HiddenFor(m => m.IsCreationMode)
    <input type="submit" value="Submit" />
</form>

构建并运行。现在,如果您访问/,您将收到一个包含两个字段的表单。

1)在ID中键入“ 10”以外的任何内容,在“名称”中键入3到50个字符之间的字符串。服务器按预期响应200 OK。

2)在ID中键入“ 10”,在“名称”中键入3到50个字符之间的字符串。服务器按预期响应400 BadRequest,并使用JSON描述一个错误,即ProductIsUnique的错误。

3)键入“ 10”和少于3个字符的字符串。我预计会出现两个错误:无效的名称和ProductIsUnique的失败。相反,我只会得到无效的名称。

0 个答案:

没有答案