Json自定义媒体类型的序列化,数据不会被反序列化



嘿,我正在尝试反序列化某些服务发送到我的端点的 json 流。 问题是此服务向我发送具有自定义媒体类型的数据,即:

application/vnd.docker.distribution.manifest.v2+json

例如,我从内存中捕获然后保存在文件中的流:

{
"events": [
{
"id": "7a604759-812c-421a-a182-3928b9eb66d6",
"timestamp": "2018-07-03T09:04:37.617519518Z",
"action": "push",
"target": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 1375,
"digest": "sha256:3ecc4d1b70b0c590284d24e6a8738981567bc54896ea03d4aa4a494eeeecc25a",
"length": 1375,
"repository": "microsoft",
"url": "http://localhost:5000/v2/microsoft/manifests/sha256:3ecc4d1b70b0c590284d24e6a8738981567bc54896ea03d4aa4a494eeeecc25a",
"tag": "latest"
},
"request": {
"id": "6189c2c2-5b57-4970-9538-038b39fb22d2",
"addr": "172.19.0.1:39304",
"host": "localhost:5000",
"method": "PUT",
"useragent": "docker/18.03.1-ce go/go1.9.5 git-commit/9ee9f40 kernel/4.9.0-6-amd64 os/linux arch/amd64 UpstreamClient(Docker-Client/18.03.1-ce \(linux\))"
},
"actor": {},
"source": {
"addr": "b6203bc638de:5000",
"instanceID": "375af6b0-42ff-4efd-a8c2-4f4c8b0edb35"
}
}
]
}

以下是我想反序列化我的流的类:

[DataContract]
public class Ev
{
[DataMember]
public IList<Event> Events { get; set; }
}
[DataContract]
public class Event
{
[DataMember]
public Guid Id { get; set; }
[DataMember]
public DateTime Timestamp { get; set; }
[DataMember]
public string Action { get; set; }
}

我作为新的输入格式化程序创建的反序列化方法

if (contentType == "application/vnd.docker.distribution.events.v1+json")
{
using (var ms = new MemoryStream(2048))
{
await request.Body.CopyToAsync(ms);
var content = ms.ToArray();
File.WriteAllBytes("test.txt", content);
ms.Position = 0;
try
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Ev));
Ev ev = (Ev) ser.ReadObject(ms);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}

return await InputFormatterResult.SuccessAsync(content);
}
}

问题是 ev 的事件属性为空,我想知道为什么。我的反序列化是否未正确启动?

你可以对你的 json 使用扩展 Paste JSON as Code in in VSCode 中,这将生成这样的类文件:

// Generated by https://quicktype.io
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class TopLevel
{
[JsonProperty("events")]
public Event[] Events { get; set; }
}
public partial class Event
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("timestamp")]
public DateTimeOffset Timestamp { get; set; }
[JsonProperty("action")]
public string Action { get; set; }
[JsonProperty("target")]
public Target Target { get; set; }
[JsonProperty("request")]
public Request Request { get; set; }
[JsonProperty("actor")]
public Actor Actor { get; set; }
[JsonProperty("source")]
public Source Source { get; set; }
}
public partial class Actor
{
}
public partial class Request
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("addr")]
public string Addr { get; set; }
[JsonProperty("host")]
public string Host { get; set; }
[JsonProperty("method")]
public string Method { get; set; }
[JsonProperty("useragent")]
public string Useragent { get; set; }
}
public partial class Source
{
[JsonProperty("addr")]
public string Addr { get; set; }
[JsonProperty("instanceID")]
public string InstanceId { get; set; }
}
public partial class Target
{
[JsonProperty("mediaType")]
public string MediaType { get; set; }
[JsonProperty("size")]
public long Size { get; set; }
[JsonProperty("digest")]
public string Digest { get; set; }
[JsonProperty("length")]
public long Length { get; set; }
[JsonProperty("repository")]
public string Repository { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("tag")]
public string Tag { get; set; }
}
public partial class TopLevel
{
public static TopLevel FromJson(string json) => JsonConvert.DeserializeObject<TopLevel>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this TopLevel self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters = {
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
}

然后,这应该使用Newtonsoft正确序列化/反序列化。

要与 DataContractJsonSerializer 一起使用,您可以对其进行一些修改以获得:

using System;
using System.Collections.Generic;
using System.Globalization;
namespace YourApp
{
[DataContract]
public class Ev
{
[DataMember(Name = "events")]
public IList<Event> Events { get; set; }
}
[DataContract]
public class Event
{
[DataMember(Name ="id")]
public string Id { get; set; }
[DataMember(Name ="timestamp")]
public DateTimeOffset Timestamp { get; set; }
[DataMember(Name ="action")]
public string Action { get; set; }
[DataMember(Name ="target")]
public Target Target { get; set; }
[DataMember(Name ="request")]
public Request Request { get; set; }
[DataMember(Name ="actor")]
public object Actor { get; set; }
[DataMember(Name ="source")]
public Source Source { get; set; }
}
[DataContract]
public class Request
{
[DataMember(Name ="id")]
public string Id { get; set; }
[DataMember(Name = "addr")]
public string Addr { get; set; }
[DataMember(Name = "host")]
public string Host { get; set; }
[DataMember(Name = "method")]
public string Method { get; set; }
[DataMember(Name = "useragent")]
public string Useragent { get; set; }
}
[DataContract]
public class Source
{
[DataMember(Name = "addr")]
public string Addr { get; set; }
[DataMember(Name = "instanceID")]
public string InstanceId { get; set; }
}
[DataContract]
public class Target
{
[DataMember(Name = "mediaType")]
public string MediaType { get; set; }
[DataMember(Name = "size")]
public long Size { get; set; }
[DataMember(Name = "digest")]
public string Digest { get; set; }
[DataMember(Name = "length")]
public long Length { get; set; }
[DataMember(Name = "repository")]
public string Repository { get; set; }
[DataMember(Name = "url")]
public string Url { get; set; }
[DataMember(Name = "tag")]
public string Tag { get; set; }
}
}

看看该类是否有效。

最新更新