Server.TransferRequest
является совершенно ненужным в MVC . Это устаревшая функция, которая была необходима только в ASP.NET, потому что запрос пришел непосредственно на страницу и должен был быть способ перенести запрос на другую страницу. Современные версии ASP.NET (включая MVC) имеют инфраструктуру маршрутизации, которую можно настроить так, чтобы напрямую направлялся к нужному ресурсу. Нет смысла позволять запросу достигать контроллера только для передачи его другому контроллеру, когда вы можете просто сделать запрос направленным непосредственно на контроллер и выполнить желаемое действие.
Более того, поскольку вы отвечаете на оригинальный запрос , нет необходимости помещать что-либо в TempData
или другое хранилище только для того, чтобы направить запрос в нужное место. Вместо этого вы получите действие контроллера с исходным запросом без изменений. Вы также можете быть уверены, что Google одобрит этот подход, поскольку он полностью применяется на стороне сервера.
Хотя вы можете сделать совсем немного из IRouteConstraint
и IRouteHandler
, наиболее мощной точкой расширения для маршрутизации является подкласс RouteBase
. Этот класс может быть расширен для обеспечения как входящих маршрутов, так и генерации исходящих URL-адресов, что делает его универсальным средством для всего, что связано с URL-адресом и действием, которое выполняет URL-адрес.
Итак, чтобы следовать второму примеру, чтобы перейти от /
к /home/7
, вам просто нужен маршрут, который добавляет соответствующие значения маршрута.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Routes directy to `/home/7`
routes.MapRoute(
name: "Home7",
url: "",
defaults: new { controller = "Home", action = "Index", version = 7 }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Но если вернуться к исходному примеру, где у вас есть случайная страница, она более сложная, потому что параметры маршрута не могут изменяться во время выполнения. Таким образом, это можно сделать с помощью подкласса RouteBase
следующим образом.
public class RandomHomePageRoute : RouteBase
{
private Random random = new Random();
public override RouteData GetRouteData(HttpContextBase httpContext)
{
RouteData result = null;
// Only handle the home page route
if (httpContext.Request.Path == "/")
{
result = new RouteData(this, new MvcRouteHandler());
result.Values["controller"] = "Home";
result.Values["action"] = "Index";
result.Values["version"] = random.Next(10) + 1; // Picks a random number from 1 to 10
}
// If this isn't the home page route, this should return null
// which instructs routing to try the next route in the route table.
return result;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
var controller = Convert.ToString(values["controller"]);
var action = Convert.ToString(values["action"]);
if (controller.Equals("Home", StringComparison.OrdinalIgnoreCase) &&
action.Equals("Index", StringComparison.OrdinalIgnoreCase))
{
// Route to the Home page URL
return new VirtualPathData(this, "");
}
return null;
}
}
Который может быть зарегистрирован в маршрутизации как:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Routes to /home/{version} where version is randomly from 1-10
routes.Add(new RandomHomePageRoute());
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Обратите внимание, что в приведенном выше примере, возможно, имеет смысл также сохранить cookie-файл, записывающий версию домашней страницы, на которую вошел пользователь, поэтому, когда они возвращаются, они получают ту же версию домашней страницы.
Также обратите внимание, что с помощью этого подхода вы можете настроить маршрутизацию, чтобы учитывать параметры строки запроса (по умолчанию они полностью игнорируются) и соответственно направить на соответствующее действие контроллера.
Дополнительные примеры