2017-01-03 81 views
1

我想将JSON序列化为没有键/值的正常格式,但不幸的是提供的类向JSON文件添加了键和值字符串。 这是帖子的方法:序列化SortedList到对象数组并删除键/值

[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": [] 
} 
+0

看起来这是不是真的ASP.NET特有的,所以它如果你能提供一个[mcve]控制台应用程序让我们重现问题,那将是最好的。接下来,你已经显示了你*的输出*,这是有意义的,因为'SortedList'是一个键/值映射,按键排序。你认为它只是JSON数组吗?如果是这样,你应该使用'List <>'而不是'SortedList <,>'。 –

回答

1

你必须将Documents属性更改为IEnumerable<ThingsRequest>,以便它不具有键/值。

如果你有一个SortedList作为输入,你可以这样做得到它作为一个简单的IEnumerable<ThingsRequest>(但仍然有序):Documents.Values

+0

嗯,我已经尝试过了,但不幸的是它没有工作,IEnumerable中有JSON文件中的键和值字符串。 – BinaryTie

+0

我在自己的项目中使用它,并且没有关键值。你确定要序列化文档吗?价值“或类似的东西,而不是你的OrderedList? – Floc

0

我不确定你期望得到什么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”和“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,这超出了本答案的范围。

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

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

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