11

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?

2 Answers 2

24

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".

Sign up to request clarification or add additional context in comments.

4 Comments

Yep, that was the problem. Thank you great sir, you are indeed a life saver!
Thank you so much for this - I was getting this error on Release builds but not Debug builds. Saved me a lot of time, as the effects of these linker options are not obvious (and I was about to give JSON.NET a lot more hand-holding with deserialisation). I was initially under the impression that this setting was to determine the DLLs linked in to the Android app package versus a separate library package...
Thanks a lot! Could not have figured out on my own.
This is not the correct solution. You simply hide the problem. you must use Preserve the class or define it in the linker config file.
3

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
}

2 Comments

When I try this, I'll get an exception: The "LinkAssemblies" task failed... failed ot resolve Mono.Security.MonoTlsProviderFActoryDelegate
Recommend asking a new question on SO @Akbari. I don't really do much w/ Android these days.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.