如何在ASP.NET Web应用的Angular模板中显示.rsx资源文件文本?
在Angular 14中显示ASP.NET外部.rsx资源文本的实现方案
步骤1:ASP.NET端暴露资源读取接口
首先需要在遗留ASP.NET应用中编写接口,让Angular可以通过HTTP请求获取.rsx文件中的文本,根据你的ASP.NET版本选择对应实现:
方式A:Web Forms环境(WebMethod)
在ASPX页面的代码后台添加静态Web方法:
using System.Collections.Generic; using System.Web.Services; [WebMethod] public static string GetResource(string key) { // 替换为你的.rsx资源文件名 return Resources.AppResources.ResourceManager.GetString(key) ?? $"[{key}]"; } // 可选:批量获取资源,减少HTTP请求次数 [WebMethod] public static Dictionary<string, string> GetResources(List<string> keys) { var resourceMap = new Dictionary<string, string>(); foreach (var key in keys) { resourceMap[key] = Resources.AppResources.ResourceManager.GetString(key) ?? $"[{key}]"; } return resourceMap; }
方式B:MVC/Web API环境(ApiController)
创建资源控制器:
using System.Collections.Generic; using System.Web.Http; public class ResourcesController : ApiController { [Route("api/resources/{key}")] [HttpGet] public IHttpActionResult GetSingleResource(string key) { var text = Resources.AppResources.ResourceManager.GetString(key) ?? $"[{key}]"; return Ok(text); } [Route("api/resources/batch")] [HttpPost] public IHttpActionResult GetBatchResources(List<string> keys) { var resourceMap = new Dictionary<string, string>(); foreach (var key in keys) { resourceMap[key] = Resources.AppResources.ResourceManager.GetString(key) ?? $"[{key}]"; } return Ok(resourceMap); } }
步骤2:Angular端创建资源服务
封装资源获取逻辑并添加缓存,避免重复请求,创建全局服务:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable, of } from 'rxjs'; import { tap, map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class ResourceService { private resourceCache = new Map<string, string>(); constructor(private http: HttpClient) {} // 获取单个资源 getResource(key: string): Observable<string> { if (this.resourceCache.has(key)) { return of(this.resourceCache.get(key)!); } return this.http.get<string>('/api/resources/' + key).pipe( tap(text => this.resourceCache.set(key, text)) ); } // 批量获取资源 getResources(keys: string[]): Observable<Map<string, string>> { const missingKeys = keys.filter(key => !this.resourceCache.has(key)); if (missingKeys.length === 0) { const result = new Map(keys.map(key => [key, this.resourceCache.get(key)!])); return of(result); } return this.http.post<Record<string, string>>('/api/resources/batch', missingKeys).pipe( tap(resources => { Object.entries(resources).forEach(([key, text]) => this.resourceCache.set(key, text)); }), map(resources => new Map([...Array.from(this.resourceCache.entries()), ...Object.entries(resources)])) ); } }
步骤3:组件模板中使用资源
在Angular组件中注入服务,通过async管道处理异步数据,直接绑定到模板:
单个资源示例
组件代码:
import { Component } from '@angular/core'; import { ResourceService } from './resource.service'; @Component({ selector: 'app-welcome', template: `<h1>{{ welcomeText$ | async }}</h1>` }) export class WelcomeComponent { welcomeText$ = this.resourceService.getResource('WelcomeMessage'); constructor(private resourceService: ResourceService) {} }
批量资源示例
组件代码:
import { Component } from '@angular/core'; import { ResourceService } from './resource.service'; @Component({ selector: 'app-user-form', template: ` <label>{{ (formTexts$ | async)?.get('UsernameLabel') }}</label> <input type="text" placeholder="{{ (formTexts$ | async)?.get('UsernamePlaceholder') }}"> <button>{{ (formTexts$ | async)?.get('SubmitButtonText') }}</button> ` }) export class UserFormComponent { formTexts$ = this.resourceService.getResources([ 'UsernameLabel', 'UsernamePlaceholder', 'SubmitButtonText' ]); constructor(private resourceService: ResourceService) {} }
注意事项
- 同域验证:确保Angular与ASP.NET应用部署在同一域名下,避免跨域问题;若需跨域,需在ASP.NET端配置CORS。
- 缓存管理:如果.rsx资源有更新需求,可在服务中添加缓存清空方法,或设置缓存过期时间。
- 缺失key处理:ASP.NET接口返回默认文本(如
[key]),避免Angular模板显示undefined。
内容的提问来源于stack exchange,提问作者Niryana
相关产品推荐
相关产品推荐

