ASP.NET Core 8中如何自动为PostDTO的CoverImage拼接域名?
解决方案
原因分析
你之前修改CoverImage属性的get方法时出现栈溢出,是因为get方法里直接引用了属性本身(比如return $"{domain}{CoverImage}"),导致无限递归调用get,最终触发栈溢出。
可行方案
方案1:使用私有字段存储原始路径,属性get拼接域名
把原始路径存在私有字段里,公共属性的get方法负责拼接域名,set方法给私有字段赋值。Dapper会通过属性的set将数据库值存入私有字段,完全避免递归问题:
public class PostDTO { private string _rawCoverImage; // 域名可从配置文件读取或通过构造注入获取 private readonly string _domain = "https://yourdomain.com"; public string CoverImage { get => string.IsNullOrEmpty(_rawCoverImage) ? null : $"{_domain}{_rawCoverImage}"; set => _rawCoverImage = value; } // 其他属性... }
方案2:实体转DTO时手动拼接域名
分离数据库实体和返回DTO,在查询完成后从实体转换为DTO的过程中完成域名拼接,DTO保持纯属性无逻辑:
// 数据库实体(与表结构一一对应) public class Post { public string CoverImage { get; set; } // 其他属性... } // 返回给客户端的DTO public class PostDTO { public string CoverImage { get; set; } // 其他属性... } // 查询并转换逻辑 var domain = "https://yourdomain.com"; var posts = await connection.QueryAsync<Post>("SELECT * FROM Posts"); var postDTOs = posts.Select(p => new PostDTO { CoverImage = $"{domain}{p.CoverImage}", // 映射其他属性 }).ToList(); return Ok(postDTOs);
方案3:自定义Dapper类型处理器
创建Dapper类型处理器,自动在读取数据库值时拼接域名,写入数据库时可反向移除域名(如果需要保存原始路径):
public class CoverImageHandler : SqlMapper.TypeHandler<string> { private readonly string _domain; public CoverImageHandler(string domain) { _domain = domain; } // 写入数据库时移除域名(仅当需要保存原始路径时启用) public override void SetValue(IDbDataParameter parameter, string value) { if (string.IsNullOrEmpty(value)) { parameter.Value = DBNull.Value; return; } parameter.Value = value.StartsWith(_domain) ? value.Replace(_domain, "") : value; } // 读取数据库时自动拼接域名 public override string Parse(object value) { var rawPath = value?.ToString(); return string.IsNullOrEmpty(rawPath) ? rawPath : $"{_domain}{rawPath}"; } } // 在Program.cs中注册处理器 var builder = WebApplication.CreateBuilder(args); var domain = builder.Configuration["AppSettings:Domain"]; // 从配置文件读取域名 SqlMapper.AddTypeHandler(new CoverImageHandler(domain));
注册后,你的PostDTO可以保持普通属性,Dapper会自动处理路径拼接,无需修改属性逻辑。
内容的提问来源于stack exchange,提问作者Reza245
相关产品推荐
相关产品推荐

