Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/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
C# 实体框架上下文验证_C#_.net_Entity Framework_Validation - Fatal编程技术网

C# 实体框架上下文验证

C# 实体框架上下文验证,c#,.net,entity-framework,validation,C#,.net,Entity Framework,Validation,当在某些情况下应该应用不同的验证逻辑时,您将如何实现实体框架实体的验证 例如,如果用户是管理员,则以一种方式验证实体,否则以另一种方式验证。在我听到更明智的想法之前,我会这样做: public partial class MyObjectContext { ValidationContext ValidationContext { get; set; } partial void OnContextCreated() { SavingChanges +=

当在某些情况下应该应用不同的验证逻辑时,您将如何实现实体框架实体的验证


例如,如果用户是管理员,则以一种方式验证实体,否则以另一种方式验证。

在我听到更明智的想法之前,我会这样做:

public partial class MyObjectContext
{
    ValidationContext ValidationContext { get; set; }

    partial void OnContextCreated()
    {
        SavingChanges += new EventHandler(EntitySavingChanges);
    }

    private void EntitySavingChanges(object sender, EventArgs e)
    {
        ObjectStateManager
            .GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Deleted)
            .Where(entry => entry.Entity is IValidatable).ToList().ForEach(entry =>
            {
                var entity = entry.Entity as IValidatable;
                entity.Validate(entry, ValidationContext);
            });
    }
}

interface IValidatable
{
    void Validate(ObjectStateEntry entry, ValidationContext context);
}

public enum ValidationContext
{
    Admin,
    SomeOtherContext
}

public partial class MyEntity : IValidatable
{
    public ValidationContext ValidationContext { get; set; }

    public void Validate(ObjectStateEntry entry, ValidationContext context)
    {
        // this validation doesn't apply to admins
        if (context != ValidationContext.Admin)
        {
            // validation logic here
        }
    }  
}

我将验证属性放在特定于上下文的专用编辑模型上


实体只有适用于所有实体的验证。

在我开始讨论如何使用VAB进行验证之前,请允许我说,您必须认真考虑验证规则。虽然可以区分角色之间的验证,但这确实意味着一个角色中的用户保存的对象对另一个用户无效。这意味着具有特定角色的用户可能需要更改该对象,然后才能保存该对象。当同一用户被提升到另一个角色时,也可能发生这种情况。如果您确定要这样做,请继续阅读


这对于企业库(VAB)来说似乎是一项不错的工作,因为它允许对这些复杂场景进行验证。当您想这样做时,忘记基于属性的验证;这根本行不通。您需要基于配置的验证才能使其工作

使用VAB可以做的是使用保存实际验证的配置文件。这在一定程度上取决于实际的验证规则应该是什么,但您可以做的是创建一个基本配置,该配置始终适用于域中的每个对象。然后创建一个或多个只包含扩展验证的配置。例如,假设您有一个
validation\u base.config
文件、一个
validation\u manager.config
和一个
validation\u admin.config
文件

您可以做的是根据用户的角色将这些验证合并在一起。例如,本例根据配置文件创建了三个配置源:

var base = new FileConfigurationSource("validation_base.config");
var mngr = new FileConfigurationSource("validation_manager.config");
var admn = new FileConfigurationSource("validation_admin.config");
现在您必须将这些文件合并到(至少)两个配置中。一个包含基本+管理器,另一个包含基本+管理规则。虽然合并不是开箱即用的支持,但它将向您展示如何进行合并。使用该文章中的代码时,您将能够执行以下操作:

var managerValidations = 
    new ValidationConfigurationSourceCombiner(base, mngr);

var adminValidations =
    new ValidationConfigurationSourceCombiner(base, admn);
您需要做的最后一件事是将这些验证包装在一个类中,该类根据用户的角色返回正确的集。你可以这样说:

public class RoleConfigurationSource : IConfigurationSource
{
    private IConfigurationSource base;
    private IConfigurationSource managerValidations;
    private IConfigurationSource adminValidations;

    public RoleConfigurationSource()
    {
        this.base = new FileConfigurationSource("validation_base.config");
        var mngr = new FileConfigurationSource("validation_manager.config");
        var admn = new FileConfigurationSource("validation_admin.config");

        managerValidations = 
            new ValidationConfigurationSourceCombiner(base, mngr);

        adminValidations =
            new ValidationConfigurationSourceCombiner(base, admn);
    }

    public ConfigurationSection GetSection(string sectionName)
    {
        if (sectionName == ValidationSettings.SectionName)
        {
            if (Roles.UserIsInRole("admin"))
            {
                return this.adminValidations;
            }
            else
            {
                return this.managerValidations;
            }
        }

        return null;
    }

    #region IConfigurationSource Members

    // Rest of the IConfigurationSource members left out.
    // Just implement them by throwing an exception from
    // their bodies; they are not used.

    #endregion
}
现在可以创建一次此
RoleConfigurationSource
,您可以在验证对象时提供它,如下所示:

static readonly IConfigurationSource validationConfiguration =
    new RoleConfigurationSource();

Validator customerValidator =
    ValidationFactory.CreateValidator<Customer>(validationConfiguration);

ValidationResults results = customerValidator.Validate(customer);

if (!results.IsValid)
{
    throw new InvalidOperationException(results[0].Message);
}
静态只读IConfigurationSource validationConfiguration=
新角色配置源();
验证器客户验证器=
CreateValidator(validationConfiguration);
ValidationResults=customerValidator.Validate(客户);
如果(!results.IsValid)
{
抛出新的InvalidOperationException(结果[0]。消息);
}
请注意,验证应用程序块不是一个简单的框架。学习它需要一些时间。然而,当您的应用程序足够大时,您的特定需求将证明它的使用是合理的。如果选择VAB,请从读取“”文档开始。如果您有问题,请在某时回来;-)


祝你好运。

不管它叫什么,你会怎么做?当有一个实体处于无效状态时,我想有条件地阻止它。当你想看看你的模型是否处于一个业务认为它是有效的状态时,在检查这个模型的过程中,你不会改变这个模型并向用户报告任何错误,在这种情况下,我会考虑你正在做的是验证。不同类型的用户是否有不同的规则并不重要。别忘了标记您最喜欢的答案;-)我喜欢。我不喜欢评论中的最小字符。您可以在此处阅读有关将VAB与实体框架集成的更多信息: