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);
}
}
