在.Net MVC中,如何从Action之外的URL Routing中访问变量?

时间:2009-02-17 15:02:20

标签: c# asp.net-mvc

我正在构建一个其他控制器可以继承的控制器(跨站点提供基本功能而不重复代码):

public abstract class ApplicationController : Controller
{
    protected ApplicationController()
    {
       //site logic goes here
       //what is the value of agentID from the Action below??
    }
}

public class AgentController : ApplicationController
{
    public ActionResult Index(string agentID)
    {
        return View();
    }
}

适用于整个站点的逻辑将进入ApplicationController类的构造函数。

问题在于构造函数我需要从Action访问参数中的值,在这种情况下是agentID(在整个站点中它将是相同的)。有没有办法在中读取该值?

3 个答案:

答案 0 :(得分:1)

在构造函数之后发生操作。该值在构造函数中不存在(尚未绑定)。路径数据可能在构造函数中已知,但动作数据绑定肯定不会发生。在调用操作之前,无法确定地获取此值。

可以通过以下方式在控制器内访问路径数据:

ControllerContext.RouteData.Values

但是,假设agentID只能绑定到路由数据是不正确的。实际上,它可能来自服务器变量,表单字段,查询字符串参数等。我的建议是在需要的地方明确地传递它。如果不出意外,它会使您的单元测试变得更好。

答案 1 :(得分:1)

我想出了怎么做......非常类似于Craig Stuntz的答案,但区别在于你如何到达RouteData。

使用ControllerContext.RouteData.Values在这种方式使用的常规方法中不起作用(它来自原始控制器,但不是来自我构建的基本控制器),但我确实通过重写OnActionExecuting方法来获取RouteData :

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string agentID = filterContext.RouteData.Values["agentID"].ToString();
        OtherMethodCall(agentID);
    }

答案 2 :(得分:0)

但是,您需要覆盖ControllerFactory。在global.asax.cs的RegisterRoutes方法中,添加以下行:

public static void RegisterRoutes(RouteCollection routes) {
    // Route code goes here
    ControllerBuilder.Current.SetControllerFactory(typeof(MyControllerFactory));
}

然后定义您的MyControllerFactory

public class MyControllerFactory : DefaultControllerFactory {
    public override IController CreateController(RequestContext requestContext, string controllerName) {
        // poke around the requestContext object here
        return base.CreateController(requestContext, controllerName);
    }
}

requestContext对象包含其中的所有路径数据和值。您可以使用它将任何您想要的内容传递给控制器​​的构造函数。

编辑添加这是大多数流行的依赖注入者(例如,StructureMap)的工作原理。