경로로 테넌트 검색


📮 문의하기 🇧🇷 🇺🇸 🇫🇷



경로로 테넌트 검색



ASP.NET 상용구(ABP)를 사용하여 도메인, 헤더 및 쿠키별로 테넌트를 검색할 수 있습니다. 이러한 옵션은 기본적으로 제공됩니다. 그러나 my-domain.com/api/{tenant}/resource와 같은 경로로 테넌트 정보를 얻으려면 ITenantResolveContributor를 구현하는 새 클래스를 추가해야 합니다.

모든 API 경로에 테넌트 추가



기본적으로 APB는 $"api/services/{moduleName}/{controllerName}/{action.ActionName}"과 같은 모든 경로를 설정한 다음 이 경로에 새 매개변수 {tenant}를 추가하고 싶습니다. ABP 코드를 보면 CreateAbpServiceAttributeRouteModel이 AbpAppServiceConvention.cs 파일 내의 비공개 정적 메서드임을 알 수 있습니다.

private static AttributeRouteModel CreateAbpServiceAttributeRouteModel(string moduleName, string controllerName, ActionModel action)
{
    return new AttributeRouteModel(
        new RouteAttribute(
            $"api/services/{moduleName}/{controllerName}/{action.ActionName}"
        )
    );
}


이를 알고 모든 중첩된 호출을 살펴본 후 원하는 대로 사용자 지정 경로 템플릿을 사용하도록 코드의 일부를 다시 작성하기로 결정했습니다. 이를 위해 AbpAppServiceConvention.cs, AbpMvcOptionsExtensions.cs, ReflectionHelper.cs 및 TypeHelper.cs 파일을 내 프로젝트에 복사했습니다. 그래서 경로 템플릿을 다음으로 변경할 수 있었습니다.

$"api/services/{moduleName}/{{tenant}}/{controllerName}/{action.ActionName}"


또한 이 새로운 서비스를 services.AddAbpWithoutCreatingServiceProvider 바로 앞에 있는 Startup 클래스에 추가해야 했습니다.

// new code...
services.Configure<MvcOptions>(mvcOptions => { mvcOptions.AddTest(services); });

// existing code...
services.AddAbpWithoutCreatingServiceProvider<AbpCustomizedWebHostModule>(
// ...


사용자 지정 PathTenantResolveContributor 만들기



사용자 지정 TenantResolveContributor 클래스를 생성할 수 있습니다. 기본 ABP 테넌트 기능을 위한 ITenantResolveContributor와 요청이 열려 있는 동안 인스턴스를 활성 상태로 유지하기 위한 IPerWebRequestDependency를 구현하는 PathTenantResolveContributor를 만들었습니다.

기본 구현은 요청의 RouteValues ​​내부 테넌트 키에서 테넌트를 검색하는 것입니다.

public class PathTenantResolveContributor : ITenantResolveContributor, IPerWebRequestDependency
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly ITenantStore _tenantStore;

    public PathTenantResolveContributor(IHttpContextAccessor httpContextAccessor, ITenantStore tenantStore)
    {
        _httpContextAccessor = httpContextAccessor;
        _tenantStore = tenantStore;
    }

    public int? ResolveTenantId()
    {
        var httpContext = _httpContextAccessor.HttpContext;

        if (httpContext is null || !httpContext.Request.RouteValues.Any(x => x.Key.Equals("tenant", StringComparison.OrdinalIgnoreCase)))
            return null;

        string tenancyName = httpContext.Request.RouteValues.First(x => x.Key.Equals("tenant", StringComparison.OrdinalIgnoreCase)).Value.ToString();

        if (string.IsNullOrEmpty(tenancyName))
            return null;

        var tenantInfo = _tenantStore.Find(tenancyName);

        if (tenantInfo is null)
            return null;

        return tenantInfo.Id;
    }
}


그런 다음 다른 모든 테넌시 확인자를 지우고 이 하나만 사용할 수 있습니다. 이를 위해 WebCoreModule의 PreInitialize 메서드로 이동하여 이 작업을 수행해야 합니다.

public override void PreInitialize()
{
    // new code...
    Configuration.MultiTenancy.Resolvers.Clear();
    Configuration.MultiTenancy.Resolvers.Add<PathTenantResolveContributor>();

    // existing code...
    Configuration.DefaultNameOrConnectionString = _appConfiguration.GetConnectionString(
        AbpCustomizedConsts.ConnectionStringName
    );

    // ...
}


마지막으로 애플리케이션을 실행하고 모든 경로에 기본적으로 새 테넌트 매개변수가 있는지 확인할 수 있습니다.



소스 코드



Source code

오타 또는 제안?



이 블로그 게시물에서 오타, 개선할 수 있는 문장 또는 업데이트해야 할 사항을 발견한 경우 git 저장소를 통해 액세스하고 풀 요청을 할 수 있습니다. github에 익숙하다면 댓글을 게시하는 대신 https://github.com/campelo/documentation로 직접 이동하여 변경 사항이 포함된 새로운 풀 리퀘스트를 여세요.

좋은 웹페이지 즐겨찾기