Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何在DB实体的子模型上使用自定义验证属性?_Asp.net Mvc_Data Annotations_Dbcontext - Fatal编程技术网

Asp.net mvc 如何在DB实体的子模型上使用自定义验证属性?

Asp.net mvc 如何在DB实体的子模型上使用自定义验证属性?,asp.net-mvc,data-annotations,dbcontext,Asp.net Mvc,Data Annotations,Dbcontext,摘要: 我希望数据注释验证程序引用同一类中的另一个属性(TitleAuthorAndPublishingConfiguration) 但是,不会直接对此类调用DB.SaveChanges()。而是在这个类的父类(WebsiteConfiguration)上调用它 因此,validationContext.ObjectType正在返回WebsiteConfiguration,我无法在数据批注验证器中引用标题作者和发布配置的属性 WebsiteConfiguration.cs public cla

摘要:


我希望数据注释验证程序引用同一类中的另一个属性(
TitleAuthorAndPublishingConfiguration

但是,不会直接对此类调用DB.SaveChanges()。而是在这个类的父类(
WebsiteConfiguration
)上调用它

因此,
validationContext.ObjectType
正在返回
WebsiteConfiguration
,我无法在数据批注验证器中引用
标题作者和发布配置的属性


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...
DbSet<WebsiteConfiguration> WebsiteConfiguration {get;set;}
ApplicationDbContext.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...
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;
    }
}

问题

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...
DbSet<WebsiteConfiguration> WebsiteConfiguration {get;set;}
  • 我是否可以通过
    validationContext
    访问子模型属性

  • 我的方法是否被误导了?是否有更好的方法将多个模型作为较大模型的一部分存储在单个DB表中

  • 我不希望有多个配置表和对数据库的调用。(本例中有4个子模型,但在下一个应用中可能有10多个子模型。)

    上面的设置在很多方面满足了我的需要。但我不想放弃子模型上的DataAnnotation功能


    奖金问题

    我遇到过一些类似这样的帖子:

    但这已经是4年前的事了,我想知道从那以后是否有什么变化

    我是否在尝试做一些基本上不可能(或至少非常困难)的事情

    我是否在尝试做一些基本上不可能的事情(或者至少是不可能的) 很难吗

    不,有一个非常简单的解决方案,它与使用DataAnnotation的框架和技术完美集成

    您可以创建由EF Validation调用的自定义
    ValidationAttribute
    ,并在内部调用
    Validator.TryValidateObject
    。这样,当EF调用
    CustomValidation.IsValid
    时,您可以手动启动整个对象图的子复杂对象验证,依此类推。作为奖励,您可以通过
    CompositeValidationResult
    收集所有错误

    i、 e

    使用系统;
    使用System.ComponentModel.DataAnnotations;
    使用System.Collections.Generic;
    公共课程
    {
    公共静态void Main(){
    var person=新的人{
    地址=新地址{
    城市=“小镇”,
    State=“TX”,
    Zip=新的ZipCode()
    },
    Name=“肯特”
    };
    var context=新的ValidationContext(person,null,null);
    var results=新列表();
    TryValidateObject(person、context、results、true);
    打印结果(结果,0);
    Console.ReadKey();
    }
    私有静态void打印结果(IEnumerable结果,Int32缩进级别){
    foreach(结果中的var validationResult){
    Console.WriteLine(validationResult.ErrorMessage);
    Console.WriteLine();
    如果(validationResult为CompositeValidationResult){
    打印结果(((CompositeValidationResult)validationResult)。结果,缩进级别+1);
    }
    }
    }
    }
    公共类ValidateObject属性:ValidationAttribute{
    受保护的重写ValidationResult有效(对象值,ValidationContext ValidationContext){
    var results=新列表();
    var context=newvalidationcontext(值,null,null);
    TryValidateObject(值、上下文、结果、true);
    如果(results.Count!=0){
    var compositeResults=new CompositeValidationResult(String.Format(“验证{0}失败!”,validationContext.DisplayName));
    results.ForEach(compositeResults.AddResult);
    返回合成结果;
    }
    返回ValidationResult.Success;
    }
    }
    公共类CompositeValidationResult:ValidationResult{
    私有只读列表_results=new List();
    可数结果{
    得到{
    返回结果;
    }
    }
    公共CompositeValidationResult(字符串errorMessage):基(errorMessage){}
    公共CompositeValidationResult(字符串errorMessage,IEnumerable memberNames):基(errorMessage,memberNames){}
    受保护的CompositeValidationResult(ValidationResult ValidationResult):基(ValidationResult){}
    public void AddResult(ValidationResult ValidationResult){
    _结果。添加(validationResult);
    }
    }
    公共阶层人士{
    [必需]
    公共字符串名称{get;set;}
    [必需,验证对象]
    公共广播地址{get;set;}
    }
    公共课堂演讲{
    [必需]
    公共字符串Street1{get;set;}
    公共字符串Street2{get;set;}
    [必需]
    公共字符串City{get;set;}
    [必需]
    公共字符串状态{get;set;}
    [必需,验证对象]
    公共ZipCode Zip{get;set;}
    }
    公共类ZipCode{
    [必需]
    公共字符串主代码{get;set;}
    公共字符串子代码{get;set;}
    }
    
    我希望在
    TitleAuthorAndPublishingConfiguration
    的属性上使用数据注释验证器来引用
    TitleAuthorAndPublishingConfiguration
    的另一个属性。但是,
    DB.SaveChanges()
    并不是直接在这个类上调用的,而是在它的父级-
    WebsiteConfiguration
    上调用的,希望澄清一下,您是否拥有
    标题author and publishingconfiguration
    验证程序?我在问题中添加了验证程序代码-这就是您的意思吗?谢谢。我要试一试。