我们正在将遗留应用程序迁移到.NET MVC,并且必须保持旧URL的向后兼容性。考虑一个论坛应用程序,其中URL看起来像这样
http://example.com/forums?page=ForumsList - shows a list of all forums
http://example.com/forums?page=Threads&forumId=1 - shows list of threads in forum 1
http://example.com/forums?page=Posts&forumId=1&threadId=1 - shows posts in forum 1, thread 1.
我希望将这些相同的网址映射到我的控制器中的操作,即
public ActionResult ForumsList(){}
public ActionResult Threads(string forumId){}
public ActionResult Posts(string forumId, string threadId){}
不重复我们遗留系统中的维护噩梦
public ActionResult Index(string page){
if (page == "Forums"){
return Forums();
}
else if (page == "Threads){
return Threads(Request.Params["forumId"]);
}
else if (page == "Posts"){
return Posts(Request.Params["forumId"], Request.Params["threadId"]);
}
// oh, there's more. a lot more.
}
我在自定义路由上找到的所有文档似乎都表明它只能解析URL的路径部分,而不是params。我尝试了以下,但无济于事:
routes.MapRoute(
name: "TestRoutes",
url: "{controller}/?page={action}",
defaults: new {controller = "Forums", action = "ForumsList"});
我能做的其他事情吗?
答案 0 :(得分:1)
实际上,你不需要做任何特别的事情。默认情况下,modelbinder将尝试将查询字符串中的任何内容作为参数附加到action方法。您只需使用一个操作来处理/代理所有请求:
public class ForumsController : Controller
{
public ActionResult Index(string page, int? forumId, int? threadId)
{
...
}
}
只有默认路线:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
工作得很好。
网址的主要部分/forums
将匹配ForumsController
,并且将使用Index
的默认操作,因为它未在网址中指定。 id
参数是可选的。然后,将为操作的同名参数设置查询字符串中的每个项目。 forumId
和threadId
参数需要为可为空的整数,以便只传递page
参数,例如您的/forums?page=ForumsList
网址。
虽然您可以简单地将应用程序设置为以这种方式工作,但我实际上建议将此特定操作保留为交换所。首先,我要创建自定义路线,因此您不必将Index
行动用于此:
routes.MapRoute(
name: "OldForums",
url: "forums",
defaults: new { controller = "OldForums", action = "RedirectToNewURLs" }
);
然后:
public class OldForumsController : Controller
{
public ActionResult RedirectToNewURLs(string page, int? forumId, int? threadId)
{
if (page == "ForumList")
{
return RedirectToActionPermanent("Index", "Forums");
}
if (page == "Threads")
{
return RedirectToActionPermanent("Threads", "Forums", { id = forumId });
}
// etc
}
}
这些重定向会指向您的新好论坛网址,例如/forums/{id}/threads
。因此,如果用户输入旧网址,他们只会被重定向到新版本,并且所有新用户都会从一开始就被发送到好网址。
修改强>
实际上,我忘了指出这种方法的一个复杂因素是你实际上不能将URL /forums
用于你的实际论坛索引。你可以使用类似/forums/all
之类的东西来区分或只是做一些像单调化的东西,即forum
。所有其他路由都可以使用forums
前缀正常工作,因为只有该字符串本身才会与自定义路由匹配。例如,像forums/1
这样的东西会落到默认路线上。