博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Asp.Net Mvc Area二级域名
阅读量:4706 次
发布时间:2019-06-10

本文共 12560 字,大约阅读时间需要 41 分钟。

参考:

参考:

适当使用反编译工具查看 Route 的源码

主要类

DomainData.cs

namespace DomainMvcTest.Core{    public class DomainData    {        public string Protocol { get; set; }        public string HostName { get; set; }        public string Fragment { get; set; }    }}

DomainRoute.cs

using System.Collections.Generic;using System.Text.RegularExpressions;using System.Web;using System.Web.Mvc;using System.Web.Routing;namespace DomainMvcTest.Core{    public class DomainRoute : Route    {        private Regex domainRegex;        private Regex pathRegex;        public string Domain { get; set; }        public DomainRoute(string domain, string url, RouteValueDictionary defaults)            : base(url, defaults, new MvcRouteHandler())        {            Domain = domain;        }        public DomainRoute(string domain, string url, RouteValueDictionary defaults, IRouteHandler routeHandler)            : base(url, defaults, routeHandler)        {            Domain = domain;        }        public DomainRoute(string domain, string url, object defaults)            : base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())        {            Domain = domain;        }        public DomainRoute(string domain, string url, object defaults, IRouteHandler routeHandler)            : base(url, new RouteValueDictionary(defaults), routeHandler)        {            Domain = domain;        }        public override RouteData GetRouteData(HttpContextBase httpContext)        {            // 构造 regex            domainRegex = CreateRegex(Domain);            pathRegex = CreateRegex(Url);            // 请求信息            string requestDomain = httpContext.Request.Headers["host"];            if (!string.IsNullOrEmpty(requestDomain))            {                if (requestDomain.IndexOf(":") > 0)                {                    requestDomain = requestDomain.Substring(0, requestDomain.IndexOf(":"));                }            }            else            {                requestDomain = httpContext.Request.Url.Host;            }            string requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;            // 匹配域名和路由            Match domainMatch = domainRegex.Match(requestDomain);            Match pathMatch = pathRegex.Match(requestPath);            // 路由数据            RouteData data = null;            if (domainMatch.Success && pathMatch.Success)            {                data = new RouteData(this, RouteHandler);                // 添加默认选项                if (Defaults != null)                {                    foreach (KeyValuePair
item in Defaults) { data.Values[item.Key] = item.Value; if (item.Key.Equals("area") || item.Key.Equals("Namespaces")) { data.DataTokens[item.Key] = item.Value; } } } // 匹配域名 for (int i = 1; i < domainMatch.Groups.Count; i++) { Group group = domainMatch.Groups[i]; if (group.Success) { string key = domainRegex.GroupNameFromNumber(i); if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0)) { if (!string.IsNullOrEmpty(group.Value)) { data.Values[key] = group.Value; if (key.Equals("area")) { data.DataTokens[key] = group.Value; } } } } } // 匹配路径 for (int i = 1; i < pathMatch.Groups.Count; i++) { Group group = pathMatch.Groups[i]; if (group.Success) { string key = pathRegex.GroupNameFromNumber(i); if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0)) { if (!string.IsNullOrEmpty(group.Value)) { data.Values[key] = group.Value; if (key.Equals("area")) { data.DataTokens[key] = group.Value; } } } } } } return data; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { return base.GetVirtualPath(requestContext, RemoveDomainTokens(values)); } public DomainData GetDomainData(RequestContext requestContext, RouteValueDictionary values) { // 获得主机名 string hostname = Domain; foreach (KeyValuePair
pair in values) { if (pair.Key == "area" && string.IsNullOrEmpty(pair.Value.ToString())) { hostname = hostname.Replace("{
" + pair.Key + "}", "www"); } else { hostname = hostname.Replace("{
" + pair.Key + "}", pair.Value.ToString()); } } //如果域名的area还没有被替换,说明路由数据里没有area,恢复为顶级域名 if (hostname.Contains("{area}")) { hostname = hostname.Replace("{area}", "www"); } RemoveDomainTokens(values); // Return 域名数据 return new DomainData { Protocol = "http", HostName = hostname, Fragment = "" }; } private Regex CreateRegex(string source) { // 替换 source = source.Replace("/", @"\/?"); source = source.Replace(".", @"\.?"); source = source.Replace("-", @"\-?"); source = source.Replace("{
", @"(?<"); source = source.Replace("}", @">([a-zA-Z0-9_]*))"); return new Regex("^" + source + "$"); } private RouteValueDictionary RemoveDomainTokens(RouteValueDictionary values) { Regex tokenRegex = new Regex(@"({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?"); Match tokenMatch = tokenRegex.Match(Domain); for (int i = 0; i < tokenMatch.Groups.Count; i++) { Group group = tokenMatch.Groups[i]; if (group.Success) { string key = group.Value.Replace("{
", "").Replace("}", ""); if (values.ContainsKey(key)) values.Remove(key); } } return values; } }}

LinkExtensions.cs

using System.Collections.Generic;using System.Linq;using System.Web.Routing;using DomainMvcTest.Core;namespace System.Web.Mvc.Html{    public static class LinkExtensions    {        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, bool requireAbsoluteUrl)        {            return htmlHelper.ActionLink(linkText, actionName, null, new RouteValueDictionary(), new RouteValueDictionary(), requireAbsoluteUrl);        }        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, bool requireAbsoluteUrl)        {            return htmlHelper.ActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary(), requireAbsoluteUrl);        }        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, bool requireAbsoluteUrl)        {            return htmlHelper.ActionLink(linkText, actionName, controllerName, new RouteValueDictionary(), new RouteValueDictionary(), requireAbsoluteUrl);        }        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues, bool requireAbsoluteUrl)        {            return htmlHelper.ActionLink(linkText, actionName, null, routeValues, new RouteValueDictionary(), requireAbsoluteUrl);        }        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes, bool requireAbsoluteUrl)        {            return htmlHelper.ActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes), requireAbsoluteUrl);        }        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues, IDictionary
htmlAttributes, bool requireAbsoluteUrl) { return htmlHelper.ActionLink(linkText, actionName, null, routeValues, htmlAttributes, requireAbsoluteUrl); } public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes, bool requireAbsoluteUrl) { return htmlHelper.ActionLink(linkText, actionName, controllerName, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes), requireAbsoluteUrl); } public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary
htmlAttributes, bool requireAbsoluteUrl) { if (requireAbsoluteUrl) { HttpContextBase currentContext = new HttpContextWrapper(HttpContext.Current); RouteData routeData = RouteTable.Routes.GetRouteData(currentContext); routeData.Values["controller"] = controllerName; routeData.Values["action"] = actionName; //如果不需要变换area,则routeValues不传入area的值 if (routeValues.Keys.Contains("area")) { routeData.Values["area"] = routeValues["area"]; } DomainRoute domainRoute = routeData.Route as DomainRoute; if (domainRoute != null) { DomainData domainData = domainRoute.GetDomainData(new RequestContext(currentContext, routeData), routeData.Values); return htmlHelper.ActionLink(linkText, actionName, controllerName, domainData.Protocol, domainData.HostName, domainData.Fragment, routeData.Values, null); } } return htmlHelper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes); } }}

在 AreaRegistration 中注册路由

using System.Web.Mvc;using DomainMvcTest.Core;namespace DomainMvcTest.Areas.Haha{    public class HahaAreaRegistration : AreaRegistration     {        public override string AreaName         {            get             {                return "Haha";            }        }        public override void RegisterArea(AreaRegistrationContext context)         {            context.Routes.Add("hahaDomain", new DomainRoute(                "{area}.chenwei.com",                                     // Domain with parameters                "{controller}/{action}/{id}",                                        // URL with parameters                new { controller = "Home", action = "Index", id = "", Namespaces = new[] { "DomainMvcTest.Areas.Haha.Controllers" }}  // Parameter defaults            ));            //context.MapRoute(            //    "Haha_default",            //    "Haha/{controller}/{action}/{id}",            //    new { action = "Index", id = UrlParameter.Optional }            //);        }    }}

View 中生成Url连接

@Html.ActionLink("前往首页", "Index", "Home",new{area=""},null,true) 
@Html.ActionLink("前往Hehe", "Index", "Home", new { area = "Hehe" }, null, true)
@Html.ActionLink("前往Haha", "Index", "Home", new { area = "Haha" }, null, true)

转载于:https://www.cnblogs.com/ideacore/p/8026451.html

你可能感兴趣的文章
Xcode开发技巧之Code Snippets Library
查看>>
Linux平台上DPDK入门指南
查看>>
Java中的别名现象
查看>>
Nginx
查看>>
Interactive Extensions简介
查看>>
Integer’s Power HDU - 3208(容斥原理)
查看>>
牛客OI周赛7-提高组
查看>>
verilog 仿真时读取txt文件
查看>>
django 之admin后台管理
查看>>
android开发笔记
查看>>
第四节 Linux目录文件及文件基本操作
查看>>
uva 1025,城市的间谍
查看>>
Codeforces 385C 线性筛素数
查看>>
gluoncv faster_rcnn 参数修改
查看>>
poj 3252 Round Numbers(数学)
查看>>
课程管理系统教程
查看>>
U盘安装windows系统
查看>>
Item 36: Understand How to Use PLINQ for I/O Bound Operations(Effective C#)
查看>>
Proxy(Chapter 22 of Pro Objective-C Design Patterns for iOS)
查看>>
读书笔记_代码大全_第16章_控制循环
查看>>