我的技能让我失望了,我知道我已经看到了这个代码,但我找不到它。
获取任意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???)
我正在尝试获取控制器的实例,就像路由系统一样,无论代码在哪里执行。我不清楚如何在这一点上将各个部分组合在一起。虽然我最终会发现它,但我想我可以通过在这里询问来节省时间;)
答案 0 :(得分:13)
嗯......我不知道这是否是最好的解决方案,因为它需要嘲笑,但也许这会有所帮助。一旦你知道要实例化的什么控制器,你就是在正确的轨道上并且控制器工厂部分很简单,所以问题是获取 RouteData 对象的最快方法是什么任意网址。
我知道怎么样的唯一方式,莫克:
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<HttpContextBase>();
var mockRequest = new Moq.Mock<HttpRequestBase>();
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);
我做了很多谷歌搜索,找不到与单元测试/模拟无关的内容。我不知道 是否可以快速轻松地做到这一点,但肯定想知道某人是否有更好的解决方案!
答案 1 :(得分:10)
好的,在用了几个星期之后,这就是我最终的结果。它的作用就像一个魅力,避免了对嘲讽的依赖,但对我来说仍然感觉很讨厌。
// 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的代码,如果有人能想出更好的东西,请不要犹豫,发布。
答案 2 :(得分:0)
显然你的意思是MVC网站上的任何后域URL字符串,对吧?所以,在http://yourdomain/something/thatSomeone/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