MVC: Redirect request to new function within Controller Initialize function
I want to be able to, within my Initialize function of my controller, decide WHICH function gets called. So for example if the route dictates that Controller:MyFunction
should get called, I want to override that from within the Initialize function and call MyFunction2
for example. How can I achieve this?
To get a better understanding of why I need this here is my current scenario.
I have a Customer Controller. Customers have lists of products. If a customer has a certain product I want to be able to add extra navigation elements and handle new functions.
So in pseudo code here is how I'm thinking it'd work
Receive request
Check if request matches any specialisation classes we have
If (match) then call SpecialClass::SpecificRequestFunction
This way I can have a standard customer controller that deals with all custom开发者_高级运维er things but if I need specialisation for those products I can keep on using the customer controller with all the benefits of re-using that code but can add specialities to it.
I hope this makes sense.
There are a few ways you can do this, you can:
1.Override the OnActionExecuting method of the controller:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (filterContext.ActionDescriptor.ActionName == "About")
filterContext.Result = RedirectToAction("Index");
}
2.Create an ActionFilter (essentially the same as above, and override the OnActionExecuting method there also.
3.Create a route constraint where you can do conditional checks before the request gets to the appropriate controller:
public class IsLocalRouteConstraint : IRouteConstraint
{
public bool Match(HttpContextBase context, Route route, string paramName, RouteValueDictionary dict, RouteDirection direction
{
return context.Request.IsLocal;
}
}
For your specified piece of work though, it might be good to abstract your navigational items out, e.g.
public interface INavigationalItem
{
string Name { get; }
string Controller { get; }
string Action { get;}
object Parameters { get; }
}
That way you could provide a IEnumerable<INavigationalItem>
which you build based on the current user state. You wouldn't have to specialise any additional controllers that way, you build the available navigational items dynamically instead.
If those functions are controller actions you can get the action that is going to be called from the routes:
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
string action = requestContext.RouteData.GetRequiredString("action");
}
but you cannot override it because the request has already been made to the first action. Also why calling this controller action in the first place when you know that you need another action?
精彩评论