MVC:在Controller Initialize函数中将请求重定向到新函数

时间:2010-12-10 09:03:59

标签: c# asp.net-mvc

我希望能够在我的控制器的Initialize函数中决定调用WHICH函数。因此,例如,如果路由规定应该调用Controller:MyFunction,我想在Initialize函数中覆盖它,例如调用MyFunction2。我怎样才能做到这一点?

为了更好地理解我为什么需要这个,这是我目前的情况。

我有一位客户控制员。客户拥有产品清单。如果客户有某种产品,我希望能够添加额外的导航元素并处理新功能。

所以在伪代码中,我认为它是如何工作的

Receive request
Check if request matches any specialisation classes we have
If (match) then call SpecialClass::SpecificRequestFunction

通过这种方式,我可以拥有一个标准的客户控制器来处理所有客户的事情,但如果我需要对这些产品进行专业化,我可以继续使用客户控制器,并具有重用该代码的所有好处,但可以为其添加专业

我希望这是有道理的。

2 个答案:

答案 0 :(得分:3)

有几种方法可以做到这一点,你可以:

1.Override控制器的OnActionExecuting方法:

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    base.OnActionExecuting(filterContext);

    if (filterContext.ActionDescriptor.ActionName == "About")
        filterContext.Result = RedirectToAction("Index");
}

2.创建一个ActionFilter(基本上与上面相同,并在那里覆盖OnActionExecuting方法。

3.创建一个路由约束,您可以在请求到达适当的控制器之前进行条件检查:

public class IsLocalRouteConstraint :  IRouteConstraint
{
  public bool Match(HttpContextBase context, Route route,  string paramName, RouteValueDictionary dict, RouteDirection direction
  {
    return context.Request.IsLocal;
  }
}

对于您指定的工作,最好将您的导航项目抽象出去,例如

public interface INavigationalItem
{
  string Name { get; }
  string Controller { get; }
  string Action { get;}
  object Parameters { get; }
}

通过这种方式,您可以提供基于当前用户状态构建的IEnumerable<INavigationalItem>。您不必专门使用任何其他控制器,而是动态地构建可用的导航项。

答案 1 :(得分:2)

如果这些函数是控制器操作,您可以从路径中获取将要调用的操作:

protected override void Initialize(RequestContext requestContext)
{
    base.Initialize(requestContext);
    string action = requestContext.RouteData.GetRequiredString("action");
}

但是您无法覆盖它,因为已经对第一个操作发出了请求。另外,为什么当你知道需要另一个动作时,首先调用这个控制器动作?