Cómo conectar parámetros de método en atributo personalizado

Tengo un atributo personalizado llamado AuthoriseAttribute cuyo constructor se parece a esto:

public AuthoriseAttribute(int userId) { .. blah } 

Esto se usa con un método llamado GetUserDetails() como este:

 [Authorise(????????)] public UserDetailsDto GetUserDetails(int userId) { .. blah } 

En tiempo de ejecución, la presencia del atributo Autorizar hace que se ejecute algún código de autorización que requiere la ID del usuario. Obviamente, esto se puede extraer del parámetro del método GetUserDetails() , pero esto significa que el código de autorización depende de que el parámetro del método reciba un nombre particular.

Me gustaría poder pasar el valor real del parámetro userId al atributo, de modo que el código de autorización funcione con el valor pasado al atributo (es decir, no al parámetro del método), cuyo nombre se conoce.

Algo como esto (que no funciona):

 [Authorise(userId)] public UserDetailsDto GetUserDetails(int userId) { .. blah } 

¿Es posible tal cosa?

Haciendo de vcsjones el comentario y la respuesta, esto no es posible.

Los atributos son metadatos; se comstackn en el ensamblaje en tiempo de comstackción y no cambian durante el tiempo de ejecución. Como tal, cualquier parámetro que pase a un atributo debe ser una constante; literales, variables constantes, comstackdor define, etc.

La única forma en que esto funcionaría es hacer que el atributo sea un elemento AOP, usando un marco como PostSharp o con el de Unity Framework, etc. Esto le permitiría adjuntar un “interceptor” al método decorándolo con un atributo, que luego ejecutará el código en el atributo y también tendrá conocimiento sobre cómo se llamó exactamente el método, incluidos los valores de los parámetros. Echa un vistazo a este blog: http://www.progware.org/Blog/post/Interception-and-Interceptors-in-C-(Aspect-oriented-programming).aspx

Hay una manera de hacer esto _ en ASP.NET MVC_ con métodos de acción (no con atributos en general)

 public class CustomAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { int userId = (int)filterContext.ActionParameters["userId"]; } } 

Pude solucionar esto usando lo siguiente:

 public class AuthorizeAttribute { protected bool RequireIdClaim { get; private set; } public AuthorizeAttribute(bool requireIdClaim = false) { RequireIdClaim = requireIdClaim; } public Authorize() { //regular auth stuff here if (RequireIdClaim) { var routeData = context.ActionContext.Request.GetRouteData(); var requiredIdClaim = Convert.ToInt32(routeData.Values["id"]); //Check here if their user profile has a claim to that Id } } } 

Y luego, en los métodos específicos en los que desea verificar las identificaciones,

 [HttpGet] [Route("{id}")] [Authorize(requireIdClaim: true)] public UserDetailsDto GetUserDetails(int userId) { .. blah } 

Y si no te importa comprobar su ID, solo que estén autenticados

 [HttpGet] [Route("")] [Authorize] public bool isLoggedIn() { .. blah } 

Por supuesto, puede organizar su procedimiento de autorización como desee, pero esta idea le permite obtener su ID en su procedimiento de autenticación allí, ya que se pasa como datos de ruta. Más aquí: https://stackoverflow.com/a/16054886