如何使用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
,我使用了指定类型的反序列化,这就是我得到的
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); } }