将SortedList序列化为对象数组并移除键/值



我试图将JSON序列化为没有键/值的正常格式,但不幸的是,所提供的类将键和值字符串添加到JSON文件中。这是我的张贴方法:

[TestMethod]
public void PostTest()
{
var request = new HttpRequestMessage();
request.Headers.Add("X-My-Header", "success");
MyCaseRequest data = new MyCaseRequest()
{
Name = "TestAgre",
ExpirationDateTime = "2016-07-14T00:00:00.000Z",
Signatories = new List<SignatoryRequest>
{
new MyRequest() { Type = MyType.Comp, Id = "11111" },
new MyRequest() { Type = MyType.Per, Id = "2222" }
},
Documents = new SortedList<string, ThingsRequest>()
{
{"0" , new ThingsRequest() { Name = "Test",  Description = "Short description about", Length = 4523 }},
{"1" , new ThingsRequest() { Name = "Test1",  Description = "short description about", Length = 56986 }}
}
};
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new DictionaryAsArrayResolver();
settings.Formatting = Formatting.Indented;
string json = JsonConvert.SerializeObject(data, settings);
var statusCode = sendJsonDemo.SendJsonDemo(json);
}

这是我的类,它将排序后的字典序列化为对象数组:

class DictionaryAsArrayResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
if (objectType.GetInterfaces().Any(i => i == typeof(IDictionary) ||
(i.IsGenericType &&
i.GetGenericTypeDefinition() == typeof(IDictionary<,>))))
{
return base.CreateArrayContract(objectType);
}
return base.CreateContract(objectType);
}
}

这是我的输出:

{
"Name": "TestAgreement",
"ExpirationDateTime": "2016-07-14T00:00:00.000Z",
"Signatories": [
{
"Type": "Comp",
"Id": "11111"
},
{
"Type": "Per",
"Id": "2222"
}
],
"Documents": [
{
"Key": "0",
"Value": {
"Name": "Test",
"Description": "Short description about",
"Length": 4523
}
},
{
"Key": "1",
"Value": {
"Name": "Test1",
"Description": "short description about",
"Length": 56986
}
}
],
"Metadata": []
}

您必须将Documents属性更改为IEnumerable<ThingsRequest>,这样它就不会有键/值。

如果您有一个SortedList作为输入,则可以将其作为一个简单的IEnumerable<ThingsRequest>(但仍然是有序的):Documents.Values

我不确定您希望得到什么JSON,因为您在问题中没有向我们展示。你说你想要"没有键/值的正常格式",这有点模糊。SortedList<K, V>实现IDictionary<K, V>,字典的"正常"序列化格式如下:

{
"Documents": {
"0": {
"Name": "Test",
"Description": "Short description about",
"Length": 4523
},
"1": {
"Name": "Test1",
"Description": "short description about",
"Length": 56986
}
}
}

在您的代码中,您正在使用一个自定义解析器将所有字典的约定更改为JsonArrayContract。这个命令告诉Json.Net将SortedList串行化为键-值对的数组,这正是您在输出中获得"key"one_answers"value"属性的原因。如果您想要"正常"输出,那么不要使用冲突解决程序来更改合同。

然而,我怀疑您真正想要的只是一个简单的项目阵列,就像您使用常规List<T>:一样

{
"Documents": [
{
"Name": "Test",
"Description": "Short description about",
"Length": 4523
},
{
"Name": "Test1",
"Description": "short description about",
"Length": 56986
}
]
}

如果是这样,您可以使用自定义JsonConverter而不是解析器来获得此输出。以下是转换器所需的代码:

class DictionaryToValuesArrayConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(IDictionary).IsAssignableFrom(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
IDictionary dict = (IDictionary)value;
JArray array = JArray.FromObject(dict.Values);
array.WriteTo(writer);
}
public override bool CanRead
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

注意:这个转换器只处理序列化,不处理反序列化。如果您需要进行完整的往返,您还需要实现ReadJson,这超出了本答案的范围

要使用转换器,请将其添加到JsonSerializerSettings:中的Converters集合

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new DictionaryToValuesArrayConverter());
string json = JsonConvert.SerializeObject(data, settings);

演示小提琴:https://dotnetfiddle.net/HFeXLC

相关内容

  • 没有找到相关文章

最新更新