如何使用YamlDotNet将JSON转换为YAML [英] How to convert JSON to YAML using YamlDotNet

查看:116
本文介绍了如何使用YamlDotNet将JSON转换为YAML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用YamlDotNet将JSON转换为YAML.这是我的代码:

I am trying to convert JSON to YAML using YamlDotNet. This is the code I have:

class Program
{
    static void Main(string[] args)
    {
        var json = "{\"swagger\":\"2.0\",\"info\":{\"title\":\"UberAPI\",\"description\":\"MoveyourappforwardwiththeUberAPI\",\"version\":\"1.0.0\"},\"host\":\"api.uber.com\",\"schemes\":[\"https\"],\"basePath\":\"/v1\",\"produces\":[\"application/json\"]}";
        var swaggerDocument = JsonConvert.DeserializeObject(json);

        var serializer = new YamlDotNet.Serialization.Serializer();

        using (var writer = new StringWriter())
        {
            serializer.Serialize(writer, swaggerDocument);
            var yaml = writer.ToString();
            Console.WriteLine(yaml);
        }
    }
}

这是我提供的JSON:

This is the JSON I provide:

{
   "swagger":"2.0",
   "info":{
      "title":"UberAPI",
      "description":"MoveyourappforwardwiththeUberAPI",
      "version":"1.0.0"
   },
   "host":"api.uber.com",
   "schemes":[
      "https"
   ],
   "basePath":"/v1",
   "produces":[
      "application/json"
   ]
}

这是我期望的YAML:

This is the YAML I expect:

swagger: '2.0'
info:
  title: UberAPI
  description: MoveyourappforwardwiththeUberAPI
  version: 1.0.0
host: api.uber.com
schemes:
  - https
basePath: /v1
produces:
  - application/json

但是,这是我得到的输出:

However, this is the output I get:

swagger: []
info:
  title: []
  description: []
  version: []
host: []
schemes:
- []
basePath: []
produces:
- []

我不知道为什么所有属性都是空数组.

I don't have a clue why all properties are empty arrays.

我还尝试过像这样的类型化反序列化和序列化:

I also tried typed deserialization and serialization like this:

var specification = JsonConvert.DeserializeObject<SwaggerDocument>(json);
...
serializer.Serialize(writer, swaggerDocument, typeof(SwaggerDocument));

但是会产生

{}

非常感谢您的帮助.

推荐答案

我认为json反序列化返回JObject时出现问题.看起来yaml序列化器不喜欢它.

I think there is problem when json deserialization returns JObject. Looks like yaml serializer doesn't like it.

正如您提到的JsonConvert.DeserializeObject<SwaggerDocument>(json)所示,我使用了指定类型的反序列化,这就是我得到的

I used deserialization with specified type as you mentioned JsonConvert.DeserializeObject<SwaggerDocument>(json) and this is what I get

Swagger: 2.0
Info:
  Title: UberAPI
  Description: MoveyourappforwardwiththeUberAPI
  Version: 1.0.0
Host: api.uber.com
Schemes:
- https
BasePath: /v1
Produces:
- application/json

这是我的完整代码:

class Program
{
    static void Main(string[] args)
    {
        var json = "{\"Swagger\":\"2.0\",\"Info\":{\"Title\":\"UberAPI\",\"Description\":\"MoveyourappforwardwiththeUberAPI\",\"Version\":\"1.0.0\"},\"Host\":\"api.uber.com\",\"Schemes\":[\"https\"],\"BasePath\":\"/v1\",\"Produces\":[\"application/json\"]}";
        var swaggerDocument = JsonConvert.DeserializeObject<SwaggerDocument>(json);
        
        var serializer = new YamlDotNet.Serialization.Serializer();

        using (var writer = new StringWriter())
        {
            serializer.Serialize(writer, swaggerDocument);
            var yaml = writer.ToString();
            Console.WriteLine(yaml);
        }
    }
}

public class Info
{
    public string Title { get; set; }
    public string Description { get; set; }
    public string Version { get; set; }
}

public class SwaggerDocument
{
    public string Swagger { get; set; }
    public Info Info { get; set; }
    public string Host { get; set; }
    public List<string> Schemes { get; set; }
    public string BasePath { get; set; }
    public List<string> Produces { get; set; }
}

更新

这里有两个问题.

在使用字段反序列化类时,默认情况下,json.net在执行此工作时不会考虑它们.为此,我们必须通过创建自定义合同解析器来自定义反序列化过程.我们可以通过

When deserializing class with fields, by default, json.net won't take them into consideration when doing this job. For this purpose we have to customize the deserialization process by creating a custom contract resolver. We can easily do this by

var swaggerDocument = JsonConvert.DeserializeObject<SwaggerDocument>(json, new JsonSerializerSettings
{
    ContractResolver = new MyContractResolver()
});

public class MyContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Select(p => base.CreateProperty(p, memberSerialization))
            .Union(type.GetFields(BindingFlags.Public | BindingFlags.Instance)
                .Select(f => base.CreateProperty(f, memberSerialization)))
            .ToList();
        props.ForEach(p => { p.Writable = true; p.Readable = true; });
        return props;
    }
}

当我们要使用字段序列化类时,存在第二个问题:yaml结果中将不包含来自字段的值.我还没有弄清楚该如何处理.

There is second issue when we want to serialize class with fields: Values from fields won't be included into yaml result. I haven't figured out how to deal with this yet.

您是否必须使用Swashbuckle.Swagger类型,还是可以为此类型创建包装器/装饰器/DTO?

Do you have to use Swashbuckle.Swagger type or you can just create wrapper/decorator/DTO for this type?

希望对您有帮助.

这篇关于如何使用YamlDotNet将JSON转换为YAML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆