【问题标题】:Handle SubDomain in Asp.net Core 3.1 application在 Asp.net Core 3.1 应用程序中处理子域
【发布时间】:2020-07-07 09:12:03
【问题描述】:

我正在开发一个 asp.net core 3.1 应用程序 (MVC),作为要求,每个帐户都应该有它的子域(例如:mystore.domain.com)和它的数据。所以我试图弄清楚如何在路由模式中添加子域部分,并在我的控制器中捕获它以获取用户数据,并将其返回到视图中。

我做了一些研究并找到了 asp.net core 版本 2 的解决方案,不幸的是,它在版本 3 上不起作用(发生了很大变化)this article for example。

总结:

  1. 用户类型:mystore.domain.com 或 mystore.domain.com\store
  2. 我捕获了 subsomain “mystore”,在数据库中搜索用户数据,然后渲染一个视图。

【问题讨论】:

  • 你有什么可行的解决方案吗?

标签: c# asp.net-core subdomain multi-tenant


【解决方案1】:

您可以使用filter,特别是动作过滤器,它可以:

  • 在调用操作方法之前和之后立即运行代码。
  • 可以更改传递给操作的参数。
  • 可以更改操作返回的结果。
  • 在 Razor 页面中不受支持。

一个例子是

public class MySampleActionFilter : IActionFilter 
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
    }
}

在这里,您可以准备一个范围服务,根据该服务加载用户,然后在需要该数据的任何服务中重用它。

即使没有过滤器,您也可以简单地创建一个具有作用域生命周期的 UserService,在其中加载用户并在您的服务中的任何位置使用它。

在我们的系统中,我们正在做类似的事情:

加载会话数据的服务:

public class ClientTokenService
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public ClientTokenService(
        IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public Profile LoadProfile()
    {
        if (_httpContextAccessor.HttpContext.User == null)
        {
            throw new Exception("No user claims found to load Profile");
        }

        var user = _httpContextAccessor.HttpContext.User;

        var numberType = (NumberType)int.Parse(user.FindFirst("numberType").Value);
        var profileType = (PackagePlan)int.Parse(user.FindFirst("profileType").Value);
        var lineOfBusiness = (LineOfBusiness)int.Parse(user.FindFirst("lineOfBusiness").Value);

        // More stuff

        // Prepare the profile data
        return new Profile(
            user.FindFirst("number").Value,
            user.FindFirst("contractId").Value,
            numberType,
            profileType,
            user.FindFirst("cc")?.Value,
            user.FindFirst("app").Value,
            user.FindFirst("clickId")?.Value,
            user.FindFirst("wifi") != null,
            lineOfBusiness
        );
    }
}

此服务可以是暂时的,然后是保存数据的范围服务

public class ClientSessionContext
{
    public Profile Profile { get; }

    public ClientSessionContext(
        ClientTokenService sessionService)
    {
        Profile = sessionService.LoadProfile();
    }
}

将此服务声明为作用域,因此此类仅在每个请求中初始化一次

Statup.cs

services.AddScoped<ClientSessionContext>();

然后只需在您需要访问用户数据的任何地方注入此服务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-25
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    相关资源
    最近更新 更多