来自Angular的无效API调用-remoteServiceBaseUrl中的占位符

问题描述

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。

步骤:

  1. 实现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,'/');

        ...
    }

    ...
}
  1. 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 {}
  1. 接受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'
        };
  1. 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);
  1. 类似于步骤3和4,替换AppConsts.remoteServiceBaseUrl的所有剩余用法。

参考

  1. 问题#5800:https://github.com/aspnetboilerplate/aspnetboilerplate/issues/5800
  2. AppUrlServicehttps://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

中定义 CorsOrigins

我的客户端应用程序需要域中的“www”,所以这就是我使用 defaultSubDomain 参数的原因。如果不需要,您可以省略它。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...