C# MVC 3-RequiredAttribute-基于会话的覆盖

C# MVC 3-RequiredAttribute-基于会话的覆盖,c#,asp.net-mvc,C#,Asp.net Mvc,我有一个这样的模型,有几个字段,比如姓名、电子邮件和电话。 所有这些都使用[Required]属性设置 我想做的是重写RequiredAttribute,并且仅当网站的当前访问者不是管理员时才需要该属性。因此,管理员基本上可以键入他们喜欢的内容,或者像普通用户一样将字段留空 有人能给我指出正确的方向或建议实现这一目标的最佳方法吗 要了解访客是否是管理员,我使用: var permissionId = Helpers.ConvertToInt(Services.UserService.GetCur

我有一个这样的模型,有几个字段,比如姓名、电子邮件和电话。 所有这些都使用[Required]属性设置

我想做的是重写RequiredAttribute,并且仅当网站的当前访问者不是管理员时才需要该属性。因此,管理员基本上可以键入他们喜欢的内容,或者像普通用户一样将字段留空

有人能给我指出正确的方向或建议实现这一目标的最佳方法吗

要了解访客是否是管理员,我使用:

var permissionId = Helpers.ConvertToInt(Services.UserService.GetCurrentPermissionId().ToString());

如果为0或1,则访问者不是管理员,因此该字段应为必填字段。

您可以编写自定义条件验证属性:

public class RequiredIfPermissionIdsAttribute : RequiredAttribute
{
    public int[] PermissionIds { get; private set; }

    public RequiredIfPermissionIdsAttribute(params int[] permissionIds)
    {
        PermissionIds = permissionIds ?? new int[0];
    }

    public override bool IsValid(object value)
    {
        int permissionId = Helpers.ConvertToInt(Services.UserService.GetCurrentPermissionId().ToString());

        if (PermissionIds.Contains(permissionId))
        {
            return base.IsValid(value);
        }

        // the current permission id is not in the list of permission ids
        // that require validation => we consider the model valid
        return true;
    }
}
[RequiredIfPermissionIds(0, 1)]
public string SomeProperty { get; set; }
然后你可以用这个属性来装饰你的房子:

public class RequiredIfPermissionIdsAttribute : RequiredAttribute
{
    public int[] PermissionIds { get; private set; }

    public RequiredIfPermissionIdsAttribute(params int[] permissionIds)
    {
        PermissionIds = permissionIds ?? new int[0];
    }

    public override bool IsValid(object value)
    {
        int permissionId = Helpers.ConvertToInt(Services.UserService.GetCurrentPermissionId().ToString());

        if (PermissionIds.Contains(permissionId))
        {
            return base.IsValid(value);
        }

        // the current permission id is not in the list of permission ids
        // that require validation => we consider the model valid
        return true;
    }
}
[RequiredIfPermissionIds(0, 1)]
public string SomeProperty { get; set; }
或者,您可以使用白名单方法代替黑名单方法:

public class NotRequiredIfPermissionIdsAttribute : RequiredAttribute
{
    public NotRequiredIfPermissionIdsAttribute(params int[] permissionIds)
    {
        PermissionIds = permissionIds ?? new int[0];
    }

    public int[] PermissionIds { get; private set; }

    public override bool IsValid(object value)
    {
        int permissionId = Helpers.ConvertToInt(Services.UserService.GetCurrentPermissionId().ToString());

        if (!PermissionIds.Contains(permissionId))
        {
            return base.IsValid(value);
        }

        return true;
    }
}
然后:

[NotRequiredIfPermissionIds(2)]
public string SomeProperty { get; set; }

您可以编写自定义条件验证属性:

public class RequiredIfPermissionIdsAttribute : RequiredAttribute
{
    public int[] PermissionIds { get; private set; }

    public RequiredIfPermissionIdsAttribute(params int[] permissionIds)
    {
        PermissionIds = permissionIds ?? new int[0];
    }

    public override bool IsValid(object value)
    {
        int permissionId = Helpers.ConvertToInt(Services.UserService.GetCurrentPermissionId().ToString());

        if (PermissionIds.Contains(permissionId))
        {
            return base.IsValid(value);
        }

        // the current permission id is not in the list of permission ids
        // that require validation => we consider the model valid
        return true;
    }
}
[RequiredIfPermissionIds(0, 1)]
public string SomeProperty { get; set; }
然后你可以用这个属性来装饰你的房子:

public class RequiredIfPermissionIdsAttribute : RequiredAttribute
{
    public int[] PermissionIds { get; private set; }

    public RequiredIfPermissionIdsAttribute(params int[] permissionIds)
    {
        PermissionIds = permissionIds ?? new int[0];
    }

    public override bool IsValid(object value)
    {
        int permissionId = Helpers.ConvertToInt(Services.UserService.GetCurrentPermissionId().ToString());

        if (PermissionIds.Contains(permissionId))
        {
            return base.IsValid(value);
        }

        // the current permission id is not in the list of permission ids
        // that require validation => we consider the model valid
        return true;
    }
}
[RequiredIfPermissionIds(0, 1)]
public string SomeProperty { get; set; }
或者,您可以使用白名单方法代替黑名单方法:

public class NotRequiredIfPermissionIdsAttribute : RequiredAttribute
{
    public NotRequiredIfPermissionIdsAttribute(params int[] permissionIds)
    {
        PermissionIds = permissionIds ?? new int[0];
    }

    public int[] PermissionIds { get; private set; }

    public override bool IsValid(object value)
    {
        int permissionId = Helpers.ConvertToInt(Services.UserService.GetCurrentPermissionId().ToString());

        if (!PermissionIds.Contains(permissionId))
        {
            return base.IsValid(value);
        }

        return true;
    }
}
然后:

[NotRequiredIfPermissionIds(2)]
public string SomeProperty { get; set; }

我建议您考虑使用它,它将允许您指定比内置数据注释更复杂的规则,而无需构建自定义属性

然后,您可以使用类似以下语法来解决此问题:

RuleFor(obj => obj.Email).NotEmpty().Unless(obj => Helpers.ConvertToInt(Services.UserService.GetCurrentPermissionId()) > 1)

我建议您考虑使用它,它将允许您指定比内置数据注释更复杂的规则,而无需构建自定义属性

然后,您可以使用类似以下语法来解决此问题:

RuleFor(obj => obj.Email).NotEmpty().Unless(obj => Helpers.ConvertToInt(Services.UserService.GetCurrentPermissionId()) > 1)

如果要将验证扩展到客户端,还需要覆盖GetClientValidationRules并有条件地执行base.GetClientValidationRules,这取决于是否存在匹配项。我喜欢此解决方案,但我也需要它在客户端工作,有人能告诉我GetClientValidationRules的重写是如何工作的吗。我尝试了这一点,但一直遇到问题。这可以通过实现
iclientvalidable
接口实现,但您打算如何调用
Helpers.ConvertToInt(Services.UserService.GetCurrentPermissionId().ToString())方法?这当然是不可能的。您可以使用
[Remote]
属性在服务器上安全地执行此验证。这是我绝对不建议您在客户端实现的。如果您想将验证扩展到客户端,您还需要覆盖GetClientValidationRules并有条件地执行base.GetClientValidationRules,这取决于是否存在匹配项。我喜欢此解决方案,但我需要它来处理客户端,还有谁能告诉我GetClientValidationRules的重写是如何工作的。我尝试了这一点,但一直遇到问题。这可以通过实现
iclientvalidable
接口实现,但您打算如何调用
Helpers.ConvertToInt(Services.UserService.GetCurrentPermissionId().ToString())方法?这当然是不可能的。您可以使用
[Remote]
属性在服务器上安全地执行此验证。这是我绝对不建议您在客户机上实现的东西。我无法让“除非”起作用,它似乎只能使用模型属性而不是变量。我通过将RuleFor包装在If语句中来实现这一点。我无法让“除非”起作用,它似乎只能使用模型属性而不是变量。我通过将RuleFor包装在If语句周围来实现这一点。