假设我通过实现IValidatableObject
interface:
public class MyModel : IValidatableObject
{
public string Name { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Name == "Foo")
{
yield return new CustomValidationResult(42, nameof(Name));
}
}
}
public class CustomValidationResult : ValidationResult
{
public CustomValidationResult(int bar, string memberName) : base("FooBar", new[] { memberName })
{
Bar = bar;
}
public int Bar { get; private set; }
}
现在我想访问控制器中的CustomValidationResult
对象或动作过滤器。例如:
public class MyActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid) {
// How to access the validation result?
// Specifically, how to get the value '42' from here?
}
}
}
有没有办法实现这个目标?
答案 0 :(得分:0)
不能。到您获得ModelStateDictionary
(context.ModelState
)时,原来的ValidationResult
对象已消失。但是核心数据仍然存在。它刚刚变了。 ValidationResult
对象中的数据通过ModelStateDictionary
添加到AddModelError(...)
。
在实践中,您将看到ValidationResult.MemberNames
中的每个值都变成字典中的Key
。 ValidationResult.ErrorMessage
进入该ModelStateEntry.ErrorMessage
集合中ModelStateEntry
对象之一的Key
。
因此,换句话说,如果单个错误消息指示多个成员,则该错误消息将在字典中显示多次(每个“成员”一次)。并且当多个ValidationResult
对象指定相同的MemberName
时,单个Key
的集合中将有多个错误。
回到您的示例:
public class MyActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
string errorMsg = context.ModelState[nameof(MyModel.Name)].Errors[0]; // errorMsg will be "FooBar"
// CustomValidationResult.Bar (42) is inaccessible from here because any original ValidationResult objects are gone.
}
}
}