0

我有控制器的操作,它与一些实体(驱动程序)一起工作。此外,每个驱动程序链接与身份配置文件如何在许多控制器的许多操作中实现一些代码

 public async Task<ActionResult> Details(int? id) 
     { 
      if ((id == null)) 
      { 
       return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
      } 
      DriverDetailVM model = mapper.Map<DriverDetailVM>(db.Drivers.Find(id)); 
      if ((model == null)) 
      { 
       return HttpNotFound(); 
      } 
      return View(model); 
     } 

     public async Task<ActionResult> Edit(int? id = null, bool isNewUser = false) 
     { 
///////// 
     } 

如果用户有角色“超级管理员”然后,他访问具有价值的任何标识的页面。如果用户具有“驱动程序”角色,那么只有当id值与他的个人资料相同时,我们才应该有权访问。我尝试实现它ActionFilter:

public class DriverAccessActionFilterAttribute : ActionFilterAttribute 
{ 
    public string IdParamName { get; set; } 
    public int DriverID { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (filterContext.HttpContext.User.IsInRole("Driver")) 
     { 
      if (filterContext.ActionParameters.ContainsKey(IdParamName)) 
      { 
       var id = filterContext.ActionParameters[IdParamName] as Int32; 
       if (id != DriverID) 
        filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden); 
      } 
      else 
       filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
     } 
     else 
      base.OnActionExecuting(filterContext); 
    } 
} 

但是当我尝试使用此代码:

[DriverAccessActionFilter(DriverID = currentUser.DriverId, IdParamName = "id")] 
    public async Task<ActionResult> Details(int? id) 
    { 

它不希望被编译,因为

对象引用所需的非静电场,方法或 属性

如何实现它?

回答

2

属性参数在编译时评估,而不是在运行时评估。所以他们必须是编译时间常量。您无法在运行时将值传递给动作属性。即在[DriverAccessActionFilter(DriverID = currentUser.DriverId, IdParamName = "id")]您通过DriverID = currentUser.DriverId。一个属性用作控制器/操作元数据,元数据需要在汇编中编译。这就是为什么属性只能取值不变的原因。

你必须改变你的属性如下:

  1. 使用依赖注入注入你的服务,回报用户登录。
  2. 或实现自定义委托人并为其分配当前请求委托人。

您可以通过修改属性作为跟随的情况下,要实现CustomPrinicpal:

public class DriverAccessActionFilterAttribute : ActionFilterAttribute 
    { 
     public string IdParamName { get; set; } 
     private int DriverID { get; set; } 

     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     {    
      if (filterContext.HttpContext.User.IsInRole("Driver")) 
      { 
       var customPrincipal = filterContext.HttpContext.User as CustomPrincipal; 
       DriverID = customPrincipal.Id; 
       // Rest of you logic     
      } 
      else 
       base.OnActionExecuting(filterContext); 
     } 
    } 

如果您选择DI路径,那么你可以使用下面的代码片段:

public class DriverAccessActionFilterAttribute : ActionFilterAttribute 
{ 
    public string IdParamName { get; set; } 
    private int DriverID { get; set; } 

    public DriverAccessActionFilterAttribute(IYourIdentityProvider provider) 
    { 
     DriverID = provider.LoggedInUserID; 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {    
     // Your logic 
    } 
} 

,然后用你的属性为[DriverAccessActionFilter(IdParamName = "id")]

+0

我想过校长,谢谢 –

+0

不客气,试着开车'AuthorizationFilterAttribute'而不是'ActionFilterAttribute'。 – Zeeshan