0

TViewModelaction filterまたはmodel binderからどのように変更するのですか?aspnet webapiの現在のユーザに応じて実行時にアクションパラメータのタイプを変更する

[HasPriviliege] 
    public IHttpActionResult Get(long id) 
    { 
     var entity = AutoMapper.Mapper.Map<TViewModel, TEntity>(model); 
     repo.Update(id, entity); 
     repo.Save(); 
     return Ok(model); 
    } 

    [HasPriviliege] 
    public IHttpActionResult Edit(long id, TViewModel model) 
    { 
     var entity = AutoMapper.Mapper.Map<TViewModel, TEntity>(model); 
     repo.Update(id, entity); 
     repo.Save(); 
     return Ok(model); 
    } 

フィルタは

public class HasPriviliege:ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     if(getPrivileges()=="doctor"){ 
      //the TViewModel(view model type to bind to) should be 
      // DoctorPatientViewModel should be; 
     }else{ 
      //the TViewModel(view model type to bind to) should be 
      //ExaminationPatientViewModel 
    } 
     //base.OnActionExecuting(actionContext); 
    } 
} 

またはalternativaly、モデルバインダー

public class IPrivilegeableModelBinder: IModelBinder 
{ 
     public object BindModel(ControllerContext controllerContext, 
          ModelBindingContext bindingContext) 
     { 
    //return (hasPriviliege()?DoctorPatientViewModel:ExaminationPatientViewModel) ; 
} 

}

+0

これが助けになるかどうかはわかりませんが、私はこのようなことをコントローラーレベルで達成しました。要求を検査し、一般的な 'Controller 'を新規に作成できるコントローラファクトリを作成しました。これで動作することができました。 –

+0

正確には、タイプ 'T'はどこで設定しますか? – Bellash

答えて

0

あるべきではなく、オーバー肥大化コメントを書く、私は自分を投稿しますジェネリックコントローラーを使ってこれに似た何かを達成した方法についての提案。

コントローラー工場:

public class ControllerFactory : IControllerFactory 
{ 
    public IController CreateController(RequestContext requestContext, string controllerName) 
    { 
     Type controllerType = typeof(GenericController<>); 
     Type genericType = controllerType.MakeGenericType(GetPrivilegeType()); 
     ConstructorInfo ctor = genericType.GetConstructor(new Type[]{}); 
     return (IController)ctor.Invoke(new object[] { }); 
    } 

    public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) 
    { 
     ... 
     return SessionStateBehavior.ReadOnly; 
    } 

    public void ReleaseController(IController controller) 
    { 
     if (controller is IDisposable) 
     { 
      ((IDisposable)controller).Dispose(); 
     } 
    } 

    private string GetPrivilegeType() 
    { 
     if (getPrivileges() == "doctor") { 
      return typeof(DoctorPatientViewModel); 
     } else { 
      return typeof(ExaminationPatientViewModel); 
     } 
    } 
} 

はこのようにそれを登録します。あなたのコントローラは、最も基本的な例です

public class GenericController<TViewModel> // TViewModel will be the privilege type from the factory 
    where TViewModel : IPrivilege 
{ 
    [HasPriviliege] 
    public IHttpActionResult Edit(long id, TViewModel model) 
    { 
     var entity = AutoMapper.Mapper.Map<TViewModel, TEntity>(model); 
     repo.Update(id, entity); 
     repo.Save(); 
     return Ok(model); 
    } 
} 

どのように見えるかを最終的に

ControllerBuilder.Current.SetControllerFactory(new ControllerFactory()); 

...とあなたが達成しようとしているものに何らかの形で進むかもしれないmvcのために働く一般的なコントローラを手に入れてください。

+0

ありがとうございます。これは、あなたのコードを編集したにもかかわらず助けになりました。 '...' 'genericType = controllerType.MakeGenericType(new Type [] {}); ConstructorInfo ctor = genericType.GetConstructor(新しいタイプ[] {}); ' – Bellash

+0

いいですね。それは必要な部分だけを取得するための盲目のカット/チョップの努力でした - 私は今更新しました。 –

+0

これはWebApiを使用してどのように達成できるのか理解していますか? – Bellash

関連する問題