我有一个Asp.Net核心REST服务,我正在使用内置验证。我需要一些额外的功能,所以我找到了一些我需要的验证属性的例子,所以这里只是我模型的一小部分:
[RequiredIfEmpty("B")]
[RequiredIfEmpty("C")]
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
所以,很明显我想要的是什么。如果B或C为空,我想验证是否指定了A.
当我发送一个验证失败的JSON请求时,我只得到:
"A is required when B is empty."
我期待得到:
"A is required when B is empty."
"A is required when C is empty."
因此,似乎验证代码在基于类型的属性上做了不同的,因为它忽略了第二个。如果我这样做,这进一步证明了:
[RequiredIfEmpty("B")]
[RequiredIfEmpty2("C")]
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
RequiredIfEmpty2只是从RequiredIfEmpty派生而来,没有额外的代码。现在我得到了预期的结果:
"A is required when B is empty."
"A is required when C is empty."
在这个例子中,我只有2个依赖属性,所以创建一个2版本没什么大不了的,但它非常hacky而且我不喜欢它。
我考虑过更改RequiredIfEmpty属性以获取属性的字符串[],但似乎MVC基础结构不允许单个属性返回多个错误字符串。
我确实向微软报告了这个问题,但是想知道除了拥有2个版本之外是否有其他人可以考虑解决方案?
答案 0 :(得分:2)
您可以覆盖属性中的Equals
和GetHashCode
方法,以创建AllowMultiple
属性之间的区别。
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
public sealed class RequiredIfEmptyAttribute : RequiredAttribute
{
private object _instance = new object();
public override bool Equals(object obj) => _instance.Equals(obj);
public override int GetHashCode() => _instance.GetHashCode();
// all the rest of the code
}
如果您仅定位.Net Framework,则可以使用TypeId
属性作为同一类型的两个属性之间的唯一标识符。 (MSDN documentation)
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
public sealed class RequiredIfEmptyAttribute : RequiredAttribute
{
public override object TypeId { get; } = new object();
// all the rest of the code
}
我考虑过更改RequiredIfEmpty属性以获取属性的字符串[],但它并不像MVC基础结构允许单个属性返回的多个错误字符串一样。
正确。每个属性不能返回多个消息。但是,您可以实现IValidatableObject
接口来实现此目的。