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-mvc – ASP.NET MVC – 单元测试过度杀毒? (TDD)
- asp.net-mvc-2 – Asp.net Mvc显示String的模板,但现在每个
- asp.net-mvc-3 – 使用接口作为部分视图数据注释的模型类型
- ASP.Net,C#.Net和VB.Net之间的区别?
- asp.net – 当DataList为空时需要显示消息
- asp.net-mvc – 清理MVC 3.0应用程序中抛出的所有错误的方法
- ASP.NET虚拟路径映射到另一个不允许的应用程序
- ASP.NET core Web中使用appsettings.json配置文件的方法
- asp.net – Ajax Control Toolkit正在加载太多脚本资源
- asp.net – 使用jquery调用webmethod时始终获得“
- asp.net-mvc – 如何在MVC WebGrid中显示行号
- asp.net – Orchard CMS Media中的文件大小上传限
- asp.net – IIS配置错误 – 此配置部分不能用于此
- asp.net-mvc – Chrome34忽略域名为“.cloudapp.
- asp.net-mvc – MVC 5 Owin Facebook Auth导致空
- 我应该把我的日志文件放在哪里用于asp.net应用程
- asp.net – 有没有办法动态更新Web API CORS中允
- asp.net – 在webrequest上停止了应用程序池
- 使用Asp.net Web API时,使用DataContract和DataM
