C# MVC:将请求重定向到控制器初始化函数中的新函数

C# MVC:将请求重定向到控制器初始化函数中的新函数,c#,asp.net-mvc,C#,Asp.net Mvc,我希望能够在控制器的初始化函数中决定调用哪个函数。因此,例如,如果路由指示应该调用Controller:MyFunction,我想在Initialize函数中覆盖该路由,并调用MyFunction2。我怎样才能做到这一点 为了更好地理解我为什么需要这个,这里是我当前的场景 我有一个客户控制员。客户有产品清单。如果客户有某种产品,我希望能够添加额外的导航元素并处理新功能 所以在伪代码中,我认为它是如何工作的 Receive request Check if request matches any

我希望能够在控制器的初始化函数中决定调用哪个函数。因此,例如,如果路由指示应该调用
Controller:MyFunction
,我想在Initialize函数中覆盖该路由,并调用
MyFunction2
。我怎样才能做到这一点

为了更好地理解我为什么需要这个,这里是我当前的场景

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

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

Receive request
Check if request matches any specialisation classes we have
If (match) then call SpecialClass::SpecificRequestFunction
通过这种方式,我可以拥有一个标准的客户控制器来处理所有客户事务,但如果我需要这些产品的专业化,我可以继续使用客户控制器,并具有重复使用该代码的所有好处,但可以为其添加特殊功能


我希望这是有意义的。

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

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

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

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

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

但是您不能覆盖它,因为已经对第一个操作发出了请求。还有,当您知道需要另一个操作时,为什么要首先调用此控制器操作?

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

1.覆盖控制器的OnActionExecuting方法:

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

    if (filterContext.ActionDescriptor.ActionName == "About")
        filterContext.Result = RedirectToAction("Index");
}
public class IsLocalRouteConstraint :  IRouteConstraint
{
  public bool Match(HttpContextBase context, Route route,  string paramName, RouteValueDictionary dict, RouteDirection direction
  {
    return context.Request.IsLocal;
  }
}
2.创建一个ActionFilter(基本上与上面相同,并在那里重写OnActionExecuting方法)

3.创建路由约束,您可以在请求到达相应控制器之前执行条件检查:

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

    if (filterContext.ActionDescriptor.ActionName == "About")
        filterContext.Result = RedirectToAction("Index");
}
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
。这样您就不必专门配置任何其他控制器,而是动态构建可用的导航项。

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

1.覆盖控制器的OnActionExecuting方法:

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

    if (filterContext.ActionDescriptor.ActionName == "About")
        filterContext.Result = RedirectToAction("Index");
}
public class IsLocalRouteConstraint :  IRouteConstraint
{
  public bool Match(HttpContextBase context, Route route,  string paramName, RouteValueDictionary dict, RouteDirection direction
  {
    return context.Request.IsLocal;
  }
}
2.创建一个ActionFilter(基本上与上面相同,并在那里重写OnActionExecuting方法)

3.创建路由约束,您可以在请求到达相应控制器之前执行条件检查:

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

    if (filterContext.ActionDescriptor.ActionName == "About")
        filterContext.Result = RedirectToAction("Index");
}
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
。这样您就不必专门设计任何其他控制器,而是动态构建可用的导航项。

谢谢Darin-我更新了我的问题,以便更好地解释我在Hanks Darin-I upd之后的想法我回答我的问题是为了更好地解释我的想法啊,这看起来很完美!!!一个问题:
RedirectToAction
是否真的重定向了用户,还是仅仅调用了一个新的操作?我希望URL在所有这些过程中保持完全相同。ThanksRedirectToAction实际上重定向了URL,而不是保持URL不变ct-您如何解决此问题?您只能通过执行选项3(在请求到达控制器之前拦截请求)来解决此问题,或从原始路由的操作中执行操作。啊,这看起来太完美了!!!一个问题:
RedirectToAction
是否确实重定向了用户,还是只是调用了一个新操作?我希望URL在所有这些过程中保持完全相同。ThanksRedirectToAction实际上重定向了URL,而不是保留URL完好无损-如何绕过此问题?您只能通过执行选项3(在请求到达控制器之前拦截请求)或在原始路由的操作中执行操作来绕过此问题。