在ASP MVC3中,如何使用uri执行控制器和动作?

时间:2011-03-06 20:45:44

标签: asp.net asp.net-mvc asp.net-mvc-3 routing

在执行控制器操作时,我怎样才能获取一个Uri(不是请求的那个)并从控制器调用该操作,如果该Uri是被调用的那个?我不能简单地重定向到该操作,因为我需要它在同一请求上下文中发生。

3 个答案:

答案 0 :(得分:12)

假设您可以访问HttpContext(我想你在问的时候就这么做了),你可以:

var routeData = new RouteData();
// controller and action are compulsory
routeData.Values["action"] = "index";
routeData.Values["controller"] = "foo";
// some additional route parameter
routeData.Values["foo"] = "bar";
IController fooController = new FooController();
var rc = new RequestContext(new HttpContextWrapper(HttpContext), routeData);
fooController.Execute(rc);

我个人使用这种方法来处理应用程序中的错误。我把它放在Application_Error中,并为停留在初始HTTP请求的上下文中的自定义错误页面执行错误控制器。您还可以在routeData哈希中放置复杂对象,然后将这些复杂对象作为操作参数返回。我使用它来传递错误控制器操作发生的实际异常。


更新:

为了解析其路线数据令牌的URL,并考虑当前的路线:

var request = new HttpRequest(null, "http://foo.com/Home/Index", "id=1");
var response = new HttpResponse(new StringWriter());
var httpContext = new HttpContext(request, response);
var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
var values = routeData.Values;
var action = values["action"];
var controller = values["controller"];

答案 1 :(得分:2)

对于正确答案,我更喜欢做这样的事情让MVC处理创建控制器而不是创建自己。

var routeData = new RouteData();
// controller and action are compulsory
routeData.Values["action"] = "index";
routeData.Values["controller"] = "foo";
IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
var requestContext = new RequestContext(new HttpContextWrapper(yourHttpContextObject), routeData);
var controller = factory.CreateController(requestContext, "FooController");
try
{
   controller.Execute(requestContext);
}
finally
{
   factory.ReleaseController(controller);
}

这可以确保您的Foo控制器获得与其他控制器相同的行为。

答案 2 :(得分:1)

你有什么理由不能将你正在调用的代码推送到独立于控制器的类中吗?交叉呼叫控制器对我来说听起来有点像WTF。