Asp.net MVC-accès au modèle de vue à partir d'un filtre d'Action personnalisé
J'essaie d'accéder aux données du modèle transmises à la vue dans le filtre D'action OnActionExecuted. Est-ce que quelqu'un sait si c'est possible?
J'essaie de faire quelque chose comme ceci:
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
//get model data
//...
sitemap.SetCurrentNode(model.Name);
}
Un conseil?
4 réponses
Le modèle est à:
filterContext.Controller.ViewData.Model
Je ne sais pas pourquoi mais filterContext.Controller.ViewData.Model
est toujours null même lorsque la liaison du modèle est exécutée avant OnActionExecuted
. J'ai trouvé une solution en utilisant l'événement OnModelUpdated
pour définir cette propriété avant.
J'ai le classeur modèle:
public class CustomModelBinder: DefaultModelBinder
{
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
controllerContext.Controller.ViewData.Model = bindingContext.Model;
base.OnModelUpdated(controllerContext, bindingContext);
}
}
Après cela, vous devez définir le classeur par défaut sur votre nouveau classeur de modèle dans la section Application_Start()
dans Global.asax:
ModelBinders.Binders.DefaultBinder = new CustomModelBinder();
Enfin, vous pouvez accéder à votre Model
en ActionFilterAttribute
:
public class TraceLog : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
//filterContext.Controller.ViewData.Model now isn't null
base.OnActionExecuted(filterContext);
}
}
Sur. net Core, vous avez un IDictionary ActionArguments sur le contexte, avec tous les paramètres de votre méthode
Donc, si vous avez la méthode de contrôleur suivante
[HttpPost]
public void Post([FromBody]BaseRequest request)
{
}
Vous pouvez accéder au champ comme
public override void OnActionExecuting(ActionExecutingContext context)
{
var request = context.ActionArguments["request"] as BaseRequest;`
//do whatever,
}
Si vous obtenez null - comme alternative à la réponse de @Gustavo Clemente, vous pouvez essayer de remplacer OnActionExecuted
et de passer votre viewModel en vue de la manière suivante:
Action:
[Breadcrumb("Index")]
public ActionResult UnitIndex()
{
View(new Answers());
}
Attribut:
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);
}
}