问题描述
ABP软件包版本:5.9.0
基本框架:.NET Core
使用带有Angular模板的.NET核心。
我如下配置appConfig.json,以使用子域标识租户。
{
"remoteServiceBaseUrl": "http://{TENANCY_NAME}.localhost:21021","appBaseUrl": "http://{TENANCY_NAME}.localhost:4200","localeMappings": [
{ "from": "pt-BR","to": "pt" },{ "from": "zh-CN","to": "zh" },{ "from": "he-IL","to": "he" }
]
}
但是Angular模板对URL http://%7Btenancy_name%7D.localhost:21021/AbpUserConfiguration/GetAll
进行了API调用。
解决方法
免责声明:未经测试,可能需要进行细微更改。
来自ASP.NET Boilerplate GitHub存储库中的问题#5800 1 :
您需要从URL中提取它,然后自己替换URL。
步骤:
- 实现
RemoteServiceBaseUrlService
类似于模板中的AppUrlService
2 。
export class RemoteServiceBaseUrlService {
static tenancyNamePlaceHolder = '{TENANCY_NAME}';
...
get remoteServiceBaseUrl(): string {
if (this._appSessionService.tenant) {
return this.getRemoteServiceBaseUrlOfTenant(this._appSessionService.tenant.tenancyName);
} else {
return this.getRemoteServiceBaseUrlOfTenant(null);
}
}
/**
* Returning url ends with '/'.
*/
getRemoteServiceBaseUrlOfTenant(tenancyName?: string): string {
// let baseUrl = this.ensureEndsWith(AppConsts.appBaseUrl,'/');
let baseUrl = this.ensureEndsWith(AppConsts.remoteServiceBaseUrl,'/');
...
}
...
}
- 在
API_BASE_URL
中替换RootModule
提供者。
@NgModule({
...
providers: [
...
// { provide: API_BASE_URL,useFactory: () => AppConsts.remoteServiceBaseUrl },{
provide: API_BASE_URL,useFactory: (remoteServiceBaseUrlService: RemoteServiceBaseUrlService) => remoteServiceBaseUrlService.remoteServiceBaseUrl,deps: [RemoteServiceBaseUrlService],multi: true,},...
],...
})
export class RootModule {}
- 接受
remoteServiceBaseUrl
中的SignalRAspNetCoreHelper.initSignalR
。
export class SignalRAspNetCoreHelper {
// static initSignalR(callback?: () => void): void {
static initSignalR(remoteServiceBaseUrl: string,callback?: () => void): void {
const encryptedAuthToken = new UtilsService().getCookieValue(AppConsts.authorization.encryptedAuthTokenName);
abp.signalr = {
autoConnect: true,connect: undefined,hubs: undefined,qs: AppConsts.authorization.encryptedAuthTokenName + '=' + encodeURIComponent(encryptedAuthToken),// remoteServiceBaseUrl: AppConsts.remoteServiceBaseUrl,remoteServiceBaseUrl,startConnection: undefined,url: '/signalr'
};
- 在
RemoteServiceBaseUrlService
中注入AppComponent
并通过remoteServiceBaseUrl
。
export class AppComponent extends AppComponentBase implements OnInit {
sidebarExpanded: boolean;
constructor(
injector: Injector,private renderer: Renderer2,private _layoutStore: LayoutStoreService,private _remoteServiceBaseUrlService: RemoteServiceBaseUrlService
) {
super(injector);
}
ngOnInit(): void {
this.renderer.addClass(document.body,'sidebar-mini');
// SignalRAspNetCoreHelper.initSignalR();
SignalRAspNetCoreHelper.initSignalR(this._remoteServiceBaseUrlService.remoteServiceBaseUrl);
- 类似于步骤3和4,替换
AppConsts.remoteServiceBaseUrl
的所有剩余用法。
参考
- 问题#5800:https://github.com/aspnetboilerplate/aspnetboilerplate/issues/5800
-
AppUrlService
:https://github.com/aspnetboilerplate/module-zero-core-template/blob/d2a2ab3ff4486983c84aa48a173c2de102f36c2e/angular/src/shared/nav/app-url.service.ts
我找到了一个简单的解决方案。更新 app-initializer.ts
如下:
一、添加方法
private replaceTenantPlaceholder(baseUrl: string,defaultSubDomain: string): string {
const tenancyNamePlaceHolder = '{TENANCY_NAME}';
baseUrl = baseUrl.replace(tenancyNamePlaceHolder + '.',tenancyNamePlaceHolder);
var subDomain = window.location.hostname.split(".")[0];
subDomain = subDomain.replace(`$:{window.location.port}`,"");
switch (window.location.hostname.split(".").length) {
case 1:
case 2:
//No sub-domain on current url
subDomain = defaultSubDomain;
if (subDomain.length > 0) subDomain += ".";
break;
case 3:
//Use the current url's sub-domain
subDomain += ".";
default:
}
return baseUrl.replace(tenancyNamePlaceHolder,subDomain);
}
然后更新方法getApplicationConfig
:
AppConsts.appBaseUrl = this.replaceTenantPlaceholder(response.appBaseUrl,"www");
AppConsts.remoteServiceBaseUrl = this.replaceTenantPlaceholder(response.remoteServiceBaseUrl,"");
多租户的这一部分不需要其他修改。确保更新 CoreModule 中的 Configuration.Modules.AbpWebCommon().MultiTenancy.DomainFormat
并在 appsettings.json
我的客户端应用程序需要域中的“www”,所以这就是我使用 defaultSubDomain 参数的原因。如果不需要,您可以省略它。