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

时间:2017-01-03 09:14:13

标签: c# asp.net json json.net

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

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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

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

在您的代码中,您使用自定义解析程序将所有词典的合同更改为JsonArrayContract。这告诉Json.Net将SortedList序列化为一组键值对,这正是你获得&#34; Key&#34;和&#34;价值&#34;输出中的属性。如果你想要&#34;正常&#34;输出,然后不要使用解析器来更改合同。

然而,我怀疑你正在寻找的只是一个简单的项目,就像你会得到普通的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