【问题标题】:Custom attributes C# not working自定义属性 C# 不起作用
【发布时间】:2025-12-06 13:05:01
【问题描述】:

我有 AuthActivityAttribute 类。此类的目的是授权用户具有执行特定活动的权限。

属性类:

[AttributeUsage(AttributeTargets.All)]

public class AuthActivityAttribute : Attribute

{
#region Properties

public string ActivityName { get; set; }

#endregion

#region Constructor

public AuthActivityAttribute()
{

}

#endregion

#region MemberFunctions

private List<aspnetactivities> GetUserActivities(ApplicationUser currentUser)
{
    IList<string> roles = DALAccessObjectObj.UserDALObj.GetUserRoles(currentUser);
    List<aspnetactivities> lstAspnetActivites = new List<aspnetactivities>();
    foreach (string role in roles)
    {
        List<aspnetactivities> activities = DALAccessObjectObj.UserDALObj.GetRoleActivity(role);
        lstAspnetActivites.AddRange(activities);
    }

    return lstAspnetActivites;
}
public void ValidateUserActivity()
{            
    DALAccessObjectObj.UserDALObj = new UserDAL();
    ApplicationUser currentUser = DALAccessObjectObj.UserDALObj.GetUserById(HttpContext.Current.User.Identity.GetUserId());
    if (GetUserActivities(currentUser).Where(r => r.ActivityName.Equals(ActivityName, StringComparison.InvariantCultureIgnoreCase)
            ).Select(r => r).Count() > 0)
    {
        throw new Exception(string.Format("User is not allowed to perform activity named : {0}", ActivityName));
    }

}

#endregion

}

我有一个 Account 控制器类。我所需要的只是用户只有在被允许执行注册活动的情况下才能注册。但是,当我发送请求时,该属性不会验证任何东西。请让我知道我错过了什么或什么?

用属性装饰的类

  public class AccountController : BaseApiController
    {
        [AuthActivityAttribute(ActivityName = "Register")]
        public async Task<IHttpActionResult> Register(RegisterBindingModel model)
        {
            // do something ...
        }
    }

例如:我们对像 [MaxLength(10)] 这样的属性进行验证,因此它验证该属性的长度必须小于 10。或 C# 中的 Authorize 属性。就像只有管理员可以访问特定方法一样。所以这是我需要实现的目标

[Authorize("Administrator")]
public void DeleteUser()
{
// do something
}

我想要什么?

[AuthActivity("DeleteUser")]
public void DeleteUser()
{
// do something
}

【问题讨论】:

  • 那么您期望使用该属性执行验证的目的是什么? PlanhayAttributeBase 是什么?
  • 亲爱的@JonSkeet,请再次检查我已编辑它。
  • 好吧,你已经改变了基类。您还没有解释为什么您希望该属性自动执行某些操作。属性不只是神奇地使代码被执行——必须找到所有相关的属性并采取相应的行动。在您的情况下,您希望这样做?
  • 是的,我想验证用户只有在被允许注册的情况下才能注册。就像只有管理员可以删除用户一样。所以如果用户不是管理员授权失败。
  • 对,然后再次 - 是什么让您认为添加属性会实现这一点?

标签: c# asp.net-mvc attributes custom-attributes


【解决方案1】:

如果您的目标是让或不让用户执行任务,则无需创建自定义属性,您可以为每个操作使用 Authorize 属性并指定允许执行该操作的角色。

无论如何,如果您想使用自定义属性执行某些自定义任务,则必须使用反射来获取具有该属性的操作并获取该属性的属性,例如:

    public static class CustomAttrr
{
    public static IEnumerable<ActionsWithAuthActivityAttribute> GetItems(Assembly types)
    {
        var model = from type in types.GetTypes()
                    from methodInfo in type.GetMethods().Where(x => x.GetCustomAttributes<AuthActivityAttribute>().Any())
                    from attribute in methodInfo.GetCustomAttributes()
                    where attribute is AuthActivityAttribute
                    let a = attribute as AuthActivityAttribute
                    select new ActionsWithAuthActivityAttribute
                    {
                        ActionName = methodInfo.Name,
                        ActivityName = a.ActivityName,
                    };
        return model.ToList();
    }
}

public class AuthActivityAttribute:Attribute
{
    public string ActivityName { get; set; }
}

public class ActionsWithAuthActivityAttribute
{
    public string ActionName { get; set; }
    public string ActivityName { get; set; }
}

现在,您有了一个用您的属性修饰的所有操作的列表,您可以做任何您想做的事情。

  var listAction = CustomAttrr.GetItems(Assembly.GetExecutingAssembly());
  var listActionsRegister = listAction.Where(x => x.ActivityName.Equals("Register"));

现在您可以对照此列表检查用户角色,但就像我说的,您不需要此自定义属性。

我发布此代码只是为了让您了解如何访问自定义属性。

【讨论】: