使用 System.ComponentModel.DataAnnotations 时有什么方法可以禁用验证吗?
不幸的是,这里的其他查询并没有回答我的问题,我希望在这个问题上能有天才的一击。
目前的问题是我有一个域对象“GamePlayer”,它有许多 DataAnnotations 来对从 UI 传入的数据提供模型验证。这些工作很不错,并且是完全可测试的等等。
然而,我们有一个数据库,其中的数据在几年内允许随意增长(大约 660,000 个用户帐户),我想说目前有 20,000 到 50,000 个帐户违反了我们在 GamePlayer 对象上设置的规则。
因此,我希望能够做的仍然是使用数据注释,但能够在从数据库到模型总体的过程中“禁用”它们。
我知道,如果我使用 ModelMetaData 内容并将验证属性存储在另一个类中并将主类与 [MetadataType(typeof(GamePlayerMetadata))] 相关联,我可以这样做:
TypeDescriptor.AddProvider(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(GamePlayer), typeof(GamePlayerMetadata)), typeof(GamePlayer));
因此,执行相反的操作 (.RemoveProvider) 以删除规则 - 这是可行的,尽管我不想使用 ModelMetaData 类并将其全部保留在一个中(如果可以的话)?
希望不要太胡言乱语:)
干杯任何帮助, Terry
希望支持这种情况的附加信息:
[Serializable]
[MetadataType(typeof(AddressMetadata))]
public class Address
{
[NonSerialized]
private readonly AssociatedMetadataTypeTypeDescriptionProvider metadataAddress;
public string House { get; private set; }
public string SubPremises { get; private set; }
public string Street { get; private set; }
public string Town { get; private set; }
public string County { get; private set; }
public string Country { get; private set; }
public string Postcode { get; private set; }
internal Address()
{
metadataAddress = new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Address), typeof(AddressMetadata));
TypeDescriptor.AddProviderTransparent(metadataAddress, typeof(Address));
}
internal Address(AddressDto address) : this()
{
this.House = address.House;
this.SubPremises = address.SubPremises;
this.Street = address.Street;
this.Town = address.Town;
this.County = address.County;
this.Country = address.Country;
this.Postcode = address.Postcode;
}
public Address(string house, string subPremises, string street, string town, string county, string country, string postcode) : this()
{
SetAddress(house, subPremises, street, town, county, country, postcode);
}
#region ------------------------------------------------------------------------------------- Methods --
public bool IsSet()
{
return !((String.IsNullOrEmpty(House) && String.IsNullOrEmpty(this.SubPremises)) && String.IsNullOrEmpty(Postcode) && String.IsNullOrEmpty(Street));
}
/// <exception cref="ValidationException">Thrown when one of the fields doesn't match the business complexity rules</exception>
public void SetAddress(string house, string subPremises, string street, string town, string county, string country, string postcode)
{
Validator.ValidateProperty(house, new ValidationContext(this, null, null) { MemberName = "House" });
Validator.ValidateProperty(street, new ValidationContext(this, null, null) { MemberName = "Street" });
Validator.ValidateProperty(postcode, new ValidationContext(this, null, null) { MemberName = "Postcode" });
House = house;
SubPremises = subPremises;
Street = street;
Town = town;
County = county;
Country = country;
Postcode = postcode;
}
/// <exception cref="ValidationException">Thrown when one of the fields doesn't match the business complexity rules</exception>
public void SetAddress(Address newAddress)
{
this.SetAddress(newAddress.House, newAddress.SubPremises, newAddress.Street, newAddress.Town, newAddress.County, newAddress.Country, newAddress.Postcode);
}
public string FirstLineOfAddress
{
get
{
return String.Format("{0}{1}, {2}",
(String.IsNullOrEmpty(this.SubPremises) ? "" : this.SubPremises),
(String.IsNullOrEmpty(this.SubPremises) ? this.House : ", " + this.House),
this.Street
);
}
}
public override string ToString()
{
return String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}",
House,
SubPremises,
Street,
Town,
County,
Postcode,
Country);
}
public AddressDto ToAddressDto()
{
return new AddressDto { House = this.House, SubPremises = this.SubPremises, Street = this.Street,
Town = this.Town, County = this.County, Country = this.Country, Postcode = this.Postcode };
}
public void DisableValidation()
{
TypeDescriptor.RemoveProviderTransparent(metadataAddress, typeof(Address));
}
#endregion
}
为了简单起见,让我们假设“House”上的 AddressMetadata 有一个 [Required] 属性,尽管显然我也有邮政编码等的正则表达式。
假设我正在同一个程序集中工作,因此内部修饰符并不重要。
现在,如果我调用:
Address stuff = new Address("", "", "", "", "", "", "");
然后验证就会启动(通过 SetAddress) no根本就是问题。
如果我这样做:
Address stuff = new Address();
stuff.DisableValidation();
stuff.SetAddress("", "", "", "", "", "", "");
我希望验证被禁用。
这对任何人提供更多信息有帮助吗?
The other queries on here don't unfortunately answer my question, and I'm hoping for a stroke of genius on this one.
The problem currently is I have a domain object 'GamePlayer' which has a number of DataAnnotations to provide model validation on data incoming from the UI. These work a treat, and are fully testable etc.
We however have a database where the data has been allowed to grow haphazardly over a period of years (approximately 660,000 user accounts), and I'd say between 20,000 and 50,000 accounts currently violate the rules that we've put in place on the GamePlayer object.
So, what I hope to be able to do is still use Data Annotations, but be able to 'disable' them on the way from the DB up to the population of the model.
I know that if I use the ModelMetaData stuff and store the validation attributes in another class and associate the main class with [MetadataType(typeof(GamePlayerMetadata))], I can do:
TypeDescriptor.AddProvider(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(GamePlayer), typeof(GamePlayerMetadata)), typeof(GamePlayer));
and hence, do the reverse (.RemoveProvider) to remove the rules - this works, though I'd rather not use the ModelMetaData class and keep it all in one if I can?
Hopefully not waffled too much :)
Cheers for any help,
Terry
Additional Information to hopefully support the case:
[Serializable]
[MetadataType(typeof(AddressMetadata))]
public class Address
{
[NonSerialized]
private readonly AssociatedMetadataTypeTypeDescriptionProvider metadataAddress;
public string House { get; private set; }
public string SubPremises { get; private set; }
public string Street { get; private set; }
public string Town { get; private set; }
public string County { get; private set; }
public string Country { get; private set; }
public string Postcode { get; private set; }
internal Address()
{
metadataAddress = new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Address), typeof(AddressMetadata));
TypeDescriptor.AddProviderTransparent(metadataAddress, typeof(Address));
}
internal Address(AddressDto address) : this()
{
this.House = address.House;
this.SubPremises = address.SubPremises;
this.Street = address.Street;
this.Town = address.Town;
this.County = address.County;
this.Country = address.Country;
this.Postcode = address.Postcode;
}
public Address(string house, string subPremises, string street, string town, string county, string country, string postcode) : this()
{
SetAddress(house, subPremises, street, town, county, country, postcode);
}
#region ------------------------------------------------------------------------------------- Methods --
public bool IsSet()
{
return !((String.IsNullOrEmpty(House) && String.IsNullOrEmpty(this.SubPremises)) && String.IsNullOrEmpty(Postcode) && String.IsNullOrEmpty(Street));
}
/// <exception cref="ValidationException">Thrown when one of the fields doesn't match the business complexity rules</exception>
public void SetAddress(string house, string subPremises, string street, string town, string county, string country, string postcode)
{
Validator.ValidateProperty(house, new ValidationContext(this, null, null) { MemberName = "House" });
Validator.ValidateProperty(street, new ValidationContext(this, null, null) { MemberName = "Street" });
Validator.ValidateProperty(postcode, new ValidationContext(this, null, null) { MemberName = "Postcode" });
House = house;
SubPremises = subPremises;
Street = street;
Town = town;
County = county;
Country = country;
Postcode = postcode;
}
/// <exception cref="ValidationException">Thrown when one of the fields doesn't match the business complexity rules</exception>
public void SetAddress(Address newAddress)
{
this.SetAddress(newAddress.House, newAddress.SubPremises, newAddress.Street, newAddress.Town, newAddress.County, newAddress.Country, newAddress.Postcode);
}
public string FirstLineOfAddress
{
get
{
return String.Format("{0}{1}, {2}",
(String.IsNullOrEmpty(this.SubPremises) ? "" : this.SubPremises),
(String.IsNullOrEmpty(this.SubPremises) ? this.House : ", " + this.House),
this.Street
);
}
}
public override string ToString()
{
return String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}",
House,
SubPremises,
Street,
Town,
County,
Postcode,
Country);
}
public AddressDto ToAddressDto()
{
return new AddressDto { House = this.House, SubPremises = this.SubPremises, Street = this.Street,
Town = this.Town, County = this.County, Country = this.Country, Postcode = this.Postcode };
}
public void DisableValidation()
{
TypeDescriptor.RemoveProviderTransparent(metadataAddress, typeof(Address));
}
#endregion
}
Lets assume for simplicity's sake that AddressMetadata on 'House' has a [Required] attribute, though obviously I have regular expressions for postcode, etc. etc. too.
Lets assume I'm working in the same assembly so the internal modifier isn't important.
Now if I call:
Address stuff = new Address("", "", "", "", "", "", "");
then the validation kicks in (via SetAddress) no problem at all.
If I do:
Address stuff = new Address();
stuff.DisableValidation();
stuff.SetAddress("", "", "", "", "", "", "");
I expect the validation to be disabled.
Does that help anyone provide more information?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论