ven*_*rik 6 c# json yaml yamldotnet
我正在尝试使用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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我提供的JSON:
{
"swagger":"2.0",
"info":{
"title":"UberAPI",
"description":"MoveyourappforwardwiththeUberAPI",
"version":"1.0.0"
},
"host":"api.uber.com",
"schemes":[
"https"
],
"basePath":"/v1",
"produces":[
"application/json"
]
}
Run Code Online (Sandbox Code Playgroud)
这是我期待的YAML:
swagger: '2.0'
info:
title: UberAPI
description: MoveyourappforwardwiththeUberAPI
version: 1.0.0
host: api.uber.com
schemes:
- https
basePath: /v1
produces:
- application/json
Run Code Online (Sandbox Code Playgroud)
但是,这是我得到的输出:
swagger: []
info:
title: []
description: []
version: []
host: []
schemes:
- []
basePath: []
produces:
- []
Run Code Online (Sandbox Code Playgroud)
我不知道为什么所有属性都是空数组.
我也尝试过类似的反序列化和序列化,如下所示:
var specification = JsonConvert.DeserializeObject<SwaggerDocument>(json);
...
serializer.Serialize(writer, swaggerDocument, typeof(SwaggerDocument));
Run Code Online (Sandbox Code Playgroud)
但那会产生
{}
Run Code Online (Sandbox Code Playgroud)
任何帮助深表感谢.
您实际上不需要将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<ExpandoObject>(json, expConverter);
var serializer = new YamlDotNet.Serialization.Serializer();
string yaml = serializer.Serialize(deserializedObject);
Run Code Online (Sandbox Code Playgroud)
你可以看到这两种方法的详细说明,即使用强类型的对象和动态对象在这里.
您可以将 转换为JObjectYamlDotNet 可以序列化的更简单的对象:
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<JToken>(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<JProperty>().ToDictionary(x => x.Name, x => ConvertJTokenToObject(x.Value));
throw new InvalidOperationException("Unexpected token: " + token);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为json反序列化返回时存在问题JObject。看起来 yaml 序列化器不喜欢它。
正如您提到的,我使用了指定类型的反序列化JsonConvert.DeserializeObject<SwaggerDocument>(json),这就是我得到的
Swagger: 2.0
Info:
Title: UberAPI
Description: MoveyourappforwardwiththeUberAPI
Version: 1.0.0
Host: api.uber.com
Schemes:
- https
BasePath: /v1
Produces:
- application/json
Run Code Online (Sandbox Code Playgroud)
这是我的整个代码:
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; }
}
Run Code Online (Sandbox Code Playgroud)
更新
这里有两个问题。
当使用字段反序列化类时,默认情况下,json.net在执行此工作时不会考虑它们。为此,我们必须通过创建自定义合约解析器来自定义反序列化过程。我们可以很容易地做到这一点
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;
}
}
Run Code Online (Sandbox Code Playgroud)
当我们想要使用字段序列化类时,存在第二个问题:字段中的值不会包含在 yaml 结果中。我还没想好如何处理这个问题。
您是否必须使用Swashbuckle.Swagger类型,或者您可以为此类型创建包装器/装饰器/DTO?
我希望它对你有帮助。
| 归档时间: |
|
| 查看次数: |
3548 次 |
| 最近记录: |