Jil Serializer 方法只能在 Type.IsGenericParameter 为真的类型上调用

Jil Serializer Method may only be called on a Type for which Type.IsGenericParameter is true

我有一个自定义日志消息对象,我正在尝试使用 Jil 将其序列化为 JSON 格式。这是我第一次使用 Jil 而不是默认的 JSON.Net 序列化程序,所以我对它不是很熟悉。

日志消息对象的属性之一是异常。当 Exception 属性 为 null 时,Jil 序列化对象没有问题。但是,如果 Exception 对象填充有实际异常,我会从 Jil of Type System.InvalidOperationException.

收到错误

Message: Method may only be called on a Type for which Type.IsGenericParameter is true.

StackTrace: at System.RuntimeType.get_GenericParameterPosition() at _DynamicMethod43(TextWriter , RuntimeType , Int32 ) at Jil.SerializeDynamic.DynamicSerializer.SerializeSemiStatically(MemberInfo dynamicMember, TextWriter stream, Object val, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 237 at Jil.SerializeDynamic.DynamicSerializer.SerializeInternal(MemberInfo dynamicMember, TextWriter stream, Object obj, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 836 at Jil.SerializeDynamic.DynamicSerializer.Serialize(TextWriter stream, Object obj, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 746 at _DynamicMethod40(TextWriter , RuntimeMethodInfo , Int32 )
at Jil.SerializeDynamic.DynamicSerializer.SerializeSemiStatically(MemberInfo dynamicMember, TextWriter stream, Object val, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 237 at Jil.SerializeDynamic.DynamicSerializer.SerializeInternal(MemberInfo dynamicMember, TextWriter stream, Object obj, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 836 at Jil.SerializeDynamic.DynamicSerializer.Serialize(TextWriter stream, Object obj, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 746 at _DynamicMethod23(TextWriter , OperationCanceledException , Int32 ) at Jil.SerializeDynamic.DynamicSerializer.SerializeSemiStatically(MemberInfo dynamicMember, TextWriter stream, Object val, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 237 at Jil.SerializeDynamic.DynamicSerializer.SerializeInternal(MemberInfo dynamicMember, TextWriter stream, Object obj, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 836 at Jil.SerializeDynamic.DynamicSerializer.Serialize(TextWriter stream, Object obj, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 746 at _DynamicMethod4(TextWriter , LogMessage , Int32 ) at Jil.SerializeDynamic.DynamicSerializer.SerializeSemiStatically(MemberInfo dynamicMember, TextWriter stream, Object val, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 237 at Jil.SerializeDynamic.DynamicSerializer.SerializeInternal(MemberInfo dynamicMember, TextWriter stream, Object obj, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 836 at Jil.SerializeDynamic.DynamicSerializer.Serialize(TextWriter stream, Object obj, Options opts, Int32 depth) in c:\Users\kevin_000\Dropbox\jil\Jil\SerializeDynamic\DynamicSerializer.cs:line 746 at Jil.JSON.SerializeDynamic(Object data, TextWriter output, Options options) in c:\Users\kevin_000\Dropbox\jil\Jil\JSON.cs:line 64 at Jil.JSON.SerializeDynamic(Object data, Options options) in c:\Users\kevin_000\Dropbox\jil\Jil\JSON.cs:line 84 at Jil.JSON.Serialize[T](T data, Options options) in c:\Users\kevin_000\Dropbox\jil\Jil\JSON.cs:line 4584 at StackExchange.Redis.Extensions.Jil.JilSerializer.Serialize(Object item) at StackExchange.Redis.Extensions.Jil.JilSerializer.<>c__DisplayClass4_0.b__0() at System.Threading.Tasks.Task`1.InnerInvoke() at System.Threading.Tasks.Task.Execute()

我正在使用以下 Jil 序列化选项:

new Jil.Options(false, true, false, DateTimeFormat.ISO8601, true, UnspecifiedDateTimeKindBehavior.IsUTC, SerializationNameFormat.CamelCase);

我调用Jil的方法是:

public byte[] Serialize(object item)
{
    var jsonString = JSON.Serialize(item);
    return encoding.GetBytes(jsonString);
}

我尝试序列化的完整对象是:

public class LogMessage
{
public LogMessage()
{
    CreatedDate = DateTime.UtcNow;
}

public LogLevel LogLevel { get; set; }
public string Message { get; set; }
public DateTime CreatedDate { get; private set; }
public string AccessToken { get; set; }
public long? ParticipantId { get; set; }
public string UserName { get; set; }
public bool IsAuthenticated { get; set; }
public string Url { get; set; }
public Exception Exception { get; set; }
public string StackTrace { get; set; }
public string Details { get; set; }
public string ClientIpAddress { get; set; }
public string EntryApplication { get; set; }
public string AuthenticationMethod { get; set; }
public string AuthenticationClientId { get; set; }
public string LoggingApplication { get; set; }

[Description("This is the combination of ClassName - MethodeName")]
public string MethodName { get; set; }
public Dictionary<string, string[]> Headers { get; set; }
public string HttpVerb { get; set; }
public string TransactionId { get; set; }
public int? HttpResponseStatusCode { get; set; }
}

如能帮助解决此问题,我们将不胜感激。我需要做什么才能用 Jil 序列化异常对象?

这里的根本问题是 System.Exception 并不意味着要序列化。它包含各种 "can only work on this machine" 信息。

通常 Jil 会忽略其中的很多内容,但是您的 Options 告诉它 includeInherited 这意味着它正在获取 System.Exception 上 public 的所有内容。这包括 System.RuntimeTypeHandleSystem.RuntimeType.

之类的内容

Jil 不应该以这种无益的方式爆炸(我正在做笔记去弄清楚如何检测这些案例并更好地报告它们),但是这些类型不能被序列化或反序列化明智地。我建议将您关心的 Exception 部分复制到一个更健全的 POCO 上。

您可能也可以调用 SerializeDynamic 或使 Serialize 通用 - Jil 将 Serialize(object) 视为几乎等同于 SerializeDynamic,也可能是明确的。