ASP.NET MVC3的伪静态实现代码

时间:2022-09-17 19:32:52

现在开始研究第一步,如何定义自己的路由规则,达到伪静态的功能需求。

基本实现原理如下图:

 ASP.NET MVC3的伪静态实现代码

首先,关于命名空间。

路由的功能是为了让所有Asp.net网站开发都可以使用,所以dll并没有在MVC中,而是在System.Web中的System.web.Routing。

现在我们为了我们实际的需求,实现MVC3中的自定义路由功能(继承RouteBase,重写RouteData和VirtualPathData)。

下面的例子实现以下目的:输入一个youdomin.com/product/123.html,执行TestController中Index.
第一步:实现TestRoute类 
1 RouteData 每次访问URL都会从此入口 
通过httpContext.Request.AppRelativeCurrentExecutionFilePath 获取我们访问的url地址,根据地址进行分析:是不是符合我们的规则,符合我们规则我们就走特定的Controller和Action。代码如下: 

复制代码代码如下:


public class TestRoute:RouteBase 

private string[] urls; 
public TestRoute(params string[]targetUrls) { 
urls = targetUrls; 

public override RouteData GetRouteData(HttpContextBase httpContext) 

RouteData result = null; 
string requestedURL = 
httpContext.Request.AppRelativeCurrentExecutionFilePath+httpContext.Request.PathInfo; 
requestedURL = requestedURL.Substring(2).Trim('/'); 
if (requestedURL.Contains(urls.ToArray().GetValue(0).ToString())) 

result = new RouteData(this, new MvcRouteHandler()); 
result.Values.Add("controller", "Test"); 
result.Values.Add("action", "Index"); 
result.Values.Add("p", requestedURL); 

return result; 

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 

return null; 


上面例子中,我们根据判断Url中是否符合某个特定的值来特定执行特定Controller和特定Action,没有就返回null。 
第二步,在Global.aspx中注册我们自己的路与规则: 

复制代码代码如下:


public static void RegisterRoutes(RouteCollection routes) 

routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
routes.Add(new TestRoute("product")); 
routes.MapRoute( 
"Default", // Route name 
"{controller}/{action}/{id}", // URL with parameters 
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
); 

protected void Application_Start() 

AreaRegistration.RegisterAllAreas(); 
RegisterGlobalFilters(GlobalFilters.Filters); 
RegisterRoutes(RouteTable.Routes); 


注意上述代码红色部分,Application_Start() 中注册一个路由规则,RegisterRoutes(RouteTable.Routes)然后在RegisterRoutes方法中加入如下代码: 
routes.Add(new TestRoute("product")); 
注明:TestRoute 是上面我们自己定义的路由,实现RouteBase的类。 
第三步:新建第一步中测试用的Controller 

复制代码代码如下:


public class TestController:Controller 

public ActionResult Index(string p) 

ViewData["t"] =p; 
return View(""); 


第四步:新建一个视图 

复制代码代码如下:


@{ 
Layout = null; 

<!DOCTYPE html> 
<html> 
<head> 
<title></title> 
</head> 
<body> 
<div> 
<!--此处会显示你输入的URL地址--> 
@ViewData["t"].ToString() 
</div> 
</body> 
</html> 


第五步,直接输入URl测试 
比如:http://127.0.0.1/product/1.html 
后续补充: 
主要内容:如何让前台列表展示页显示以上5步中实现的伪静态URL? 
经过实际验证,发现RouteBase中VirtualPathData的实现就能解决以上问题。.net Route其实已经实现了这个双向解析的问题,通过输入URL,从RouteData进入,根据自己的路由规则进行解析到相对应的Controller和Action,然后在使用URL.Action的地方从VirtualPathData解析出符合路由规则的URL地址,具体代码如下: 

复制代码代码如下:


public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 

if (values["controller"].ToString().Contains("Test")) 

return new VirtualPathData(this, "product/" + values["p"] + ".html"); 

else 
return null; 


可以替换第一步中TestRoute类中的GetVirtualPath方法,查看实际效果。