问题描述
我正在尝试使用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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!