分享web开发知识

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

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

.Net Core 二级域名绑定到指定的控制器

发布时间:2023-09-06 01:45责任编辑:胡小海关键词:暂无标签

在说二级域名绑定之前,先说一下.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扩展

[csharp]view plaincopy
  1. <span>publicclassSubDomainRouter:RouteBase
  2. {
  3. privatereadonlyIRouter_target;
  4. privatereadonlystring_subDomain;
  5. publicSubDomainRouter(
  6. IRoutertarget,
  7. stringsubDomain,//当前路由规则绑定的二级域名
  8. stringrouteTemplate,
  9. RouteValueDictionarydefaults,
  10. RouteValueDictionaryconstrains,
  11. IInlineConstraintResolverinlineConstraintResolver)
  12. :base(routeTemplate,
  13. subDomain,
  14. inlineConstraintResolver,
  15. defaults,
  16. constrains,
  17. newRouteValueDictionary(null))
  18. {
  19. if(target==null)
  20. {
  21. thrownewArgumentNullException(nameof(target));
  22. }
  23. if(subDomain==null)
  24. {
  25. thrownewArgumentNullException(nameof(subDomain));
  26. }
  27. _subDomain=subDomain;
  28. _target=target;
  29. }
  30. publicoverrideTaskRouteAsync(RouteContextcontext)
  31. {
  32. stringdomain=context.HttpContext.Request.Host.Host;//获取当前请求域名,然后跟_subDomain比较,如果不想等,直接忽略
  33. if(string.IsNullOrEmpty(domain)||string.Compare(_subDomain,domain)!=0)
  34. {
  35. returnTask.CompletedTask;
  36. }
  37.       
  38.     //如果域名匹配,再去验证访问路径是否匹配
  39. returnbase.RouteAsync(context);
  40. }
  41. protectedoverrideTaskOnRouteMatched(RouteContextcontext)
  42. {
  43. context.RouteData.Routers.Add(_target);
  44. return_target.RouteAsync(context);
  45. }
  46. protectedoverrideVirtualPathDataOnVirtualPathGenerated(VirtualPathContextcontext)
  47. {
  48. return_target.GetVirtualPath(context);
  49. }
  50. }</span>

如何把域名绑定到指定的控制器上,代码如下:

[csharp]view plaincopy
  1. <span>publicstaticclassRouteBuilderExtensions
  2. {
  3. publicstaticIRouteBuilderMapDomainRoute(
  4. thisIRouteBuilderrouteBuilder,stringdomain,stringarea,stringcontroller)
  5. {
  6. if(string.IsNullOrEmpty(area)||string.IsNullOrEmpty(controller))
  7. {
  8. thrownewArgumentNullException("areaorcontrollercannotbenull");
  9. }
  10. varinlineConstraintResolver=routeBuilder
  11. .ServiceProvider
  12. .GetRequiredService<IInlineConstraintResolver>();
  13. stringtemplate="";
  14. RouteValueDictionarydefaults=newRouteValueDictionary();
  15. RouteValueDictionaryconstrains=newRouteValueDictionary();
  16. constrains.Add("area",area);
  17. defaults.Add("area",area);
  18. constrains.Add("controller",controller);
  19. defaults.Add("controller",string.IsNullOrEmpty(controller)?"home":controller);
  20. defaults.Add("action","index");
  21. template+="{action}/{id?}";//路径规则中不再包含控制器信息,但是上面通过constrains限定了查找时所要求的控制器名称
  22. routeBuilder.Routes.Add(newSubDomainRouter(routeBuilder.DefaultHandler,domain,template,defaults,constrains,inlineConstraintResolver));
  23. returnrouteBuilder;
  24. }
  25. }</span>

使用方法:

[csharp]view plaincopy
  1. <span>routes.MapDomainRoute("xxx.domain.com","areaname","controllername");</span>

以上代码为原博客中的代码,使用起来也很方便,只需要传值域名,区域名,控制器名,就可以实现我们想要的结果。下面我对以上代码稍作了修改,通过配置文件配置域名和控制器的绑定。新建一个关于域名、区域、控制器名的Model:

[csharp]view plaincopy
  1. <span>///域名信息实体类
  2. ///<summary>
  3. ///域名信息实体类
  4. ///</summary>
  5. publicclassSubDomain
  6. {
  7. ///域名
  8. ///<summary>
  9. ///域名
  10. ///</summary>
  11. publicstringDomain{get;set;}
  12. ///区域名
  13. ///<summary>
  14. ///区域名
  15. ///</summary>
  16. publicstringAreaName{get;set;}
  17. ///控制器名
  18. ///<summary>
  19. ///控制器名
  20. ///</summary>
  21. publicstringController{get;set;}
  22. }</span>

另外在MapDomainRoute扩展方法中,去掉了对区域的判断, 这样也可以配置非区域的控制器了,代码如下:

[csharp]view plaincopy
  1. <span>publicstaticIRouteBuilderMapDomainRoute(
  2. thisIRouteBuilderrouteBuilder,stringdomain,stringarea,stringcontroller)
  3. {
  4. try
  5. {
  6. <spanstyle="background-color:rgb(255,204,0);">if(string.IsNullOrEmpty(domain))
  7. {
  8. thrownewArgumentNullException("domaincannotbenull");
  9. }
  10. //string.IsNullOrEmpty(area)||//去掉该判断,不限制仅限区域使用配置
  11. if(string.IsNullOrEmpty(controller))
  12. {
  13. thrownewArgumentNullException("controllercannotbenull");
  14. }</span>
  15. varinlineConstraintResolver=routeBuilder
  16. .ServiceProvider
  17. .GetRequiredService<IInlineConstraintResolver>();
  18. stringtemplate="";
  19. RouteValueDictionarydefaults=newRouteValueDictionary();
  20. RouteValueDictionaryconstrains=newRouteValueDictionary();
  21. constrains.Add("area",area);
  22. defaults.Add("area",area);
  23. constrains.Add("controller",controller);
  24. defaults.Add("controller",string.IsNullOrEmpty(controller)?"Home":controller);
  25. defaults.Add("action","index");
  26. template+="{action}/{id?}";//路径规则中不再包含控制器信息,但是上面通过constrains限定了查找时所要求的控制器名称
  27. routeBuilder.Routes.Add(newSubDomainRouter(routeBuilder.DefaultHandler,domain,template,defaults,constrains,inlineConstraintResolver));
  28. returnrouteBuilder;
  29. }
  30. catch(Exceptionex)
  31. {
  32. throwex;
  33. }
  34. }</span>

同时也添加了一个对该方法的重载:

[csharp]view plaincopy
  1. <span>publicstaticvoidMapDomainRoute(thisIRouteBuilderrouteBuilder,List<SubDomain>listDomains)
  2. {
  3. try
  4. {
  5. if(listDomains==null||listDomains.Count<=0)
  6. {
  7. return;
  8. }
  9. foreach(SubDomaindomaininlistDomains)
  10. {
  11. MapDomainRoute(routeBuilder,domain.Domain,domain.AreaName,domain.Controller);
  12. }
  13. }
  14. catch(Exceptionex)
  15. {
  16. throwex;
  17. }
  18. }</span>

将域名路由信息配置到appsetting.json文件中,例如:

当然在.net core中可以直接从IConfiguration对象中可以直接获取到配置文件下的信息,但我也没找到可以直接序列化我为要的标准的Json格式,就使用了直接读取文件的方式,借助Json.Net,又反序列化成我要的实体信息List<SubDomain>,代码如下:

[csharp]view plaincopy
  1. <span>//获取域名路由配置规则信息
  2. varjsonDomain=JObject.Parse(File.ReadAllText("appsettings.json"))["SubDomains"];
  3. if(jsonDomain!=null)
  4. {
  5. varinfos=JsonConvert.DeserializeObject<List<SubDomain>>(jsonDomain.ToString());
  6. routes.MapDomainRoute(infos);
  7. }</span>

这样也就可以直接通过配置文件去修改配置了,效果展示:

https://www.allenchoi.net

https://blog.allenchoi.net

https://admin.allenchoi.net

以上就实现了我们想要的结果。

原文中涉及到的博客地址(尊重原创):http://www.cnblogs.com/dxp909/p/6994354.html

扫描二维码关注我的公众号,共同学习,共同进步!

.Net Core 二级域名绑定到指定的控制器

原文地址:https://www.cnblogs.com/Allen0910/p/8570765.html

知识推荐

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