В ASP MVC3, как можно выполнить контроллер и действие, используя URI? - PullRequest
4 голосов
/ 06 марта 2011

Как я могу при выполнении действия контроллера взять Uri (не тот, который запрошен) и вызвать действие от контроллера, который был бы выполнен, если бы Uri был тем, который был вызван? Я не могу просто перенаправить на это действие, так как мне нужно, чтобы оно происходило в том же контексте запроса.

Ответы [ 3 ]

12 голосов
/ 06 марта 2011

Предполагая, что у вас есть доступ к 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, и вы получите эти сложные объекты обратно в качестве параметров действия. Я использую это для передачи фактического исключения, которое произошло, к действию контроллера ошибок.


UPDATE:

Чтобы проанализировать 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"];
2 голосов
/ 01 июня 2015

Для правильного ответа я бы предпочел сделать что-то подобное, чтобы позволить 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 работает так же, как и другие контроллеры.

1 голос
/ 07 марта 2011

По какой причине вы не можете вставить код, который вы вызываете, в независимый от контроллера класс?Для меня кросс-вызов контроллеров звучит как что-то вроде WTF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...