MissingMethodException from Async Serialization Operation

I wrote a small wrapper of the Async library for Json.Net v5.06 from NuGet and after updating a number of Telerik packages my UnitTests started to fail with MissingMethodException .

I created a dummy non-Async method that works, so I got confused where the error is.

Project Target Platform

.Net 4.5

x86 CPU

Operation async

public class JsonSerialiser : ISerialiser { [InjectionConstructor] public JsonSerialiser(IStringCompression streamCompressor, ILog logger) { if (streamCompressor == null) throw new ArgumentNullException("streamCompressor"); if (logger == null) throw new ArgumentNullException("logger"); XmlConfigurator.Configure(); this.streamCompressor = streamCompressor; this.logger = logger; } public async Task<string> SerialiseAsync<T>(T serialseObject) where T : class { if (serialseObject == null) throw new ArgumentNullException("serialseObject"); try { return await JsonConvert.SerializeObjectAsync(serialseObject); } catch (JsonSerializationException ex) { logger.Error(ex); throw new SerialisationException("Could Not Serialse The Object", ex); } } } 

Asynchronous Example

Now this code has been reset to check basic serialization, where I go to null checks in the class constructor.

  private async void button1_Click(object sender, EventArgs e) { List<Part> parts = new List<Part> { new Part() { AbstractType = typeof(IOpcController), ConcreteType = typeof(OpcController) }, new Part() { AbstractType = typeof(ISerialiser), ConcreteType = typeof(JsonSerialiser) }, new Part() { AbstractType = typeof(IStringCompression), ConcreteType = typeof(StringGZipCompression)}}; string serialisedResult = string.Empty; JsonSerialiser serialiser = new JsonSerialiser(null, null); serialisedResult = await serialiser.SerialiseAsync<List<Part>>(parts); } 

Async Result

This is a generation of MissingMethodException

enter image description here

 Method not found: 'System.Threading.Tasks.Task`1<System.String> Newtonsoft.Json.JsonConvert.SerializeObjectAsync(System.Object)'. at Helper.Core.Serialisation.Json.JsonSerialiser.<SerialiseAsync>d__0`1.MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start[TStateMachine](TStateMachine& stateMachine) at Helper.Core.Serialisation.Json.JsonSerialiser.SerialiseAsync[T](T serialseObject) at OpcTester.Form1.<button1_Click>d__9.MoveNext() in c:\Users\phil.murray\Desktop\tmp\OpcTester\Form1.cs:line 44 

No Async Operation

Just to check if there was an asynchronous part of the method causing the problem, I wrote a non-asynchronous implementation.

 public string Serialise<T>(T serialseObject) where T : class { if (serialseObject == null) throw new ArgumentNullException("serialseObject"); try { return JsonConvert.SerializeObject(serialseObject); } catch (JsonSerializationException ex) { logger.Error(ex); throw new SerialisationException("Could Not Serialse The Object", ex); } } 

No Asynchronous Implementation

 private async void button1_Click(object sender, EventArgs e) { List<Part> parts = new List<Part> { new Part() { AbstractType = typeof(IOpcController), ConcreteType = typeof(OpcController) }, new Part() { AbstractType = typeof(ISerialiser), ConcreteType = typeof(JsonSerialiser) }, new Part() { AbstractType = typeof(IStringCompression), ConcreteType = typeof(StringGZipCompression)}}; string serialisedResult = string.Empty; JsonSerialiser serialiser = new JsonSerialiser(null, null); serialisedResult = serialiser.Serialise<List<Part>>(parts); } 

No Asynchronous Result

The method completes and serializes the list into a string.

Invalid test case.

  Test Name: SerialiserSerialiseObjectExists Test FullName: Helper.Tests.SerialiserTests.SerialiserSerialiseObjectExists Test Source: c:\Perforce\Development\SharedAPIs\Helper.Core\Helper.Tests\SerialiserTests.cs : line 38 Test Outcome: Failed Test Duration: 0:00:00.0116216 Result Message: Test method Helper.Tests.SerialiserTests.SerialiserSerialiseObjectExists threw exception: System.MissingMethodException: Method not found: 'System.Threading.Tasks.Task`1<System.String> Newtonsoft.Json.JsonConvert.SerializeObjectAsync(System.Object)'. Result StackTrace: at Helper.Core.Serialisation.Json.JsonSerialiser.<SerialiseAsync>d__0`1.MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) a t System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start[TStateMachine](TStateMachine& stateMachine) at Helper.Core.Serialisation.Json.JsonSerialiser.SerialiseAsync[T](T serialseObject) at Helper.Tests.SerialiserTests.<SerialiserSerialiseObjectExists>d__3.MoveNext() in c:\Perforce\Development\SharedAPIs\Helper.Core\Helper.Tests\SerialiserTests.cs:line 40 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 

Asynchronous test without Json.Net

Just for arguments, I replaced the Json.Net call with a dummy task, and it worked, so the problem is calling Json.net using Await \ Async. Strange as it worked, and the version was not updated.

 public async Task<string> SerialiseAsync<T>(T serialseObject) where T : class { if (serialseObject == null) throw new ArgumentNullException("serialseObject"); try { //return await JsonConvert.SerializeObjectAsync(serialseObject); return await Task.Run(() => string.Empty); } catch (JsonSerializationException ex) { logger.Error(ex); throw new SerialisationException("Could Not Serialse The Object", ex); } } 

Question

Now, the asynchronous UnitTests method worked previously before I updated the Telerik management pack and I tested the operation in multiple instances of the real world. I'm not saying that updating Telerik caused a problem, as it could be a coincidence. A number of other asynchronous tests pass when testing other classes (not related to Json.Net).

Any idea what is wrong with the Async method and how to solve the problem?

Possible resolution

As I continued to investigate the problem, it occurred to me that the problem could arise in the Async call in the Json.Net library, so I wrapped up no Async call in the Task, as shown below, which worked

  public async Task<string> SerialiseAsync<T>(T serialseObject) where T : class { if (serialseObject == null) throw new ArgumentNullException("serialseObject"); try { //return await JsonConvert.SerializeObjectAsync(serialseObject); return await Task.Run<string>(() => JsonConvert.SerializeObject(serialseObject)); } catch (JsonSerializationException ex) { logger.Error(ex); throw new SerialisationException("Could Not Serialse The Object", ex); } } 

Out of interest, I downloaded the source for Json.Net and checked the JsonConvert.SerializeObjectAsync call, and it did the same, so again I'm not sure about the main problem.

 public static Task<string> SerializeObjectAsync(object value, Formatting formatting, JsonSerializerSettings settings) { return Task.Factory.StartNew(() => SerializeObject(value, formatting, settings)); } 
+4
source share
1 answer

Check the output directory containing your build. Inside the properties of Newtonsoft.Json.dll, you will see that the description is β€œJson.Net Portable.Net 4.0” and this version does not provide SerializeObjectAsync (you can check the assembly using ILSpy ).

enter image description here

Replace the Json assembly with .Net 4.5, and it should work.

0
source

Source: https://habr.com/ru/post/1494037/


All Articles