.Net Core WebAPI如何在AutoMapper Profile中获取接口基地址拼接AttachmentUrl
AutoMapper Profile 中获取Web API基地址的解决方案
核心逻辑:AutoMapper的Profile默认是全局单例注册的,不能直接存储随请求变化的动态值,所以分两种场景处理:
场景1:BaseUrl为全局固定值(写在配置文件中,不会随请求变化)
你可以直接将基地址通过Profile的构造函数传入,步骤如下:
- 首先修改NoteProfile的定义,增加构造函数参数接收BaseUrl:
public class NoteProfile : Profile { // 私有字段存储固定的BaseUrl private readonly string _baseUrl; public NoteProfile(string baseUrl) { _baseUrl = baseUrl; // 注意:原代码中的sc.Id有误,实体类主键为NoteId CreateMap<NoteDto, Note>().ReverseMap() .ForMember(a => a.AttachmentUrl, ac => ac.MapFrom(sc => $"{_baseUrl}notes/download/{sc.NoteId}")); } }
- 注册AutoMapper时传入配置中的BaseUrl即可:
// 示例:ASP.NET Core 中从配置读取BaseUrl并注册 builder.Services.AddAutoMapper(cfg => { cfg.AddProfile(new NoteProfile(builder.Configuration["ApiSettings:BaseUrl"])); });
场景2:BaseUrl为动态值(随请求域名变化,多域名部署场景)
这种情况需要使用AutoMapper的运行时参数传递能力,通过映射上下文的Items字典传递基地址:
- 第一步:修改Profile的映射配置,使用带ResolutionContext的MapFrom重载:
public class NoteProfile : Profile { public NoteProfile() { CreateMap<NoteDto, Note>().ReverseMap() .ForMember(a => a.AttachmentUrl, // 从上下文Items中获取BaseUrl ac => ac.MapFrom((sc, _, _, ctx) => $"{ctx.Items["BaseUrl"]}notes/download/{sc.NoteId}")); } }
- 第二步:在调用映射的位置(通常是Controller中)传入当前请求的基地址:
[ApiController] [Route("api/[controller]")] public class NotesController : ControllerBase { private readonly IMapper _mapper; private readonly INoteRepository _noteRepository; public NotesController(IMapper mapper, INoteRepository noteRepository) { _mapper = mapper; _noteRepository = noteRepository; } [HttpGet] public async Task<IActionResult> GetAll() { var notes = await _noteRepository.GetAllAsync(); // 拼接当前请求的基地址 var baseUrl = $"{Request.Scheme}://{Request.Host}{Request.PathBase}/"; // 映射时传入BaseUrl到上下文Items var noteDtos = _mapper.Map<List<NoteDto>>(notes, opt => { opt.Items["BaseUrl"] = baseUrl; }); return Ok(noteDtos); } }
注意点
原代码中sc.Id存在错误,你的Note实体类和NoteDto的主键字段都是NoteId,需要替换为对应字段名。
内容的提问来源于stack exchange,提问作者Anurag
相关产品推荐
相关产品推荐

