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来记录用户进入的主页版本,因此当他们返回时,他们会收到相同的主页版本。
还要注意,使用这种方法,您可以自定义路由以将查询字符串参数考虑在内(默认情况下它会完全忽略它们),并相应地路由到适当的控制器操作。
其他例子
ServerTransferAction
您要复制的确切是什么?那是真的吗?(找不到任何信息...感谢您的问题,顺便说一句,以下答案非常棒)