C# 反序列化mimekit.MimeMessage对象
我对序列化为JSON字符串并存储在redis键值缓存中的mimeKit.mimeMessage进行反序列化时遇到一些问题 我能够使用json.NET或Jil成功地序列化和存储mimessage,但是当我转到反序列化时,会抛出以下错误 由json.NET抛出 找不到用于类型MimeKit.Header的构造函数。一个类应该有一个默认构造函数、一个带参数的构造函数或一个标记有JsonConstructor属性的构造函数。路径“头[0]。偏移量”,第1行,位置22 我使用StackExchange.Redis方法stringGet获取序列化对象,然后将RedisValue传递到Json.Net;下面的代码片段:C# 反序列化mimekit.MimeMessage对象,c#,json,json.net,mimekit,C#,Json,Json.net,Mimekit,我对序列化为JSON字符串并存储在redis键值缓存中的mimeKit.mimeMessage进行反序列化时遇到一些问题 我能够使用json.NET或Jil成功地序列化和存储mimessage,但是当我转到反序列化时,会抛出以下错误 由json.NET抛出 找不到用于类型MimeKit.Header的构造函数。一个类应该有一个默认构造函数、一个带参数的构造函数或一个标记有JsonConstructor属性的构造函数。路径“头[0]。偏移量”,第1行,位置22 我使用StackExchange.R
RedisValue result = db.StringGet(key);
MimeMessage message = new MimeMessage();
message = JsonConvert.DeserializeObject<MimeMessage>(result);
RedisValue结果=db.StringGet(键);
MimeMessage message=新的MimeMessage();
message=JsonConvert.DeserializeObject(结果);
我的理解是,默认构造函数总是被创建的,这让我很难理解,默认构造函数是否可以被指定为私有的,如果是,为什么
我还检查了返回的JSON字符串的格式,它是正确的
谢谢您的帮助。首先,要解决一些问题: 我的理解是,默认构造函数总是被创建的,这让我很难理解,默认构造函数是否可以被指定为私有的,如果是,为什么 那不是真的。当您定义一个没有构造函数的类时,会为您生成一个默认的、没有参数的构造函数。如果提供构造函数,则不再生成此默认构造函数。换句话说,类可能没有默认构造函数
考虑到这一点,
MimeKit.Header
类提供了6个构造函数,其中没有一个不带参数。因此,JSON.NET不知道如何实例化这个类,这就是为什么会发生异常
由于您无法控制MimeKit.Header
类,因此让JSON.NET知道如何构造Header
实例的一种方法是使用自定义转换器:
public class MimeHeaderConverter : JsonConverter
{
public override object ReadJson(
JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
{
JObject obj = serializer.Deserialize<JObject>(reader);
HeaderId headerId = obj["Id"].ToObject<HeaderId>();
Header header = new Header(headerId, obj["Value"].ToObject<string>());
return header;
}
public override void WriteJson(
JsonWriter writer,
object value,
JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanConvert(Type t)
{
return typeof(Header).IsAssignableFrom(t);
}
public override bool CanRead { get { return true; } }
public override bool CanWrite { get { return false; } }
}
这样,我们就不会意外地将这些属性之一的null
传递给setter
这里还有一个注意事项:我注意到,即使我忽略了MimeVersion
和ResentMessageId
标题,如果标题包含MimeVersion
和/或ResentMessageId
标题,它们仍然被设置。我猜这是在MimeMessage
的某个地方烤出来的,但是我对这个库不是很熟悉
因此,要使用上述类(仅在反序列化时),您需要执行以下操作:
string someJsonString = "{ ... }";
MimeMessage deserialized = JsonConvert.DeserializeObject<MimeMessage>(
someJsonString, new JsonSerializerSettings
{
ContractResolver = new MimeMessageContractResolver(),
Converters = new JsonConverter[]
{
new MimeHeaderConverter()
}
});
string someJsonString=“{…}”;
MimeMessage deserialized=JsonConvert.DeserializeObject(
一些JSONString,新的JsonSerializerSettings
{
ContractResolver=新的MIMessageContractResolver(),
转换器=新的JsonConverter[]
{
新的MimeHeaderConverter()
}
});
通过一些基本测试,这似乎效果良好。在实际使用中,您可能会遇到更多问题,因此无法保证
希望这至少能让你开始。我想你可能需要
public override bool CanWrite{get{return false;}}
Wow,感谢你为这个答案付出了这么多的努力,尤其是解释。获取问题的解释而不仅仅是代码片段总是有益的。您将MimeMessage序列化到JSON或从JSON反序列化有什么原因吗?MIME本质上是复合文档的序列化格式,所以这对我来说没有多大意义。您可以使用message.WriteTo()和MimeMessage.Load()进行序列化和反序列化。嘿@jstedfast谢谢您的回复。我不知道mime是连载格式。建议使用writeTo方法写入字符串吗?正如我在问题中所说,我想将消息存储在redis键值缓存中,从我所读到的内容来看,json字符串似乎是实现这一点的首选方法。消息通常有多个字符集,尤其是来自西欧/美国以外的字符集,因此不能用单个字符集表示(因此不可能将它们表示为字符串)。我意识到这是一个相当老的问题,但我需要将它们保存到Mongo,为此我需要转换为字符串。
string someJsonString = "{ ... }";
MimeMessage deserialized = JsonConvert.DeserializeObject<MimeMessage>(
someJsonString, new JsonSerializerSettings
{
ContractResolver = new MimeMessageContractResolver(),
Converters = new JsonConverter[]
{
new MimeHeaderConverter()
}
});