2009-05-16 4 views
33

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

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

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

    sitemap.SetCurrentNode(model.Name); 
} 

Любые советы?

ответ

51

Модель по адресу:

filterContext.Controller.ViewData.Model 
+8

Это всегда null :( – Korayem

+4

@Korayem - зависит от того, как рано вы пытаетесь получить к нему доступ. Если вы получите его после выполнения действия контроллера, он должен быть экземпляром viewmodel. – JBeckton

+8

Это значение null для меня во всех методах (OnActionExecuting, OnActionExecuted, OnResultExecuting, OnResultExecuted) –

18

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

Если вы получаете нуль - как альтернатива ответ @Gustavo Клементе вы можете попробовать перекрывая 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

+0

Где находится этот код? Странно, что я искал ответ на этот вопрос конкретно в контексте подключения решения для панировки в недавнем проекте! –

+0

@CrescentFresh Я сделал это для одной из компаний .... –

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, 
    }