如何使用YamlDotNet将JSON转换为YAML

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

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:

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

这是我期待的YAML:

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

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

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

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

我也尝试过类似的反序列化和序列化,如下所示:

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

但那会产生

 {} 

任何帮助深表感谢。

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

当你提到JsonConvert.DeserializeObject(json) ,我使用了指定类型的反序列化,这就是我得到的

 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(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 Schemes { get; set; } public string BasePath { get; set; } public List Produces { get; set; } } 

更新

这里有两个问题。

使用字段反序列化类时,默认情况下json.net在执行其工作时不会考虑它们。 为此,我们必须通过创建自定义合约解析程序来自定义反序列化过程。 我们可以轻松地做到这一点

 var swaggerDocument = JsonConvert.DeserializeObject(json, new JsonSerializerSettings { ContractResolver = new MyContractResolver() }); public class MyContractResolver : DefaultContractResolver { protected override IList 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结果中。 我还没想办法解决这个问题。

你必须使用Swashbuckle.Swagger类型,或者你可以为这种类型创建包装/装饰/ DTO?

我希望它对你有所帮助。

实际上,您不需要将JSON反序列化为强类型对象,也可以使用动态Expando对象将JSON转换为YAML。 这是一个小例子: –

 var json = @"{ 'Name':'Peter', 'Age':22, 'CourseDet':{ 'CourseName':'CS', 'CourseDescription':'Computer Science', }, 'Subjects':['Computer Languages','Operating Systems'] }"; var expConverter = new ExpandoObjectConverter(); dynamic deserializedObject = JsonConvert.DeserializeObject(json, expConverter); var serializer = new YamlDotNet.Serialization.Serializer(); string yaml = serializer.Serialize(deserializedObject); 

您可以在这里看到两种方法的详细说明,即使用强类型对象和动态对象。

您可以将JObject转换为YamlDotNet可以序列化的更简单的对象:

 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 = ConvertJTokenToObject(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); } } static object ConvertJTokenToObject(JToken token) { if (token is JValue) return ((JValue)token).Value; if (token is JArray) return token.AsEnumerable().Select(ConvertJTokenToObject).ToList(); if (token is JObject) return token.AsEnumerable().Cast().ToDictionary(x => x.Name, x => ConvertJTokenToObject(x.Value)); throw new InvalidOperationException("Unexpected token: " + token); } }