C#表达式树是该任务的正确工具吗?

时间:2014-03-12 15:26:35

标签: c# lambda expression-trees

我的示例项目是MVC WebApi项目。

标准AuthorizeAttribute采用角色=""或用户=""参数。 我还没有看到实现,但我不想要:) 你能用表达式做一点虚拟证明吗? 在某种程度上,当您决定重命名属性"" Roles"时,您会收到编译时错误。财产到其他什么?

public interface IControllerContext
{
    int MagicNumber { get; }
    int ScaryNumber { get; }
    string Version { get; }
}

public class AppAuthorizationAttribute : FilterAttribute
{
    public IControllerContext SomeControllerContext
    {
       get; // implementation omitted
    }

    // ...
}

// This is my sample class which needs to be validated using the attribute.
public class TestClass : BaseClass
{
    [AppAuthorization((n) => n.MagicNumber == 13)] // or literally: which property and how to validate it"
    protected void SomeMethodWhichRequiresPreProcessingValidation()
    {
        // do something.
        // inside here I have access to an instance of ISomeContext
        // and can do anything I want.
    }
}

可选的红利问题:是否可以从属性定义中以某种方式访问​​当前控制器的字段(非静态)?将控制器字段注入验证lambda表达式会很酷。类似的东西:AppAuthorization((controller)=> controller.SomePropertyHere.MagicNumer == 13)

2 个答案:

答案 0 :(得分:4)

属性声明只能使用simple types and constants。编译器不允许您使用表达式,因此您的计划方法将无效。

您也不能引用字段或属性,只能引用常量。你能得到的最接近的是

public const MagicNumberPropertyName = "MagicNumber";
public enum Operator
{
    Equals
}

[AppAuthorization(MagicNumberPropertyName, Operator.Equals, 13)]
protected void Method() {}

答案 1 :(得分:0)

以下是您可以使用Enum for Authorize属性的示例,您可以在授权内编写您的逻辑

 /// <summary>
    /// Class RoleAuthorizeAttribute.
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class RoleAuthorizeAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="RoleAuthorizeAttribute"/> class.
        /// </summary>
        /// <param name="roles">The roles.</param>
        /// <exception cref="System.ArgumentException">The roles parameter may only contain enums;roles</exception>
        public RoleAuthorizeAttribute(params object[] roles)
        {
            if (roles.Any(r => r.GetType().BaseType != typeof (Enum)))
            {
                throw new ArgumentException(
                    "The roles parameter may only contain enums",
                    "roles");
            }
            Roles = string.Join(",", roles.Select(r => Enum.GetName(r.GetType(), r)).ToList());
        }
    }