web-dev-qa-db-ja.com

Asp.netmvc-カスタムアクションフィルターからビューモデルにアクセスする

アクションフィルターOnActionExecutedのビューに渡されたモデルデータにアクセスしようとしています。これが可能かどうか誰かが知っていますか?

私はこのようなことをしようとしています:

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    //get model data
    //...

    sitemap.SetCurrentNode(model.Name);
}

何かアドバイス?

38
ebrown

モデルは次のとおりです。

filterContext.Controller.ViewData.Model
57
Steven Lyons

理由はわかりませんが、OnActionExecutedの前にモデルバインドが実行された場合でも、_filterContext.Controller.ViewData.Model_は常にnullです。以前にOnModelUpdatedイベントを使用してそのプロパティを設定する解決策を見つけました。

私はモデルバインダーを持っています:

_public class CustomModelBinder: DefaultModelBinder
{
    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        controllerContext.Controller.ViewData.Model = bindingContext.Model;
        base.OnModelUpdated(controllerContext, bindingContext);
    }
}
_

その後、Global.asaxのApplication_Start()セクションでデフォルトのバインダーを新しいモデルバインダーに設定する必要があります。

_ModelBinders.Binders.DefaultBinder = new CustomModelBinder();
_

最後に、Model内のActionFilterAttributeにアクセスできます。

_public class TraceLog : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        //filterContext.Controller.ViewData.Model now isn't null
        base.OnActionExecuted(filterContext);
    }
}
_
19
gustavocs

メソッドの最後の行をbase.OnActionExecuted()で呼び出すと、「Modelbeingnull」の問題が解決しました。

(これは@Steven Lyonsの回答へのコメントですが、コメントできないため、回答として投稿しています。)

3
Arun Kumar A.J

.Net Coreでは、メソッドのすべてのパラメーターを使用して、コンテキストにActionArgumentsIDictionaryがあります。

したがって、次のコントローラーメソッドがある場合

    [HttpPost]
    public void Post([FromBody]BaseRequest request)
    {
    }

あなたはそのようにフィールドにアクセスすることができます

    public override void OnActionExecuting(ActionExecutingContext context)
    {
      var request = context.ActionArguments["request"] as BaseRequest;`
      //do whatever, 
    }
2
Safin Ahmed

Nullを取得している場合は、@ Gustavo Clementeの回答の代わりに、OnActionExecutedをオーバーライドして、次の方法でviewModelをビューに渡すことができます。

アクション:

[Breadcrumb("Index")]
public ActionResult UnitIndex()
{
    View(new Answers());
}

属性:

public class BreadcrumbAttribute : ActionFilterAttribute
{
    public string Page { get; set; }

    public BreadcrumbAttribute(string page)
    {
        Page = page;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var model = (IBreadcrumbs)filterContext.Controller.ViewData.Model;
        model.Breadcrumbs = BreadcrumbHelper.GetBreadCrumbs(string.Format("{0}", filterContext.RouteData.DataTokens["area"]), Page);
    }
}

enter image description here

1