由于公司的工作安排,一直在研究其他技术,所以一直没时间更新博客,今天终于可以停下手头的事情,写一些新内容了。

  应用场景:企业门户网站会根据内容不同,设置不同的板块,如新浪有体育,娱乐频道,等等。有的情况下需要给不同的板块设置不同的二级域名,如新浪体育sports.sina.com.cn。

  在asp.net core mvc中,如果要实现板块的效果,可能会给不同的板块建立不同的控制器(当然也有其他的技术,这里不讨论实现方式的好坏),在这种情况下,如何给控制器绑定上独有的二级域名,比如体育频道对应的控制器叫SportController,通过sports.XXX.com域名访问系统的时候,直接进入SportController,并且通过这个二级域名无法访问其他的控制器。

  上面说完场景了,下面来看下如何实现。

  在asp.net core mvc中有路由规则配置,配置的地方在Startup.Configure方法中,具体代码如下:

  

app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}",
defaults: new { area="admin"});
});

  遗憾的是不支持对域名的支持(我目前了解的是,如果有问题,欢迎大家指正)。通过routes.MapRouter注册路由规则,并加入到RouteCollection中,当某个请求过来后,RouterCollection循环所有注册好的IRouter对象,找到第一个匹配的IRouter为止。虽然框架不支持域名配置规则,但是我们可以自己去实现一个IRouter,在里面实现二级域名判断的逻辑,我这里暂时起名为SubDomainRouter,具体实现代码如下:

  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);
}
}

  从上面的代码我们只看到了域名检测,但是如何把域名定向到特定的控制器上,这就需要我们在注册这个IRouter的时候做些文章,直接上代码:

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;
}
}

  最后我们就可以在Startup中注册对应的规则,如下:

app.UseMvc(
routes =>
{
routes.MapDomainRoute("xxx.domain.com","areaname","controllername"); routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}",
defaults: new { area = "web" });
});

  实现方法可能不是最好的,但是已经满足了基本需求,如果大家有更好的方法,欢迎讨论交流。

  

  

  

asp.net core mvc中如何把二级域名绑定到特定的控制器上的更多相关文章

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

    在说二级域名绑定之前,先说一下.net core中的区域,关于区域这一块儿在很久之前的博客中,已经提过,详见<03-dotnet core创建区域[Areas]及后台搭建>,在这篇博客中, ...

  2. ASP.NET Core MVC 中的 [Controller] 和 [NonController]

    前言 我们知道,在 MVC 应用程序中,有一部分约定的内容.其中关于 Controller 的约定是这样的. 每个 Controller 类的名字以 Controller 结尾,并且放置在 Contr ...

  3. ASP.NET Core MVC 中设置全局异常处理方式

    在asp.net core mvc中,如果有未处理的异常发生后,会返回http500错误,对于最终用户来说,显然不是特别友好.那如何对于这些未处理的异常显示统一的错误提示页面呢? 在asp.net c ...

  4. 006.Adding a controller to a ASP.NET Core MVC app with Visual Studio -- 【在asp.net core mvc 中添加一个控制器】

    Adding a controller to a ASP.NET Core MVC app with Visual Studio 在asp.net core mvc 中添加一个控制器 2017-2-2 ...

  5. 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】

    Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...

  6. ASP.NET Core MVC中的 [Required]与[BindRequired]

    在开发ASP.NET Core MVC应用程序时,需要对控制器中的模型校验数据有效性,元数据注释(Data Annotations)是一个完美的解决方案. 元数据注释最典型例子是确保API的调用者提供 ...

  7. ASP.NET Core MVC中构建Web API

    在ASP.NET CORE MVC中,Web API是其中一个功能子集,可以直接使用MVC的特性及路由等功能. 在成功构建 ASP.NET CORE MVC项目之后,选中解决方案,先填加一个API的文 ...

  8. 007.Adding a view to an ASP.NET Core MVC app -- 【在asp.net core mvc中添加视图】

    Adding a view to an ASP.NET Core MVC app 在asp.net core mvc中添加视图 2017-3-4 7 分钟阅读时长 本文内容 1.Changing vi ...

  9. 在ASP.NET Core MVC中子类Controller拦截器要先于父类Controller拦截器执行

    我们知道在ASP.NET Core MVC中Controller上的Filter拦截器是有执行顺序的,那么如果我们在有继承关系的两个Controller类上,声明同一种类型的Filter拦截器,那么是 ...

随机推荐

  1. AsciiDoc Text based document generation

    AsciiDoc Text based document generation    AsciiDoc Home Page http://asciidoc.org/   AsciiDoc is a t ...

  2. Powered by Flink

    Apache Flink: Powered by Flink https://flink.apache.org/poweredby.html Powered by Flink Apache Flink ...

  3. app返回之前app焦点的操作方法

    var hdWin,hdfocus: THandle; trdID: Cardinal; //获取前置app窗口句柄 hdWin := GetForegroundWindow;//FindWindow ...

  4. java获取当前路径&读取当前目录下文件

    项目目录如下: test1.class中读取test.txt import java.io.*; import java.util.Scanner; public class Test1 { publ ...

  5. VS c++ opencv画图

    任务:用c++在图片上画线 之前用过python的opencv,所以直接想到了用c++的opencv来画线. 但关键就是VS中如何配置c++ opencv库的问题: vs中opencv库的配置:htt ...

  6. PYTHON 最佳实践指南(转)

    add by zhj: 本文参考了The Hitchhiker's Guide to Python,当然也加入了作者的一些东西.The Hitchhiker's Guide to Python 的gi ...

  7. Diango思维图

    1,http 2,Django生命周期 3,Django部分命令 4,待续...

  8. Spring的IoC模式

    1.依赖 依赖就是有联系,有地方使用到它就是有依赖它,一个系统不可能完全避免依赖.如果你的一个类或者模块在项目中没有用到它,恭喜你,可以从项目中剔除它或者排除它了,因为没有一个地方会依赖它.下面看一个 ...

  9. PAGELATCH_x和PAGEIOLATCH_x介绍

    Microsoft SQL Server企业级平台管理实践 第11章 Buffer Latch Timeout的解析 什么是PAGELATCH和PAGEIOLATCH 1.PAGELATCH_x和PA ...

  10. Linux服务器内存cache清理

    发现cache中占用大量内存,无free内存可用 使用如下命令清理: syncsysctl -w vm.drop_caches=1 转自:http://blog.csdn.net/sky_qing/a ...