分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

asp.net ?MVC把Areas区域绑定成二级域名

发布时间:2023-09-06 02:20责任编辑:傅花花关键词:MVC

先分析需求

在MVC项目中,我们如果有两个Areas。比如Test和DEMO。我们的访问地址应该是

http://localhost:8098/test

http://localhost:8098/demo

如果我们绑定域名后想实现这样访问

http://test.abc.com:8098/

http://demo.abc.com:8098/     

 这个问题的相关解决办法倒是不少,比如http://www.cnblogs.com/jobily/archive/2011/10/09/2204800.html。可惜都是破坏了原来项目的结构,对于已经上线的项目不太适用。

本文的解决办法实在不破坏原来的结构之上,在原来的Areas里面重新绑定新的路由规则,重写基类路由 RouteBase的GetRouteData方法达到绑定二级域名,访问Areas的方法。

前期准备工作你需要先修改本地host文件,绑定一些二级域名。比如 

127.0.0.1 demo.abc.com

127.0.0.1 test.abc.com

首先新建 AreaDomainRegistrationContext类。

public class AreaDomainRegistrationContext ???{ ???????/// <summary> ???????/// ???????/// </summary> ???????/// <param name="_domainName">子域名 如:www.xxx.com 可以传 abc</param> ???????public AreaDomainRegistrationContext(AreaRegistrationContext _context, string _domainName) ???????{ ???????????domainName = _domainName; context = _context; ???????} ???????private string domainName; private AreaRegistrationContext context; ???????private RouteCollection Routes ???????{ ???????????get ???????????{ ???????????????if (!DomainRouteTable.DomainRoutes.ContainsKey(domainName)) ???????????????{ ???????????????????DomainRouteTable.DomainRoutes[domainName] = new RouteCollection(); ???????????????} ???????????????return DomainRouteTable.DomainRoutes[domainName]; ???????????} ???????} ???????public Route MapRoute(string name, string url, object defaults, object constraints = null, string[] namespaces = null) ???????{ ???????????if (namespaces == null && context.Namespaces != null) ???????????{ ???????????????namespaces = context.Namespaces.ToArray(); ???????????} ???????????Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces); ???????????route.DataTokens["area"] = context.AreaName; ???????????route.DataTokens["UseNamespaceFallback"] = false; ???????????route.DataTokens["SubDomain"] = domainName; ???????????return route; ???????} ???}
View Code

 DomainRouteTable类里面有一个静态属性DomainRoutes。主要存储域名和路由之间的存储关联。

 public class DomainRouteTable ???{ ???????private static Dictionary<string, RouteCollection> _instance = new Dictionary<string, RouteCollection>(); ???????public static Dictionary<string, RouteCollection> DomainRoutes ???????{ ???????????get ???????????{ ???????????????return _instance; ???????????} ???????} ???}
View Code

下面就是重写RouteBase的类了

 public class DomainRoute : RouteBase ???{ ???????public ResolveDomainName resolveDomainName = DependencyResolver.Current.GetService<ResolveDomainName>(); ???????public RouteData d = new RouteData(null, new StopRoutingHandler()); ???????public override RouteData GetRouteData(HttpContextBase httpContext) ???????{ ???????????string domainName = resolveDomainName.Resolve(httpContext); ???????????//该主机头没有配置,返回 null 继续查找路由 ???????????if (domainName == null) return null; ???????????if (!DomainRouteTable.DomainRoutes.ContainsKey(domainName)) return d; ???????????var rs = DomainRouteTable.DomainRoutes[domainName]; ???????????RouteData routeData = rs.GetRouteData(httpContext); ???????????if (routeData == null) return d; ???????????return routeData; ???????} ???????public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) ???????{ ???????????string domainName = resolveDomainName.Resolve(requestContext.HttpContext); ???????????if (domainName == null) return null; ???????????if (!DomainRouteTable.DomainRoutes.ContainsKey(domainName)) return null; ???????????var rs = DomainRouteTable.DomainRoutes[domainName]; ???????????VirtualPathData vpd = rs.GetVirtualPathForArea(requestContext, values); ???????????return vpd; ???????} ???}
View Code

ResolveDomainName主要映射Areas和域名之间的关系,可以根据Areas查找到域名。

 public class ResolveDomainName ???{ ???????public static Dictionary<string, string> DomainMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); ???????public string Resolve(HttpContextBase httpContext) ???????{ ???????????string key = httpContext.Request.Headers["host"]; ???????????string value; ???????????if (DomainMap.TryGetValue(key, out value)) { return value; } ???????????else return null; ???????} ???}
View Code

接下来在Global文件的里面的Application_Start方法里面的第一行加入一下代码

RouteTable.Routes.Add(new DomainRoute());
???????????ResolveDomainName.DomainMap.Add("demo.abc.com:8098", "demo1");

ResolveDomainName.DomainMap.Add("test.abc.com:8098", "Test");

这样就可以绑定多个域名,后面的demo1和Test可以不和areas的名称相等,这里这是一个key而已。

接着在Areas区域里面绑定路由的地方加入一下代码

 var context2 = new AreaDomainRegistrationContext(context, "Test"); ???????????context2.MapRoute( ???????????????name: "Test_default", ???????????????url: "{controller}/{action}", ???????????????defaults: new { controller = "Home", action = "index" }, ??????????????namespaces: new string[] { "WebApplication1.Areas.Test.Controllers" });
View Code

代码看起来是这样的,这样并不影响之前的访问,还是可以通过areas的方式访问的

同理demo区域也添加代码。

接着编译我们的项目,就可以用demo.abc.com:8098来访问了,是不是很简单。

访问后的效果

本文参考文章地址

https://www.cnblogs.com/hitearth/p/6848788.html

asp.net ?MVC把Areas区域绑定成二级域名

原文地址:https://www.cnblogs.com/Playfunny/p/9875342.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved