json.net – 如何使用ASP.Net核心ModelMetadata属性
[Table("LegalEntity")] [ModelMetadataType(typeof(LegalEntityMeta))] public class LegalEntity : Entity<long> { } public class LegalEntityMeta { [JsonProperty(PropertyName = "LegalEntityId")] public long Id { get; set; } [JsonProperty(PropertyName = "LegalEntityName")] public string Name { get; set; } } 在Startup.cs …. services .AddCors(options => { options.AddPolicy("CorsPolicy",builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); }) .AddAutoMapper(typeof(Startup)) .AddMvcCore() .AddJsonFormatters() .AddApiExplorer(); 我的期望是看到带有legalEntityId和legalEntityName属性的json,但生成的json有id和name作为属性.
Json.NET目前不支持
Microsoft.AspNetCore.Mvc.ModelMetadataTypeAttribute .在
Issue #1349: Add support for ModelMetadataType for dotnetcore like supported MetadataTypeAttribute in previous versions,实施支持的请求被拒绝.
Json.NET确实支持 [System.ComponentModel.DataAnnotations.MetadataType(typeof(EntityMeta))] public class Entity<T> { public T Id { get; set; } public string Name { get; set; } } public class EntityMeta { [JsonProperty(PropertyName = "LegalEntityId")] public long Id { get; set; } [JsonProperty(PropertyName = "LegalEntityName")] public string Name { get; set; } } 但以下不是: [System.ComponentModel.DataAnnotations.MetadataType(typeof(LegalEntityMeta))] public class LegalEntity : Entity<long> { } public class LegalEntityMeta { [JsonProperty(PropertyName = "LegalEntityId")] public long Id { get; set; } [JsonProperty(PropertyName = "LegalEntityName")] public string Name { get; set; } } 为什么Json.NET不允许派生类型元数据信息来修改基类型契约?你不得不问问牛顿软件,但猜测包括: > Json.NET是一个基于合同的序列化程序,其中每种类型都通过属性指定其合同.并不是说一种类型可以重写第二种类型的合同. 那么,你有什么选择? >您可以序列化DTO代替您的LegalEntity,并使用类似automapper之类的内容进行映射: public class LegalEntityDTO { [JsonProperty(PropertyName = "LegalEntityId")] public long Id { get; set; } [JsonProperty(PropertyName = "LegalEntityName")] public string Name { get; set; } } >您可以使用必要的逻辑为LegalEntity创建custom using System.Reflection; public class ModelMetadataTypeAttributeContractResolver : DefaultContractResolver { public ModelMetadataTypeAttributeContractResolver() { // Default from https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Formatters.Json/JsonSerializerSettingsProvider.cs this.NamingStrategy = new CamelCaseNamingStrategy(); } const string ModelMetadataTypeAttributeName = "Microsoft.AspNetCore.Mvc.ModelMetadataTypeAttribute"; const string ModelMetadataTypeAttributeProperty = "MetadataType"; protected override IList<JsonProperty> CreateProperties(Type type,MemberSerialization memberSerialization) { var properties = base.CreateProperties(type,memberSerialization); var propertyOverrides = GetModelMetadataTypes(type) .SelectMany(t => t.GetProperties()) .ToLookup(p => p.Name,p => p); foreach (var property in properties) { var metaProperty = propertyOverrides[property.UnderlyingName].FirstOrDefault(); if (metaProperty != null) { var jsonPropertyAttribute = metaProperty.GetCustomAttributes<JsonPropertyAttribute>().FirstOrDefault(); if (jsonPropertyAttribute != null) { property.PropertyName = jsonPropertyAttribute.PropertyName; // Copy other attributes over if desired. } } } return properties; } static Type GetModelMetadataType(Attribute attribute) { var type = attribute.GetType(); if (type.FullName == ModelMetadataTypeAttributeName) { var property = type.GetProperty(ModelMetadataTypeAttributeProperty); if (property != null && property.CanRead) { return property.GetValue(attribute,null) as Type; } } return null; } static Type[] GetModelMetadataTypes(Type type) { var query = from t in type.BaseTypesAndSelf() from a in t.GetCustomAttributes(false).Cast<System.Attribute>() let metaType = GetModelMetadataType(a) where metaType != null select metaType; return query.ToArray(); } } public static partial class TypeExtensions { public static IEnumerable<Type> BaseTypesAndSelf(this Type type) { while (type != null) { yield return type; type = type.BaseType; } } } 样品.Net fiddle. 要直接序列化,请执行: var settings = new JsonSerializerSettings { ContractResolver = new ModelMetadataTypeAttributeContractResolver(),}; var json = JsonConvert.SerializeObject(entity,Formatting.Indented,settings); 要将合同解析程序安装到Asp.Net Core,请参阅here. 注意我使用完整的.Net 4.5.1编写了这个,所以它只是一个原型. .Net Core使用different reflection API,但如果您按照here所述安装System.Reflection.TypeExtensions,我相信它应该可行. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |