.Net Core 二级域名绑定到指定的控制器
在说二级域名绑定之前,先说一下.net core中的区域,关于区域这一块儿在很久之前的博客中,已经提过,详见《03-dotnet core创建区域[Areas]及后台搭建》,在这篇博客中,创建区域的时候,都是手动创建的,手动创建区域Areas文件夹,手动添加M-V-C等文件目录,由于在最早的VS2017版本中,直接右键添加区域的选项居然没了,然而在后来的VS版本更新中,这一功能又恢复了,也不知微软是出于什么考虑。区域的功能,就不用多说了,至于如何创建如何使用,也不多说,这些都是在MVC4的功能了。今天主要说一下关于二级域名如何绑定到指定的控制器。
二级域名也无需多说了吧,比如我们进入百度,我们直接输入www.baidu.com或者输入baidu.com(重定向到www.baidu.com),会直接进入百度的首页,而如果我们输入的是,news.baidu.com,则直接进入百度新闻,我们称news.baidu.com为二级域名,那输入不同的二级域名会进入不同的主页面,那这是如何实现的呢。关于二级域名绑定其实使用一些代理服务器如nginx等,都可以实现域名绑定,这些我们都不讨论,这里我们只讨论在.net core 项目中如何配置。
这里借助于一篇博客,园子中早已经有人对路由作了扩展,使其可以自定义域名绑定控制器,原文地址:《asp.net core mvc中如何把二级域名绑定到特定的控制器上》 。下面附上代码:二级域名逻辑判断,基于RouteBase扩展
- <span style="font-size:14px;">public class SubDomainRouter : RouteBase
- {
- private readonly IRouter _target;
- private readonly string _subDomain;
- public SubDomainRouter(
- IRouter target,
- string subDomain,//当前路由规则绑定的二级域名
- string routeTemplate,
- RouteValueDictionary defaults,
- RouteValueDictionary constrains,
- IInlineConstraintResolver inlineConstraintResolver)
- : base(routeTemplate,
- subDomain,
- inlineConstraintResolver,
- defaults,
- constrains,
- new RouteValueDictionary(null))
- {
- if (target == null)
- {
- throw new ArgumentNullException(nameof(target));
- }
- if (subDomain == null)
- {
- throw new ArgumentNullException(nameof(subDomain));
- }
- _subDomain = subDomain;
- _target = target;
- }
- public override Task RouteAsync(RouteContext context)
- {
- string domain = context.HttpContext.Request.Host.Host;//获取当前请求域名,然后跟_subDomain比较,如果不想等,直接忽略
- if (string.IsNullOrEmpty(domain) || string.Compare(_subDomain, domain) != 0)
- {
- return Task.CompletedTask;
- }
- //如果域名匹配,再去验证访问路径是否匹配
- return base.RouteAsync(context);
- }
- protected override Task OnRouteMatched(RouteContext context)
- {
- context.RouteData.Routers.Add(_target);
- return _target.RouteAsync(context);
- }
- protected override VirtualPathData OnVirtualPathGenerated(VirtualPathContext context)
- {
- return _target.GetVirtualPath(context);
- }
- }</span>
如何把域名绑定到指定的控制器上,代码如下:
- <span style="font-size:14px;">public static class RouteBuilderExtensions
- {
- public static IRouteBuilder MapDomainRoute(
- this IRouteBuilder routeBuilder,string domain,string area,string controller)
- {
- if(string.IsNullOrEmpty(area)||string.IsNullOrEmpty(controller))
- {
- throw new ArgumentNullException("area or controller can not be null");
- }
- var inlineConstraintResolver = routeBuilder
- .ServiceProvider
- .GetRequiredService<IInlineConstraintResolver>();
- string template = "";
- RouteValueDictionary defaults = new RouteValueDictionary();
- RouteValueDictionary constrains = new RouteValueDictionary();
- constrains.Add("area", area);
- defaults.Add("area", area);
- constrains.Add("controller", controller);
- defaults.Add("controller", string.IsNullOrEmpty(controller) ? "home" : controller);
- defaults.Add("action", "index");
- template += "{action}/{id?}";//路径规则中不再包含控制器信息,但是上面通过constrains限定了查找时所要求的控制器名称
- routeBuilder.Routes.Add(new SubDomainRouter(routeBuilder.DefaultHandler, domain, template, defaults, constrains, inlineConstraintResolver));
- return routeBuilder;
- }
- }</span>
使用方法:
- <span style="font-size:14px;">routes.MapDomainRoute("xxx.domain.com","areaname","controllername");</span>
以上代码为原博客中的代码,使用起来也很方便,只需要传值域名,区域名,控制器名,就可以实现我们想要的结果。下面我对以上代码稍作了修改,通过配置文件配置域名和控制器的绑定。新建一个关于域名、区域、控制器名的Model:
- <span style="font-size:14px;">/// 域名信息实体类
- /// <summary>
- /// 域名信息实体类
- /// </summary>
- public class SubDomain
- {
- /// 域名
- /// <summary>
- /// 域名
- /// </summary>
- public string Domain { get; set; }
- /// 区域名
- /// <summary>
- /// 区域名
- /// </summary>
- public string AreaName { get; set; }
- /// 控制器名
- /// <summary>
- /// 控制器名
- /// </summary>
- public string Controller { get; set; }
- }</span>
另外在MapDomainRoute扩展方法中,去掉了对区域的判断, 这样也可以配置非区域的控制器了,代码如下:
- <span style="font-size:14px;">public static IRouteBuilder MapDomainRoute(
- this IRouteBuilder routeBuilder, string domain, string area, string controller)
- {
- try
- {
- <span style="background-color:rgb(255,204,0);">if (string.IsNullOrEmpty(domain))
- {
- throw new ArgumentNullException("domain can not be null");
- }
- //string.IsNullOrEmpty(area) || //去掉该判断,不限制仅限区域使用配置
- if (string.IsNullOrEmpty(controller))
- {
- throw new ArgumentNullException("controller can not be null");
- }</span>
- var inlineConstraintResolver = routeBuilder
- .ServiceProvider
- .GetRequiredService<IInlineConstraintResolver>();
- string template = "";
- RouteValueDictionary defaults = new RouteValueDictionary();
- RouteValueDictionary constrains = new RouteValueDictionary();
- constrains.Add("area", area);
- defaults.Add("area", area);
- constrains.Add("controller", controller);
- defaults.Add("controller", string.IsNullOrEmpty(controller) ? "Home" : controller);
- defaults.Add("action", "index");
- template += "{action}/{id?}";//路径规则中不再包含控制器信息,但是上面通过constrains限定了查找时所要求的控制器名称
- routeBuilder.Routes.Add(new SubDomainRouter(routeBuilder.DefaultHandler, domain, template, defaults, constrains, inlineConstraintResolver));
- return routeBuilder;
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }</span>
同时也添加了一个对该方法的重载:
- <span style="font-size:14px;">public static void MapDomainRoute(this IRouteBuilder routeBuilder, List<SubDomain> listDomains)
- {
- try
- {
- if (listDomains == null || listDomains.Count <= 0)
- {
- return;
- }
- foreach (SubDomain domain in listDomains)
- {
- MapDomainRoute(routeBuilder, domain.Domain, domain.AreaName, domain.Controller);
- }
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }</span>
将域名路由信息配置到appsetting.json文件中,例如:
当然在.net core中可以直接从IConfiguration对象中可以直接获取到配置文件下的信息,但我也没找到可以直接序列化我为要的标准的Json格式,就使用了直接读取文件的方式,借助Json.Net,又反序列化成我要的实体信息List<SubDomain>,代码如下:
- <span style="font-size:14px;">//获取域名路由配置规则信息
- var jsonDomain = JObject.Parse(File.ReadAllText("appsettings.json"))["SubDomains"];
- if (jsonDomain != null)
- {
- var infos = JsonConvert.DeserializeObject<List<SubDomain>>(jsonDomain.ToString());
- routes.MapDomainRoute(infos);
- }</span>
这样也就可以直接通过配置文件去修改配置了,效果展示:
以上就实现了我们想要的结果。后面内容应该会涉及微服务内容了,我会结合微软的示例项目eShop,应用到自己的项目中。另外,微软官方出了一本电子书《.NET微服务:容器化.NET应用架构指南》,大家可以免费下载,下载地址:https://aka.ms/microservicesebook
原文中涉及到的博客地址(尊重原创):http://www.cnblogs.com/dxp909/p/6994354.html
扫描二维码关注我的公众号,共同学习,共同进步!
.Net Core 二级域名绑定到指定的控制器的更多相关文章
- asp.net core mvc中如何把二级域名绑定到特定的控制器上
由于公司的工作安排,一直在研究其他技术,所以一直没时间更新博客,今天终于可以停下手头的事情,写一些新内容了. 应用场景:企业门户网站会根据内容不同,设置不同的板块,如新浪有体育,娱乐频道,等等.有的情 ...
- linux下关于Apache设置二级域名绑定二级目录的方法
背景:对于一些论坛网站,某些目录需要制定二级域名去访问,这时候就要在apache中用二级域名绑定二级目录. 方法: 1.首先你要找到apache安装路径,在apahce安装路径下的conf文件夹中找到 ...
- Linux虚拟主机通过程序实现二级域名绑定到子目录
虚拟主机中CP控制台不支持将二级域名绑定到子目录的功能,用户可以通过程序实现将二级域名绑定到子目录. 有两种方法将二级域名绑定到子目录: 1. 配置.htaccess, 通过伪静态代码实现.具体实现方 ...
- 阿里云Centos中二级域名绑定二级目录的方法
对于一些目录,我们往往需要对其指定二级域名,那么具体如何操作呢?下面,我将用亲身实践来说明一下. 由于第一次接触centos,我不得不借助于网络资源.然后得知要开启mod_rewrite这个模块,具体 ...
- 为阿里云ECS服务器二级域名绑定tomcat子目录,实现一个IP多个二级域名
摘要:前几天租了阿里云ECS服务器,选择的Windows系统,并在服务器上部署了tomcat服务器,随后我又买了一个域名,可一个域名只能指向一个IP地址,包括二级域名也只能指向一个IP地址,并不能指向 ...
- 二级域名绑定ECS
关于阿里云域名的绑定,下面是个人的理解,如有错误请指出. 首先,任何域名都需要在阿里云备案后才可以使用, 如果是二级域名,不能单独备案,需要其顶级域名在阿里云备案. http://help.aliyu ...
- thinkphp 二级域名绑定模块,导致设置的路由被多域名共用的问题解决方案
问题背景: 在router.php路由配置文件设置了二级域名和路由设置 use think\Route; Route::domain('www','index'); Route::domain('ad ...
- .htaccess 文件 访问二级域名 对应的 指定文件夹
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / # 绑定m.xxx.cc 到子目录m RewriteCond %{HTTP_ ...
- aliyun二级域名绑定
NameVirtualHost *:80 开启监听 <VirtualHost *:80> DocumentRoot /home/service/ ServerName serv ...
随机推荐
- boost 智能指针intrusive_ptr
boost::intrusive_ptr一种“侵入式”的引用计数指针,它实际并不提供引用计数功能,而是要求被存储的对象自己实现引用计数功能,并提供intrusive_ptr_add_ref和intru ...
- java通过url抓取网页数据
在很多行业中,要对行业数据进行分类汇总,及时分析行业数据,对于公司未来的发展,有很好的参照和横向对比.所以,在实际工作,我们可能要遇到数据采集这个概念,数据采集的最终目的就是要获得数据,提取有用的数据 ...
- Objective-C中的alloc和init问题
从开始学的NSString *name=[[NSString alloc] init] 起,仅仅这句话是分配内存空间,一直在用,从来没考虑过它的内部是怎么实现的.今天无意中看到了这一句代码: NSSt ...
- ZenCart分类数量打折Category Quantity Discount插件
附件:http://files.cnblogs.com/lzj87980239/Category_Quantity_Discount.rar 效果图后台1.将update.sql导入到数据库 2.将Y ...
- BigInteger和Complex:NET 4新增数据类型
BigInteger和Complex是.NET 4中新增的两种值类型,他们位于System.Numeric命名空间下,需要单独添加引用. BigInteger BigInteger类型是不可变类型,代 ...
- jQuery—$让渡
方法1:(取别名) 方法2:(指定作用域) 场景用例: 解决方案:方法1(取别名) 解决方案:方法2(指定作用域)
- ASP.NET MVC5 视图相关学习
MVC Razor模板引擎中3个重要的方法:@RenderBody.@RenderPage.@RenderSection 1.@RenderBody 在Razor引擎中布局页面类似于asp.net中的 ...
- Python面试题之Python迭代器
要理解迭代器,首先要从字面意思来说. 迭代 重复 下一次重复基于上一次的结果 软件开发就是典型的迭代更新. 讲迭代,我们就先来模拟一下迭代: 现在让我们使用while循环来遍历出一个列表list1 = ...
- linux把软件安装到指定目录
1.安装包带configure文件的: ./configure --prefix=安装目录 2.安装包不带configure文件,只带MakeFile 2.1 make install PREFIX= ...
- 20145303刘俊谦 《Java程序设计》实验四 实验报告
实验要求 完成实验.撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等).解决办法(空洞的方法如"查网络&q ...