Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JsonSerializationException 'Unable to find a constructor' on Xamarin.Android

I have this very odd problem with my code, and it's a pretty new problem, considering I didn't have it half a year ago. Long story short, I've made an app in Xamarin, and released it about half a year ago, on all 3 stores (App Store, Google Play and Microsoft Store).

Yesterday a user reported a problem with the Android app, and after I got that fixed and recompiled, I'm now encountering a new error with Json.NET

The exception is

Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type Rowlog.Common.Dtos.CompressedTripData. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'tripCoordinates', line 1, position 19.

And before you ask, yes Rowlog.Common.Dtos.CompressedTripData does indeed have a parameterless constructor (Well, it doesn't have one at all, which we all know is the same thing).

And like I said, this is when I load a CompressedTripData object from the server on an Android device. Loading the exact same object on iOS and Windows Phone works without a hitch. I'm guessing it's gotta be a recent change in either Json.NET, or Xamarin.Android which is causing this (The other apps are still using the Json.NET libraries from about half a year ago. Not sure if there has even been any updates to it since)

Has anyone else encountered a similar problem, and if so, how have you fixed it?

like image 804
Falgantil Avatar asked Jan 14 '15 08:01

Falgantil


2 Answers

The Preserve attribute is a more focused way to ensure a member is not removed by the linker if you still prefer it to generally do it's thing with your code.

Example:

[Preserve]
[JsonConstructor]
private AlertRequest(bool fake_arg)
{
    // fake_arg is to have a unique ctor that we exclusively
    // use in JSON de-serialization via JsonConstructor attribute.
    // Preserve attribute ensures Xamarin linker does not remove,
    // as there are no direct uses of this ctor in the code base
}
like image 144
t9mike Avatar answered Oct 02 '22 21:10

t9mike


In the 'Android options' tab of the project properties, there is a 'linker' tab. Is the selected option in the 'Linking' dropdown "Sdk Assemblies only" or is it "Sdk and user assemblies"?

If it is the latter, the parameterless constructor is skipped when linking, because no use is detected. So change it to "Sdk Assemblies only".

like image 42
Stephen Avatar answered Oct 02 '22 21:10

Stephen