从任意URL手动实例化Controller实例?

我的技能让我失望,我知道我已经看到了这个代码,但我找不到它。

获取任意URL的最快方法是什么,通过asp.net mvc路由系统运行它,并在另一端引用控制器实例?

例如,代码执行在一些任意控制器方法中。 我想做这样的事情:

... string myURL = "http://mysite/mycontroller/myaction/myparameters"; RouteData fakeRouteData = new RouteData(Route???, IRouteHandler???) RequestContext ctxt = new RequestContext(this.ControllerContext.HttpContext, fakeRouteData); ControllerFactory factory = ControllerBuilder.Current.GetControllerFactory(); Controller result = factory.CreateController(ctxt, controllername???) 

我正在尝试获取控制器的实例,就像路由系统一样,无论代码在哪里执行。 我不清楚在这一点上如何将各个部分组合在一起。 虽然我最终会发现它,但我想我可以通过询问来节省时间;)

嗯……我不知道这是否是最佳解决方案,因为它需要嘲笑,但也许这会有所帮助。 一旦你知道要实例化什么控制器,你就在正确的轨道上并且控制器工厂部分很简单,所以问题是从任意url获取RouteData对象的最快方法是什么。

Moq是我知道怎么样的唯一方式:

 string url = "~/Account/LogOn"; //trying to create Account controller in default MVC app RouteCollection rc = new RouteCollection(); MvcApplication.RegisterRoutes(rc); System.Web.Routing.RouteData rd = new RouteData(); var mockHttpContext = new Moq.Mock(); var mockRequest = new Moq.Mock(); mockHttpContext.Setup(x => x.Request).Returns(mockRequest.Object); mockRequest.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns(url); RouteData routeData = rc.GetRouteData(mockHttpContext.Object); string controllerName = routeData.Values["controller"].ToString(); IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory(); IController controller = factory.CreateController(this.ControllerContext.RequestContext, controllerName); 

我做了很多谷歌搜索,找不到与unit testing/模拟无关的内容。 我不知道是否有一个快速而简单的做法,但肯定想知道是否有人有更好的解决方案!

好的,在用了几个星期之后,这就是我最终的结果。 它的作用就像一个魅力,避免了对模拟的依赖,但对我来说仍然感觉很讨厌。

 // Get the application's route collection. UrlRoutingModule module = new UrlRoutingModule(); RouteCollection col = module.RouteCollection; // Fake a request to the supplied URL into the routing system string originalPath = this.HttpContext.Request.Path; this.HttpContext.RewritePath(urlToGetControllerFor); RouteData fakeRouteData = col.GetRouteData(this.HttpContext); // Get an instance of the controller that would handle this route string controllername = fakeRouteData.Values["controller"].ToString(); var ctxt = new RequestContext(this.ControllerContext.HttpContext, fakeRouteData); IController controller = ControllerBuilder.Current.GetControllerFactory() .CreateController(ctxt, controllername); // Reset our request path. this.HttpContext.RewritePath(originalPath.ToString()); 

到目前为止, RewritePath()调用绝对没有下游副作用。 感谢Kurt的代码,如果有人能想出更好的东西,请不要犹豫,发布。

显然你的意思是MVC网站上的任何后域URL字符串,对吧? 所以,在http:// yourdomain / something / thatSomeone / might / type / here中,你的意思是/ someone / might / type / here部分。

转到RegisterRoutes方法中的Global.asax.ca文件并添加如下内容:

 routes.MapRoute("foo", "foo/bar/in/a/jar", new { controller = "Home", action = "Index", id = "" }); 

现在当有人输入http:// yourdoamin / foo / bar / in / a / jar时,他们将被路由到Home / Index控制器操作。

希望有所帮助。

干杯,-jc