如何在REST API中按CRUD接口类型条件隐藏模型的ResourceId属性
解决方案
方案一:拆分请求/响应模型(推荐)
这是REST API开发中最清晰、最符合单一职责原则的做法,完全避免属性读写规则冲突:
- 创建
CreateResourceRequest:仅包含客户端需要传入的字段,不包含ResourceIdpublic class CreateResourceRequest { public string FirstName { get; set; } public string LastName { get; set; } public string ResourceTypeName { get; set; } public string ResourceStatusName { get; set; } } - 创建
ResourceResponse:包含所有需要返回给客户端的字段,包括ResourceIdpublic class ResourceResponse { public int ResourceId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string ResourceTypeName { get; set; } public string ResourceStatusName { get; set; } } - 原有的
ResourceDto可保留作为领域模型与这两个模型的转换载体,或直接调整转换逻辑在请求/响应模型和ResourceModel之间完成映射。
这种方案的优势是模型职责明确,后续扩展字段时不会出现读写规则混淆的问题,维护成本更低。
方案二:使用[BindNever]控制模型绑定(适用于不想拆分模型的场景)
在ResourceId属性上添加ASP.NET Core的[BindNever]特性,它会告知模型绑定系统忽略客户端传入的该属性值,但不会影响接口返回时的序列化输出:
public class ResourceDto { [BindNever] // 接收请求时忽略该属性,客户端传入也不会被绑定 public int ResourceId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string ResourceTypeName { get; set; } public string ResourceStatusName { get; set; } // 保留原有的隐式转换逻辑 public static implicit operator ResourceModel(ResourceDto resource) { return new ResourceModel() { FirstName = resource.FirstName, LastName = resource.LastName, ResourceType = new ResourceTypeModel() { Name = resource.ResourceTypeName }, ResourceStatus = new ResourceStatusModel() { StatusName = resource.ResourceStatusName } }; } }
注意:该特性仅控制模型绑定环节,无论使用System.Text.Json还是Newtonsoft.Json进行序列化,返回结果中都会正常包含ResourceId。
方案三:使用Json序列化条件控制
如果项目基于.NET 5+并使用System.Text.Json,可以通过[JsonIgnore]的Condition参数,指定仅在反序列化(读取请求)时忽略该属性:
using System.Text.Json.Serialization; public class ResourceDto { [JsonIgnore(Condition = JsonIgnoreCondition.WhenReading)] // 反序列化时忽略,序列化时保留 public int ResourceId { get; set; } // 其他属性... }
若使用Newtonsoft.Json,可通过自定义ContractResolver实现类似逻辑,但配置相对繁琐,不如前两种方案直接高效。
内容的提问来源于stack exchange,提问作者USMC6072
相关产品推荐
相关产品推荐

