I have a custom log message object that I am trying to serialize with Jil to JSON format. This is the first time I have used Jil instead of the default JSON.Net serializer so I am not very familiar with it.
One of the properties on the log message object is an Exception. When the Exception property is null, Jil serializes the object without a problem. However, if the Exception object is populated with an actual exception, I get an error from 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()
I am using the following Jil Serialization options:
new Jil.Options(false, true, false, DateTimeFormat.ISO8601, true, UnspecifiedDateTimeKindBehavior.IsUTC, SerializationNameFormat.CamelCase);
The method I am using to call Jil is:
public byte[] Serialize(object item)
{
var jsonString = JSON.Serialize(item);
return encoding.GetBytes(jsonString);
}
The full object that I am trying to serialize is:
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; }
}
Any help in fixing this issue would be greatly appreciated. What do I need to do in order to serialize an Exception object with Jil?
The fundamental problem here is that System.Exception
isn't meant to be serialized. It contains all sorts of "can only work on this machine" information.
Normally Jil would ignore a lot of that, but your Options
are telling it to includeInherited
which means it's getting ahold of everything that's public on System.Exception
. This includes things like System.RuntimeTypeHandle
and System.RuntimeType
.
Jil should't explode in such an unhelpful way (I'm making a note to go and figure out how to detect these cases and better report them), but those sorts of types can't be serialized or deserialized sensibly. I'd suggest copying the parts of Exception you care about onto a saner POCO.
You probably also either way to call SerializeDynamic
or make Serialize
generic - Jil's treats Serialize(object)
as mostly equivalent to SerializeDynamic
, might as well be explicit.