简体   繁体   English

在 Asp.net Core 3.1 应用程序中处理子域

[英]Handle SubDomain in Asp.net Core 3.1 application

I'm working on an asp.net core 3.1 application (MVC), and as a requirement, every account should have its subdomain (ex : mystore.domain.com) and its data.我正在开发一个 asp.net core 3.1 应用程序 (MVC),作为一项要求,每个帐户都应该有它的子域(例如:mystore.domain.com)及其数据。 So I'm trying to figure out how to add the subdomain part in the routing pattern, and catch it in my controller in order to get the user data, and return it in a view.所以我试图弄清楚如何在路由模式中添加子域部分,并在我的控制器中捕获它以获取用户数据,并在视图中返回它。

I've done some research and found solutions for asp.net core version 2, unfortunettly, it does not work on version 3 (so much have changed) this article for example .我做了一些研究并找到了针对 asp.net 核心版本 2 的解决方案,不幸的是,它不适用于版本 3( 例如发生了很多变化) 这篇文章

Summary :概括 :

  1. User types : mystore.domain.com or mystore.domain.com\\store用户类型:mystore.domain.com 或 mystore.domain.com\\store
  2. I catch the subsomain "mystore", search the database for the user data, and render a view.我捕获子域“mystore”,在数据库中搜索用户数据,并呈现视图。

You could use a filter , specifically, an action filter, which could:您可以使用过滤器,特别是操作过滤器,它可以:

  • Run code immediately before and after an action method is called.在调用操作方法之前和之后立即运行代码。
  • Can change the arguments passed into an action.可以更改传递给动作的参数。
  • Can change the result returned from the action.可以改变动作返回的结果。
  • Are not supported in Razor Pages. Razor Pages 不支持。

An example is一个例子是

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

Here you could prepare a scoped service, load the user based on the service and then reuse it in any service that requires that data.在这里,您可以准备一个范围服务,根据服务加载用户,然后在需要该数据的任何服务中重用它。

Even without the filter, you could simply create a UserService with a scoped lifetime, load the user there and use it anywhere in your services.即使没有过滤器,您也可以简单地创建一个具有作用域生命周期的 UserService,在那里加载用户并在您的服务中的任何地方使用它。

In our system we are doing something similar:在我们的系统中,我们正在做类似的事情:

A service to load the session data:加载会话数据的服务:

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

This service can be transient, and then a scoped service which saves the data此服务可以是瞬态的,然后是保存数据的范围服务

public class ClientSessionContext
{
    public Profile Profile { get; }

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

Declare this service as scoped, so this class is initialized just once per request将此服务声明为作用域,因此此类每个请求仅初始化一次

Statup.cs状态文件

services.AddScoped<ClientSessionContext>();

Then just inject this service anywhere where you need access to the user data.然后只需在需要访问用户数据的任何地方注入此服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM