Asp.net core mvc ASP.NET Core 2.0 ModelState筛选器是否在验证之前?

Asp.net core mvc ASP.NET Core 2.0 ModelState筛选器是否在验证之前?,asp.net-core-mvc,asp.net-core-2.0,Asp.net Core Mvc,Asp.net Core 2.0,我可以在ASP.NET Core 2.0中执行类似操作吗 例如,我有一个ViewModel: public class TodoViewModel { [Required(ErrorMessage = "Required !")] // <--- Required public int? Key { get; set; } // Is Nullable [Required(ErrorMessage = "Required !")] // <--- Requi

我可以在ASP.NET Core 2.0中执行类似操作吗

例如,我有一个ViewModel:

public class TodoViewModel
{
    [Required(ErrorMessage = "Required !")] // <--- Required
    public int? Key { get; set; } // Is Nullable

    [Required(ErrorMessage = "Required !")] // <--- Required
    public int? Value { get; set; } Nullable

    [Required(ErrorMessage = "Required !")] // <--- Required
    public byte Type { get; set; }
}
在行动中,我有这样一个想法:

@Html.BeginForm(FormMethod.Post)
{ 
    @if (Model.Type == 1)
    {
        @Html.TextBoxFor(x => x.Key)
        @Html.ValidationMessageFor(x => x.Key)
    }

    @if (Model.Type == 2)
    {
        @Html.TextBoxFor(x => x.Value)
        @Html.ValidationMessageFor(x => x.Key)
    }
}
    [HttpPost]
    public IActionResult Todo(TodoViewModel model)
    {
        // My problem
        // if model.type = 1 return ModelState has error validate for Property (Value) is Required
        // and if model.type = 2 return ModelState has error validate for Property (Key) is Required
        if (!ModelState.IsValid) // <-- Here is my problem
            return View(model);
    }
但不幸的是,executefor(OnActionExecuting)是在ModelState验证之后执行的

有没有具体的方法可以做到这一点

如果“Type”属性等于1,我想排除“Key”属性的ModelState验证


如果“Type”属性等于2,则排除“Value”属性的ModelState验证这清楚地表明您实际上需要两个视图模型。要么就是对ViewModel进行粗略的验证,然后在业务逻辑中进行更详细的验证

当然,您可以编写自己的验证属性(但不是通过
ActionFilterAttribute
,而是通过继承并将其放在视图模型上,而不是
[Required]
),这将检查是否需要一个验证属性,但这基本上只是覆盖/隐藏了您拥有两种不同类型模型的意图

验证属性不是用来强制执行业务规则的,它们应该比较简单,并且在应用业务验证之前(可能需要额外的检查、服务或数据库往返),验证数据在第一次查看时是否看起来良好


但是请记住,如果使用自定义验证属性,则不会有任何客户端验证(通过浏览器中的JavaScript)。您还需要实现一个
AttributeAdapterBase

实现IValidatableObject接口

using System.ComponentModel.DataAnnotations;
public class TodoViewModel : IValidatableObject
{
    public int? Key { get; set; } 

    public int? Value { get; set; } 

    [Required(ErrorMessage = "Required !")] 
    public byte Type { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Type == 1)
        {
            yield return
              new ValidationResult(errorMessage: "Property (Value) is Required",
                                   memberNames: new[] { "Value" });
        }
        if (Type == 2)
        {
            yield return
              new ValidationResult(errorMessage: "Property (Key) is Required",
                                   memberNames: new[] { "Key" });
        }

   }
}
使用System.ComponentModel.DataAnnotations;
提供模型的公共类:IValidatableObject
{
公共int?密钥{get;set;}
公共int?值{get;set;}
[必需(ErrorMessage=“必需!”)]
公共字节类型{get;set;}
公共IEnumerable验证(ValidationContext ValidationContext)
{
如果(类型==1)
{
生利
新的ValidationResult(错误消息:“需要属性(值)”,
MemberName:new[]{“Value”});
}
如果(类型==2)
{
生利
新的ValidationResult(错误消息:“需要属性(键)”,
成员名称:新[]{“键”});
}
}
}

您只需使用
ValidationAttribute
实现
IClientValidatable
即可获取客户端validation@StephenMuecke:介意提供一个例子或参考吗?在添加注释后,我意识到它是
核心mvc
,并重新标记了这个问题。在core中,它的
IClientModelValidator
中的一个例子是,尽管尚未找到一个好的博客,介绍core的条件客户端验证(如mvc),但它使用了一个条件验证属性,例如
[RequredIf]
。或者如果你想写你自己的参考
using System.ComponentModel.DataAnnotations;
public class TodoViewModel : IValidatableObject
{
    public int? Key { get; set; } 

    public int? Value { get; set; } 

    [Required(ErrorMessage = "Required !")] 
    public byte Type { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Type == 1)
        {
            yield return
              new ValidationResult(errorMessage: "Property (Value) is Required",
                                   memberNames: new[] { "Value" });
        }
        if (Type == 2)
        {
            yield return
              new ValidationResult(errorMessage: "Property (Key) is Required",
                                   memberNames: new[] { "Key" });
        }

   }
}