mvc Routing特性优化

在mvc中,Url地址是利用routing特性来支持,但是这个Routing有个问题,多个不同的地址和指向同一个action方法,

例如:

        http://test.com (默认)
        http://test.com/ (斜杠结尾)
        http://test.com/Home (带有Controller)
        http://test.com/Home/Action (带有Controller和Action)
        http://test.com/home/Action (不同的情况)

解决方法:通过使用注册全局的filter

先定义一个filter

 public class RemoveDuplicateContentAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var routes = RouteTable.Routes;
            var requestContext = filterContext.RequestContext;
            var routeData = requestContext.RouteData;
            var dataTokens = routeData.DataTokens;
            if (dataTokens["area"] == null)
                dataTokens.Add("area", "");
            var vpd = routes.GetVirtualPathForArea(requestContext, routeData.Values);
            if (vpd != null)
            {
                var virtualPath = vpd.VirtualPath.ToLower();
                var request = requestContext.HttpContext.Request;
                if (virtualPath != request.Path)
                {
                    filterContext.Result = new RedirectResult(virtualPath + request.Url.Query, true);
                }
            }
            base.OnActionExecuting(filterContext);
        }
    }

然后注册这个filter:

   public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            //整个程序所有控制器都使用HandlerError来处理错误
            //不过它只处理500系列错误,404类型需要单独处理
            filters.Add(new HandleErrorAttribute());
            filters.Add(new RemoveDuplicateContentAttribute());
        }

 

总结:
首先获取当前的RequestContext和RouteData,然后判断如果当前没有使用Area的话就为DataToken添加一个空值,这个非常重要,否则,后面再使用Area特性的话就会出错

接着该filter通过RouteData获取虚拟path,然后toLower转成小写
然后和当前request的path进行比较,如果不一致就重定向到小写的虚拟path上,这样搜索引擎就能识别当多个请求其实都是对应虚拟的path的真实地址上,也就是唯一的action地址,
对于SEO:确保一个地址对应一个内容是非常重要的,

posted @ 2016-07-05 17:23  那就让我这样吧  阅读(443)  评论(0编辑  收藏  举报