自定义服务堆栈中的序列化/序列化JSON

时间:2013-04-12 01:52:14

标签: json servicestack

我需要从服务栈中转换这个美丽的默认JSON:

{
      "Status": "ok",
      "LanguageArray": [{
      "Id": 1,
      "Name": "English"
      }, {
      "Id": 2,
      "Name": "Chinese"
      }, {
      "Id": 3,
      "Name": "Portuguese"
      }]
     }

这种憎恶的怪物:

{"status":"ok","language":{
     "0":{"id":"1", "name":"English"},
     "1":{"id":"2", "name":"Chinese"},
     "2":{"id":"3", "name":"Portuguese"},
     }

由于我无法控制或理性或逻辑的原因。

我的问题是实现这一目标的最简单方法是什么? 我需要对几乎所有的数组执行此操作(它们是使用C#中的List实现的IEnumerables)

1 个答案:

答案 0 :(得分:4)

我认为我没有“最简单的方法”,这取决于您需要序列化发生的位置以及格式的严格程度(区分大小写?间距?)

如果放置示例文本并将其转换为类似

的类
public class Language
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class OuterLanguage
{
    public string Status { get; set; }
    public IEnumerable<Language> LanguageArray { get; set; }
}

一种非常简单的方法是使用Dto为Array的序列化添加属性并忽略原始Array。

public class OuterLanguageDto
{
    public string Status { get; set; }
    [IgnoreDataMember]
    public IEnumerable<Language> LanguageArray { get; set; }
    public IDictionary<string, Language> language 
    { 
        get { return this.LanguageArray.ToDictionary(x => (x.Id - 1).ToString()); } 
    }
}

当您需要序列化您的类(OuterLanguage)时,您可以使用TranslateTo(或您首选的Mapper)并将值复制到Dto。

var jsonObj = obj.TranslateTo<OuterLanguageDto>();
var jsonStr = new JsonSerializer<OuterLanguageDto>().SerializeToString(jsonObj);

您还可以查看Custom Serialization。这将使您有办法将所有阵列序列化为正确的格式。

JsConfig<IEnumerable<Language>>.SerializeFn = ToJson

private string ToJson(IEnumerable<Language> arr)
{
    var dict = arr.ToDictionary(x => x.Id - 1);

    var str = JsonSerializer.SerializeToString<Dictionary<int, Language>>(dict);

    return str;
}

但是,我猜你可能不得不做一些“魔术字符串工作”来获取你的自定义序列化数组的json字符串并在外部类(本例中为OuterLanguage)被序列化时正确格式化。