如何在C#接口返回PlayerProfile类时忽略指定属性
解决C#接口返回对象时忽略敏感属性且不影响初始化的方案
针对你的需求,核心是要做到序列化输出时忽略PasswordHash和PasswordSalt,但不影响对象的初始化/反序列化赋值,下面提供三种实用方案:
1. 使用DTO(数据传输对象)【推荐】
这种方式完全隔离数据模型与展示模型,是最清晰、最符合软件工程原则的方案,绝对不会影响PlayerProfile的初始化逻辑。
实现步骤:
- 新建一个仅包含需要展示属性的DTO类
- 在接口中把
PlayerProfile对象映射到DTO后返回
示例代码:
// 用于接口展示的DTO类 public class PlayerProfileDto { public string Id { get; set; } public string AccountType { get; set; } public string UserEmail { get; set; } public string Username { get; set; } public string Country { get; set; } public string Passphrase { get; set; } public Wallet Wallet { get; set; } public List<string> Titles { get; set; } } // 接口中的使用示例(ASP.NET Core场景) [HttpGet("{id}")] public IActionResult GetPlayerProfile(string id) { // 从数据库/服务获取完整的PlayerProfile对象 PlayerProfile profile = _playerRepo.GetById(id); // 手动映射到DTO(也可以用AutoMapper等工具简化映射) var dto = new PlayerProfileDto { Id = profile.id, AccountType = profile.AccountType, UserEmail = profile.UserEmail, Username = profile.Username, Country = profile.Country, Passphrase = profile.Passphrase, Wallet = profile.Wallet, Titles = profile.Titles }; return Ok(dto); }
2. 使用Newtonsoft.Json(Json.NET)特性配置
如果你使用Newtonsoft.Json作为序列化库,可以通过特性控制仅在序列化时忽略属性,反序列化时正常赋值。
特性方式(直接标记属性)
using Newtonsoft.Json; public class PlayerProfile : BaseDataModel { public string id { get; set; } public string AccountType { get; set; } public string UserEmail { get; set; } public string Username { get; set; } public string Country { get; set; } // 序列化时忽略,反序列化时允许赋值 [JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)] public byte[] PasswordHash { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)] public byte[] PasswordSalt { get; set; } public string Passphrase { get; set; } public Wallet Wallet { get; set; } public List<string> Titles { get; set; } }
自定义ContractResolver(全局/批量控制)
如果需要对多个类或属性做统一控制,可以自定义解析器:
using Newtonsoft.Json; using Newtonsoft.Json.Serialization; public class PlayerProfileContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(System.Reflection.MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); // 指定忽略的属性 if (property.PropertyName == nameof(PlayerProfile.PasswordHash) || property.PropertyName == nameof(PlayerProfile.PasswordSalt)) { property.ShouldSerialize = _ => false; // 序列化时不输出 property.ShouldDeserialize = _ => true; // 反序列化时允许赋值 } return property; } } // 接口中使用示例 [HttpGet("{id}")] public IActionResult GetPlayerProfile(string id) { PlayerProfile profile = _playerRepo.GetById(id); var settings = new JsonSerializerSettings { ContractResolver = new PlayerProfileContractResolver() }; return Json(profile, settings); }
3. 使用System.Text.Json(.NET Core/.NET 5+内置)
如果使用.NET内置的System.Text.Json,可以通过配置JsonTypeInfo实现需求:
全局配置示例(Program.cs)
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver { Modifiers = { typeInfo => { if (typeInfo.Type == typeof(PlayerProfile)) { // 移除PasswordHash的序列化逻辑 var hashProp = typeInfo.Properties.FirstOrDefault(p => p.Name == nameof(PlayerProfile.PasswordHash)); if (hashProp != null) hashProp.ShouldSerialize = (_, __) => false; // 移除PasswordSalt的序列化逻辑 var saltProp = typeInfo.Properties.FirstOrDefault(p => p.Name == nameof(PlayerProfile.PasswordSalt)); if (saltProp != null) saltProp.ShouldSerialize = (_, __) => false; } } } }; });
配置后,所有返回PlayerProfile的接口都会自动忽略这两个敏感属性,同时不影响对象的初始化赋值。
内容的提问来源于stack exchange,提问作者Falcon Stakepool
相关产品推荐
相关产品推荐

