0

私はいくつかのエンティティ(ドライバ)で動作するアクションを持つコントローラを持っています。また、各ドライバはIDプロファイルにリンクされています。多くのコントローラの多くのアクションでいくつかのコードを実装する方法

 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値を持つページにアクセスできます。ユーザーがロール "ドライバ"を持っている場合、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 DriverAccessActionFilterAttribute(IYourIdentityProvider provider) 
    { 
     DriverID = provider.LoggedInUserID; 
    } 

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

してから使用してください。あなたは、あなたは以下のコードを使用することができDIパスを選択した場合

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); 
     } 
    } 

をあなたの属性として[DriverAccessActionFilter(IdParamName = "id")]

+0

私はプリンシパルについて考えて、ありがとうございます –

+0

あなたは歓迎してからドライブを試みてください'ActionFilterAttribute'の代わりに' AuthorizationFilterAttribute'があります。 – Zeeshan

関連する問題