Asp.net MVC - 从一个自定义的行为过滤访问视图模型

问题描述 投票:35回答:5

我试图访问传递给在OnActionExecuted行动过滤器视图的模型数据。有谁知道这是否可能?

我试图做这样的事情:

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

    sitemap.SetCurrentNode(model.Name);
}

有什么建议?

c# asp.net-mvc custom-action-filter
5个回答
56
投票

该模型是:

filterContext.Controller.ViewData.Model

19
投票

我不知道为什么,但filterContext.Controller.ViewData.Model即使模型绑定是OnActionExecuted之前执行总是空。我发现使用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);
    }
}

2
投票

在.NET中的核心,你有一个ActionArguments IDictionary的上下文,从你的方法的所有参数

所以,如果你有以下控制器方法

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

您可以访问现场,像这样

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

2
投票

使得base.OnActionExecuted()调用该方法的最后一行解决了“模式被空”的问题对我来说。

(这是为了@Steven里昂的答案评论,但我张贴作为一个答案,因为我不能发表评论。)


1
投票

如果您收到空 - 作为替代@Gustavo克莱门特的回答,您可以尝试重写OnActionExecuted和传递您的视图模型到视图方式如下:

行动:

[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

© www.soinside.com 2019 - 2024. All rights reserved.