ASP.NET OData中[NotMapped]属性未在JSON中显示的问题
我来帮你排查这个困扰你的问题——明明给模型加了非数据库属性ForeignStudentCount,也试了各种注解,但JSON里就是看不到它。结合你的代码来看,大概率是OData的序列化规则或者模型配置出了问题,咱们一步步来调整:
1. 优先检查EDM模型是否包含该属性
OData的序列化完全依赖EDM模型来决定哪些属性要暴露给客户端,哪怕你加了[NotMapped],如果EDM里没把这个属性加进去,序列化时就会直接忽略它。
你需要在WebApi的配置类(比如WebApiConfig.cs或者Program.cs)里,显式把这个非映射属性添加到实体模型中:
var builder = new ODataConventionModelBuilder(); builder.EntitySet<Etudiant>("Etudiant"); // 关键:手动添加非数据库属性到EDM模型 builder.EntityType<Etudiant>().Property(e => e.ForeignStudentCount); config.MapODataServiceRoute("ODataRoute", null, builder.GetEdmModel());
2. 调整数据注解的组合方式
你之前单独用[DataMember]或[JsonProperty]可能没生效,因为OData序列化优先遵循DataContract体系的规则,试试给整个类加上[DataContract],再给需要序列化的属性标记[DataMember]:
[Table("Etudiant")] [DataContract] // 必须添加这个类级注解 public partial class Etudiant { [DataMember] public int StudentID { get; set; } [StringLength(128)] [IgnoreDataMember] // 不需要序列化的属性用这个 public string UserID { get; set; } [DataMember] public int? Age { get; set; } [StringLength(15)] [DataMember] public string CodeName { get; set; } [NotMapped] [DataMember] // 给非映射属性加上这个 public int? ForeignStudentCount { get; set; } }
如果你的项目用的是System.Text.Json而非Newtonsoft.Json,那[JsonProperty]要换成[JsonPropertyName](来自System.Text.Json.Serialization命名空间)。
3. 确认控制器中属性的赋值逻辑
再检查下GetStudent方法里的赋值代码,确保你真的给ForeignStudentCount赋了有效值:
[EnableQuery] [Authorize(Roles = "Admin")] public Etudiant GetStudent([FromODataUri] int key) { var student = db.Student.Find(key); if (student != null) { // 这里要确保赋值逻辑正确,比如从其他表统计或者计算 student.ForeignStudentCount = 你的统计/计算结果; } return student; }
如果student为空,或者赋值逻辑出错,属性自然不会在JSON里显示。
4. 排查OData版本和序列化配置
如果是较新的OData版本,默认可能用System.Text.Json序列化,这时候要确保没有在配置中禁用非映射属性的序列化。另外,也可以检查是否有自定义的OData序列化器,不小心过滤了这个属性。
内容的提问来源于stack exchange,提问作者Noah13

