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.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;
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;
}
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))
{
return new VirtualPathData(this, "");
}
return null;
}
}
这可以像以下这样在路由中注册:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(new RandomHomePageRoute());
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
在上面的例子中,也许将记录用户进入的首页版本的cookie存储起来会有意义,这样当他们返回时就可以收到相同的首页版本。
还要注意,使用这种方法,您可以自定义路由以考虑查询字符串参数(默认情况下完全忽略它们),并相应地路由到适当的控制器操作。
其他示例:
ServerTransferAction
到底是什么?那是一个真实存在的东西吗?(我找不到任何相关信息...顺便感谢你的问题,下面的答案非常好) - jleachif
语句确实是一个太诱人的解决方案。 - Simon_WeaverRouteBase
来放置你的if
语句,而不是为了从一个控制器跳到另一个控制器而弯曲一切,那么这有什么问题吗? - NightOwl888