c# - 将嵌套在动态对象中的 C# 列表中的第一项和最后一项序列化为 JSON
问题描述
我有一个类需要将任何类型的对象序列化为 JSON。如果对象具有一个或多个类型为列表的属性,我想序列化整个对象,但只序列化列表中的第一个和最后一个项目。
例如,我有以下代码
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections;
using Newtonsoft.Json.Serialization;
using System.Linq;
using Newtonsoft.Json.Linq;
public class Program
{
public class Product{
public Product(string name, int price){
this.Name = name;
this.Price = price;
}
public string Name {get;set;}
public int Price {get;set;}
}
public class ProductResult{
public ProductResult(List<Product> products, int code){
this.Products = products;
this.Code = code;
}
public int Code {get;set;}
public List<Product> Products {get;set;}
}
public static string DoTheThing(object dynamicObject){
return JsonConvert.SerializeObject(dynamicObject);
}
public static void Main()
{
var list = new List<Product>(){new Product("product1",100),new Product("product2",100),new Product("product3",100),new Product("product4",100)};
var result = new ProductResult(list,0);
string jsonObj = DoTheThing(result);
Console.WriteLine(jsonObj);
// Output {"Code":0,"Products":[{"Name":"product1","Price":100},{"Name":"product2","Price":100},{"Name":"product3","Price":100},{"Name":"product4","Price":100}]}
}
}
我希望它输出以下内容,并且我需要它能够处理各种对象类型。
{"Code":0,"Products":[{"Name":"product","Price":100},{"Name":"product","Price":100}]}
我查看了使用Custom JsonConverter和Custom ContractResolver但不确定如何实现这些。
解决方案
您可以将 aCustom ContractResolver
与 a 一起使用ValueConverter
。例如,
public class ListContractResolver : DefaultContractResolver
{
public new static readonly ListContractResolver Instance = new ListContractResolver ();
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (property.PropertyType.IsGenericType && property.PropertyType.GetInterfaces().Contains(typeof(IList)))
{
property.ValueProvider = new FilterListValueProvider(member as PropertyInfo);
}
return property;
}
}
public class FilterListValueProvider : IValueProvider
{
PropertyInfo _propertyInfo;
public FilterListValueProvider(PropertyInfo propertyInfo)
{
_propertyInfo = propertyInfo;
}
public object GetValue(object target)
{
return GetList(target);
}
public IEnumerable GetList(object target)
{
var list = _propertyInfo.GetValue(target) as IList;
yield return list[0];
yield return list[list.Count - 1];
}
public void SetValue(object target, object value)
{
_propertyInfo.SetValue(target, value);
}
}
更新您的DoTheThing
方法以使用ListContractResolver
我们定义为
public static string DoTheThing(object dynamicObject)
{
return JsonConvert.SerializeObject(dynamicObject,
Newtonsoft.Json.Formatting.Indented,
new JsonSerializerSettings
{ ContractResolver = new ListContractResolver() });
}
样本输出
{
"Code": 0,
"Products": [
{
"Name": "product1",
"Price": 100
},
{
"Name": "product4",
"Price": 100
}
]
}
推荐阅读
- kubernetes - 如何通过 helm 模板使用 kubernetes 密封的秘密
- blazorise - 使用 Blazorise 将工具栏最后一个元素向右对齐
- node.js - @google-cloud/iot API 有真实的文档吗?
- python - 抓取时如何解决Python字符串超出范围
- c++ - 为什么我的 C++ 应用程序消耗太多系统资源而没有响应?
- postgresql - AuthenticationTicket byte[] 值在服务器重新启动时无法反序列化
- angular - 在 Angular 中创建一个可观察的 Dictionary/HashMap(或 KeyValue 对)?
- php - Laravel:尝试访问 null 类型值的数组偏移量
- python - 如何在数据框中将值 1 和 2 更改为女性和男性?
- javascript - 根据 startdtate 和当前工作对数组进行排序或不