Home > OS >  NewtonSoft is not deserializing json to object when in release mode
NewtonSoft is not deserializing json to object when in release mode

Time:01-17

I am facing a weird error in my Android Xamarin Forms app. Unable to find the root cause of it. Following is my code which gets the API response and deserializes it to an object.

public async static Task<T2> ExecuteRequest<T1, T2>(T1 t1, EndPoint endPoint, bool getParams = false, HttpVerb method = HttpVerb.POST)
{
    string resStr = "";
    try
    {
        object data = t1;
        if (endPoint.ToString() != EndPoints.Login.ToString() && getParams == false)
              data = Newtonsoft.Json.JsonConvert.SerializeObject(t1);
        HttpUtils.RestClient restClient = new HttpUtils.RestClient(APIPath   endPoint, HttpVerb.POST, data.ToString());
        restClient.ContentType = "application/json";
        restClient.Method = method;
        resStr = await (endPoint != EndPoints.Login && getParams == false ? restClient.MakeRequest() : restClient.MakeRequest(data.ToString()));

        if (string.IsNullOrEmpty(resStr))
            return default(T2);
            
        return Newtonsoft.Json.JsonConvert.DeserializeObject<T2>(resStr);
    }   
    catch (Newtonsoft.Json.JsonSerializationException e)
    {
        Device.BeginInvokeOnMainThread(async () => await Application.Current.MainPage.DisplayAlert("Error", e.Message   "\n----------\n"   resStr, "OK"));
        return default(T2);
    }
    catch (System.Net.WebException)
    {
        Device.BeginInvokeOnMainThread(async () => await Application.Current.MainPage.DisplayAlert("Not Connected", "Please check your Internet connection and restart the app.", "OK"));
        return default(T2);
    }
}

And following is how I am trying to login using above method to the backend system:

Services.API.ResponseModels.Login res = await APIAccess.ExecuteRequest<string, Services.API.ResponseModels.Login>(req, APIAccess.EndPoints.Login);

Object Class:

public class Login
{
    public string access_token { get; set; }
    public string token_type { get; set; }
    public int expires_in { get; set; }
    public string userName { get; set; }
    public string issued { get; set; }
    public string expires { get; set; }
}

I am receiving a response correctly in following JSON format:

{
    "access_token": "<access token received here>",
    "token_type": "bearer",
    "expires_in": 2591999,
    "userName": "<userName received here>",
    ".issued": "Sun, 16 Jan 2022 09:41:06 GMT",
    ".expires": "Tue, 15 Feb 2022 09:41:06 GMT"
}

But when in Debug mode NewtonSoft deserializes it correctly and takes user to another screen and when in Release mode it shows following error:

enter image description here

I tried adding a default constructor normally and with [JsonConstructor] attribute but it's not working. I cleaned and removed Bin and Obj on all projects and also updated NewtonSoft JSON package. Nothing seems to work in Release mode.

CodePudding user response:

So why u don't try that with the new T2() instead of default(T2) ?

For that u need to define new(), class at the definition of your action.

CodePudding user response:

This is a linker issue, you need to hint that it should not remove that constructor, since it is never invoked directly.

One trick is to create a class, something like LinkerPleaseInclude and create methods that hint the usage of things that would normally get linked out. Make sure to tell the compiler to not link away this class with a [Preserve] attrubute.

This could look something like:

[Preserve(AllMembers = true)]
public class LinkerPleaseInclude
{
    public void Include(Login login)
    {
        login = new Login();
    }
}

Then do this with all the types that require it.

  •  Tags:  
  • Related