ASP.NET Core中反序列化Umbraco CMS动态JSON对象的问题
解决方案:ASP.NET Core中反序列化Umbraco动态JSON到固定类结构
针对Umbraco返回的动态JSON结构,我们可以利用ASP.NET Core常用的JSON序列化库(System.Text.Json或Newtonsoft.Json),通过配置和特性映射,轻松将动态JSON转换为自定义的固定类结构,自动填充匹配字段、忽略不存在的字段。
一、使用System.Text.Json(ASP.NET Core默认)
System.Text.Json默认支持忽略未知属性,只需简单配置即可适配动态JSON:
1. 基础反序列化配置
创建JsonSerializerOptions,开启大小写不敏感匹配(适配Umbraco JSON中混合的驼峰/帕斯卡命名),并保留空值:
var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, // 忽略属性名大小写差异,匹配header/Header或name/Name IgnoreNullValues = false, // 保留JSON中的null值,不存在的字段会设为类型默认值 IgnoreReadOnlyProperties = false // 确保可读写属性能被填充 }; // 反序列化JSON字符串到自定义类 var myContent = JsonSerializer.Deserialize<MyContentClass>(umbracoJsonResponse, jsonOptions);
2. 属性名映射
如果JSON字段名和类属性名不一致(比如JSON里是title,类里是name),用[JsonPropertyName]特性显式映射:
public class Header { [JsonPropertyName("title")] // 对应JSON中的title字段 public string name; public int? height; // 用可空类型区分"不存在"和"值为0" public List<Property> properties; }
3. 处理动态数组
对于Umbraco返回的不确定结构数组(比如bulletItems),可以先用JsonElement接收原始动态内容,后续按需解析:
public class MyContentClass { public Header header; public Footer footer; public string title; public List<JsonElement> bulletItems; // 先接收动态数组,再逐个解析 }
二、使用Newtonsoft.Json(Json.NET)
若习惯使用Json.NET,其配置更灵活,同样支持忽略未知属性:
1. 基础反序列化设置
var jsonSettings = new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Ignore, // 忽略JSON中不存在的类属性 NullValueHandling = NullValueHandling.Include, // 保留null值 ContractResolver = new DefaultContractResolver { IgnoreCase = true } // 大小写不敏感匹配 }; var myContent = JsonConvert.DeserializeObject<MyContentClass>(umbracoJsonResponse, jsonSettings);
2. 属性名映射
用[JsonProperty]特性实现字段名匹配:
public class Footer { [JsonProperty("Name")] // 对应JSON中的Name字段 public string name; public string content1; public string content2; public List<Property> properties; }
三、进阶:自定义转换器处理复杂嵌套结构
如果Umbraco的JSON嵌套层级极深或结构多变,可自定义JsonConverter手动解析特定类型:
public class PropertyConverter : JsonConverter<Property> { public override Property Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { using var doc = JsonDocument.ParseValue(ref reader); var root = doc.RootElement; var property = new Property(); // 只解析存在的字段,不存在的留空 if (root.TryGetProperty("referenceCacheLevel", out var levelElement)) { property.ReferenceCacheLevel = levelElement.GetString(); } // 解析嵌套的propertyType if (root.TryGetProperty("propertyType", out var propTypeElement)) { property.PropertyType = JsonSerializer.Deserialize<PropertyType>(propTypeElement.GetRawText(), options); } return property; } // 序列化逻辑按需实现,反序列化可忽略 public override void Write(Utf8JsonWriter writer, Property value, JsonSerializerOptions options) { throw new NotImplementedException(); } }
注册转换器后使用:
var jsonOptions = new JsonSerializerOptions(); jsonOptions.Converters.Add(new PropertyConverter()); var myContent = JsonSerializer.Deserialize<MyContentClass>(umbracoJsonResponse, jsonOptions);
四、关键注意事项
- 访问修饰符:确保类的属性/字段为
public,否则序列化工具无法访问赋值。 - 可空类型:用
int?、string?等可空类型,区分“字段不存在”和“字段值为默认值”。 - 根节点匹配:如果Umbraco返回的JSON被
content节点包裹(如第一个示例),需先定义根类接收:public class UmbracoRoot { public MyContentClass Content { get; set; } } var umbracoRoot = JsonSerializer.Deserialize<UmbracoRoot>(umbracoJsonResponse, jsonOptions); var myContent = umbracoRoot.Content;
内容的提问来源于stack exchange,提问作者Rich
相关产品推荐
相关产品推荐

