MVC3 action filter attribute with execution of multiple action results
I would like to know if its possible to execute few actionresults as a result of an action filter.
filterContext.Result=execution of few actionresults
My problem is that i have 开发者_开发百科to render the view of my action depending on some user credentials or one view of my action + one RenderPartial into this view.
That should not be done in filter, that kind of decisions should be done in controller, and rendering should be done in view. Injecting partial results in already generated html would be hard and difficult to maintain. Make a sample ViewModel
public class MyViewModel
{
Model SomeBaseModel; //whatever model is needed for base information
bool ShouldRenderPartial; //this point is important
}
In the controller, set shouldRenderPartial
true or false depending on credentials. and In the view (assuming you use razor syntax)
@if(Model.ShouldRenderPartial){
@{Html.RenderPartial("PartialViewName")}
}
You can set the filterContext so that it navigates to another action/view i.e.
private static void SetRedirectToLoginPageForContext(AuthorizationContext filterContext)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
{
{ "controller", "Login" },
{ "action", "Index" }
});
}
public class UserAuthenticatedAction : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
SetRedirectToLoginPageForContext(filterContext);
return;
}
}
In the above example, I'm setting the filter context so that, upon retuning, the user will be navigated to the Login/Index view.
Have a play around with this code, it should be similar for ActionFilters/GlobalFilters.
The solution was more easy that i expected:
First create a multiple action result class that is a wrapper of ActionResult that contains an IEnumerable with ActionResults
/// <summary>
/// this class contains a batch of ActionResult to execute
/// </summary>
public class PortalMultipleActionResult : ActionResult
{
/// <summary>
/// Builds a new instance of PortalMultipleActionResult
/// </summary>
/// <param name="results"></param>
public PortalMultipleActionResult(IEnumerable<ActionResult> results)
{
Results = results;
}
/// <summary>
/// Builds a new instance of PortalMultipleActionResult
/// </summary>
/// <param name="actions"></param>
public PortalMultipleActionResult(IEnumerable<Action> actions)
{
Results = actions.Select(x => new PortalActionDelegateResult(x));
}
/// <summary>
/// Batch execution of all the results
/// </summary>
/// <param name="context"></param>
public override void ExecuteResult(ControllerContext context)
{
foreach (var res in Results)
{
res.ExecuteResult(context);
}
}
/// <summary>
/// Action results collection
/// </summary>
private IEnumerable<ActionResult> Results
{
get;
set;
}
}
Second you can create a Filter in order to return set filterContext.Result to one instance of this PortalMultipleActionResult.
Finally just add the filter to your action method of the controller.
精彩评论