Asp.net mvc - доступ к модели представления из пользовательского фильтра действий

Я пытаюсь получить доступ к данным модели, переданным представлению в фильтре действий OnActionExecuted. Кто-нибудь знает возможно ли это?

Я пытаюсь сделать что-то вроде этого:

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

    sitemap.SetCurrentNode(model.Name);
}

Любой совет?

16.05.2009 16:52:11
5 ОТВЕТОВ
РЕШЕНИЕ

Модель находится по адресу:

filterContext.Controller.ViewData.Model
57
16.05.2009 16:56:01
Это всегда
Korayem 26.11.2011 01:08:06
@Korayem - зависит от того, как рано вы пытаетесь получить к нему доступ. Если вы получите его после выполнения действия контроллера, это должен быть экземпляр модели представления.
JBeckton 25.01.2013 03:53:40
Для меня это пустой метод во всех методах (OnActionExecuting, OnActionExecuted, OnResultExecuting, OnResultExecuted)
Péter 18.09.2013 11:26:40
пожалуйста, смотрите схему конвейера , чтобы понять, когда модель установлена ​​на viewdata.
QuantumHive 27.10.2016 12:32:15

Я не знаю почему, но 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);
    }
}

После этого вам нужно установить привязку по умолчанию для новой привязки модели в Application_Start()разделе в Global.asax:

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
13.01.2016 15:33:42

Если вы получаете 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);
    }
}

введите описание изображения здесь

1
17.11.2015 14:10:24
Откуда этот код? Странно, я искал ответ на этот вопрос специально в контексте подключения решения для крошек в недавнем проекте!
Crescent Fresh 18.10.2016 15:25:45

В .Net Core у вас есть контекст 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
14.11.2018 01:15:39

Выполнение base.OnActionExecuted()вызова в последней строке метода решило для меня проблему «Модель является нулем».

(Это комментарий к ответу @Steven Lyons, но я публикую его как ответ, потому что не могу комментировать.)

3
5.02.2019 10:59:43