asp.net-mvc – 如何在DB实体的子模型上使用自定义验证属性?
概要:
我想要一个数据注释验证器引用同一个类中的另一个属性(TitleAuthorAndPublishingConfiguration). 但是,DB.SaveChanges()没有直接在此类上调用.而是在该类的父级(WebsiteConfiguration)上被调用. 因此,validationContext.ObjectType正在返回WebsiteConfiguration,我无法引用数据注释验证器中TitleAuthorAndPublishingConfiguration的属性. WebsiteConfiguration.cs public class WebsiteConfiguration { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; } public TitleAuthorAndPublishingConfiguration TitleAuthorAndPublishing { get; set; } public BookChaptersAndSectionsConfiguration BookChaptersAndSections { get; set; } public SocialMediaLoginsConfiguration SocialMediaLogins { get; set; } public TagGroupsConfiguration TagGroups { get; set; } } public class TitleAuthorAndPublishingConfiguration { public string BookTitle { get; set; } public bool IsPublished { get; set; } // how do I access a property of current model when calling DB.SaveChanges() on parent? [RequiredIfOtherFieldIsEnabled("IsPublished")] public string Publisher { get; set; } } // ... and other sub models... ApplicationDbContext.cs DbSet<WebsiteConfiguration> WebsiteConfiguration {get;set;} 示例更新代码 public void SeedWebsiteConfiguration() { var titleAuthorAndPublishingConfiguration = new TitleAuthorAndPublishingConfiguration() { // seed values }; var bookChaptersAndSectionsConfiguration = new BookChaptersAndSectionsConfiguration() { // seed values }; var socialMediaLoginConfiguration = new SocialMediaLoginsConfiguration() { // seed values }; var tagGroupsConfiguration = new TagGroupsConfiguration() { // seed values }; var websiteConfiguration = new WebsiteConfiguration() { TitleAuthorAndPublishing = titleAuthorAndPublishingConfiguration,BookChaptersAndSections = bookChaptersAndSectionsConfiguration,SocialMediaLogins = socialMediaLoginConfiguration,TagGroups = tagGroupsConfiguration }; DB.WebsiteConfiguration.Add(websiteConfiguration); DB.SaveChanges(); } 验证码 public class RequiredIfOtherFieldIsEnabledAttribute : ValidationAttribute { private string _ifWhatIsEnabled { get; set; } public RequiredIfOtherFieldIsEnabledAttribute(string IfWhatIsEnabled) { _ifWhatIsEnabled = IfWhatIsEnabled; } protected override ValidationResult IsValid(object currentPropertyValue,ValidationContext validationContext) { var isEnabledProperty = validationContext.ObjectType.GetProperty(_ifWhatIsEnabled); if (isEnabledProperty == null) { return new ValidationResult( string.Format("Unknown property: {0}",_ifWhatIsEnabled) ); } var isEnabledPropertyValue = (bool)isEnabledProperty.GetValue(validationContext.ObjectInstance,null); if (isEnabledPropertyValue == true) { if (String.IsNullOrEmpty(currentPropertyValue.ToString())) { return new ValidationResult(String.Format("This field is required if {0} is enabled",isEnabledProperty)); } } return ValidationResult.Success; } } 问题 >有没有办法让我从validationContext访问子模型属性? 我希望不要有多个配置表和调用DB. (在这个例子中有4个孩子模型,但在下一个应用中可能有10个.) 上面的设置以很多方式满足了我的需求.但是我不想放弃DataAnnotations在子模型上的功能! 奖金问题 我遇到过这样一个帖子: 但是那是4岁,我想知道自那以后有没有改变. 我是否试图做一些基本上不可能的事情(至少是非常困难的)? 解决方法
不,有一个非常简单的解决方案,与DataAnnotations的框架和技术完美结合. 您可以创建一个自定义ValidationAttribute,由EF Validation调用,并在其中调用Validator.TryValidateObject.这样,当通过EF调用CustomValidation.IsValid时,您可以手动启动子对象验证,以此等等对整个对象图进行验证.作为奖金,您可以收集所有错误,谢谢CompositeValidationResult. 即 using System; using System.ComponentModel.DataAnnotations; using System.Collections.Generic; public class Program { public static void Main() { var person = new Person { Address = new Address { City = "SmallVille",State = "TX",Zip = new ZipCode() },Name = "Kent" }; var context = new ValidationContext(person,null,null); var results = new List<ValidationResult>(); Validator.TryValidateObject(person,context,results,true); PrintResults(results,0); Console.ReadKey(); } private static void PrintResults(IEnumerable<ValidationResult> results,Int32 indentationLevel) { foreach (var validationResult in results) { Console.WriteLine(validationResult.ErrorMessage); Console.WriteLine(); if (validationResult is CompositeValidationResult) { PrintResults(((CompositeValidationResult)validationResult).Results,indentationLevel + 1); } } } } public class ValidateObjectAttribute: ValidationAttribute { protected override ValidationResult IsValid(object value,ValidationContext validationContext) { var results = new List<ValidationResult>(); var context = new ValidationContext(value,null); Validator.TryValidateObject(value,true); if (results.Count != 0) { var compositeResults = new CompositeValidationResult(String.Format("Validation for {0} failed!",validationContext.DisplayName)); results.ForEach(compositeResults.AddResult); return compositeResults; } return ValidationResult.Success; } } public class CompositeValidationResult: ValidationResult { private readonly List<ValidationResult> _results = new List<ValidationResult>(); public IEnumerable<ValidationResult> Results { get { return _results; } } public CompositeValidationResult(string errorMessage) : base(errorMessage) {} public CompositeValidationResult(string errorMessage,IEnumerable<string> memberNames) : base(errorMessage,memberNames) {} protected CompositeValidationResult(ValidationResult validationResult) : base(validationResult) {} public void AddResult(ValidationResult validationResult) { _results.Add(validationResult); } } public class Person { [Required] public String Name { get; set; } [Required,ValidateObject] public Address Address { get; set; } } public class Address { [Required] public String Street1 { get; set; } public String Street2 { get; set; } [Required] public String City { get; set; } [Required] public String State { get; set; } [Required,ValidateObject] public ZipCode Zip { get; set; } } public class ZipCode { [Required] public String PrimaryCode { get; set; } public String SubCode { get; set; } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – “用户首选项”数据库表设计
- ASP.NET WebApi文件下载
- asp.net – 无法编写输出文件… pdb visual studio 2010
- asp.net – TinyMCE在我第一次保存时不会返回任何值
- DevExpress v17.2新版亮点—ASP.NET篇(二)
- Asp.net Core +MVC+Bootstrap开发项目实站2
- asp.net – 如何以编程方式将位置元素添加到Web配置?
- asp.net – 工作线程和I/O线程有什么区别?
- asp.net – 获取当前请求的凭据以便在WebRequest中使用
- asp.net – 将Eval参数从ASPX文件传递给JavaScript函数
- 从ASP.NET WebForms迁移到ASP.NET MVC
- asp.net – Web配置转换不工作
- asp.net – VS2012 Crystal Report Viewer组树隐
- asp.net – GridView中的TemplateField标题
- asp.net – 如何正确使用RegisterForEventValida
- 使用ASP.net和VB.net(或C#)从XML文件编辑和删除数
- asp.net – 在为app_offline.htm提供特定URL时,将
- asp.net 自动将汉字转换成拼音第一个字母
- asp.net – 在同一站点上使用基本身份验证和表单
- asp.net-mvc-3 – 当调用Controller.PartialView