Serialization Exception With PerformContext when manually trigger a job

Tags: #<Tag:0x00007f0664e77c20> #<Tag:0x00007f0664e77b58>

Currently running latest Pro version in a .net core environment. We have two projects, a web project which runs only the dashboard and a jobs project that runs the actual jobs.

We have a simple job that runs on a schedule. When the cron schedule kicks off the job it runs fine and we can debug it. However, if you manually try to trigger the job from the dashboard we get the following error.

Error converting value "Hangfire.Server.PerformContext, Hangfire.Core, Version=1.6.19.0, Culture=neutral, 
PublicKeyToken=null" to type 'System.Type'. Path '[0]', line 1, position 104.

Newtonsoft.Json.JsonSerializationException: Error converting value "Hangfire.Server.PerformContext, Hangfire.Core, 
Version=1.6.19.0, Culture=neutral, PublicKeyToken=null" to type 'System.Type'. Path '[0]', line 1, position 104. ---> 
System.ArgumentException: Could not cast or convert from System.String to System.Type.
at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType)

Hm, so I have some additional questions to you. Could you show me how do you create your recurring job and how does it look like (especially the corresponding method signature)? Also what Newtonsoft.Json package version do you have, and what is the full stack trace for this exception?

Hi there, information is below. This is a .netcore 2 project that hosts hangfire, and this is the only place we’ve had this problem the desktop .net hangfire server we have does not exhibit this issue. My gut tells me this is something related to dotnetcore and hangfire.

CronJob.AddOrUpdate(typeof(IRecurringJob));

Job:

 public interface IRecurringJob : IHangfireJob
{
    [DisplayName("Checks for new documents")]
    [Description("Checks for new documents")]
    [AutomaticRetry(Attempts = 3)]
    [RecurringJob("* * * * *", Queue = "docs", RecurringJobId = "Checks for new documents", TimeZone = "UTC")]
    void CheckForDocuments(PerformContext context);
}

Dependencies for the dotnet core hangfire server:

image

Full stack trace:
Newtonsoft.Json.JsonSerializationException
Error converting value “Hangfire.Server.PerformContext, Hangfire.Core, Version=1.6.19.0, Culture=neutral, PublicKeyToken=null” to type ‘System.Type’. Path ‘[0]’, line 1, position 104.

Newtonsoft.Json.JsonSerializationException: Error converting value "Hangfire.Server.PerformContext, Hangfire.Core, Version=1.6.19.0, Culture=neutral, PublicKeyToken=null" to type 'System.Type'. Path '[0]', line 1, position 104. ---> System.ArgumentException: Could not cast or convert from System.String to System.Type.
   at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType)
   at Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
   --- End of inner exception stack trace ---
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at Hangfire.Common.JobHelper.FromJson[T](String value)
   at Hangfire.Storage.InvocationData.Deserialize()

Thanks for all the details. Your dashboard instance use newer version for Hangfire.Core. When Newtonsoft.Json is serializing a recurring job triggered by dashboard with overridden serialization settings (because default ones don’t include type name in the payload), the serialized payload includes the “1.6.19” version. It can’t deserialize it on the server, because it uses the lower version of Hangfire.Core assembly on it (1.6.14).

You can try to downgrade the version in dashboard instance, or upgrade your server. Alternatively, you can tell Newtonsoft.Json to not to include the version information, by specifying the TypeNameHandlingFormat.Simple option in your serialization settings.

So to fix this i had to explicitly reference Hangfire.Core in the server project as Hangfire.Pro is still referencing 1.6.14. That was the only way I could see to fix it