2

Depending on the licence I query, I get two different JSON responses. On Success I get the "success" string and on error I get the "code" string. Now, I have built a two constructors class to catch both cases.

When I deserialize the json string with:

License license = JsonConvert.DeserializeObject<License>(json_str);

I get the error: "Unable to find a constructor to use for type..."

Here is the code, any suggestions:

 //JSON String on Success -> {"success":true,"data":{"id":54,"orderId":109,"productId":79,"userId":1,"licenseKey":"1y10a3P-YL-A1-EQ-F9-GI-DM-W3","expiresAt":"2022-09-04 09:02:40","validFor":365,"source":1,"status":2,"timesActivated":null,"timesActivatedMax":1,"createdAt":"2021-09-04 09:02:40","createdBy":0,"updatedAt":"2021-09-04 09:02:40","updatedBy":0}}
 //JSON String on error -> {"code":"lmfwc_rest_license_expired","message":"The license Key expired on 2021-10-06 00:00:00 (UTC).","data":{"status":405}}

    public partial class License
    {
        [JsonProperty("success")]
        public bool Success { get; set; }

        [JsonProperty("data")]
        public Success_Data Success_Data { get; set; }

        [JsonProperty("code")]
        public String Code { get; set; }

        [JsonProperty("message")]
        public String Message { get; set; }

        [JsonProperty(PropertyName = "error_data")]
        public Error_Data Error_Data { get; set; }

        public License(bool success, Success_Data data)
        {
            Success = success;
            Success_Data = data;
        }

        public License(String code, String message, Error_Data error_data)
        {
            Code = code;
            Message = message;
            Error_Data = error_data;
        }
    }

    public partial class Error_Data
    {
        [JsonProperty("status")]
        public long Status { get; set; }
    }        

    public partial class Success_Data
    {
        [JsonProperty("id")]
        public long Id { get; set; }

        [JsonProperty("orderId")]
        public long OrderId { get; set; }

        [JsonProperty("productId")]
        public long ProductId { get; set; }

        [JsonProperty("userId")]
        public long UserId { get; set; }

        [JsonProperty("licenseKey")]
        public string LicenseKey { get; set; }

        [JsonProperty("expiresAt")]
        public DateTimeOffset ExpiresAt { get; set; }

        [JsonProperty("validFor")]
        public object ValidFor { get; set; }      
 

... }

Charlieface
  • 52,284
  • 6
  • 19
  • 43
paralax
  • 21
  • 2
  • 3
    I think JSON serialization requires a _default constructor_ (i.e., one without any parameters). Your `License` type doesn't have one – Flydog57 Nov 01 '21 at 14:18
  • @Flydog57 is correct, you need a default, parameterless constructor. For example: `public License(){}` *If* you still want to use a constructor other than the default, add `[JsonConstructor]` attribute to that constructor. [Here's](https://stackoverflow.com/questions/23017716/json-net-how-to-deserialize-without-using-the-default-constructor) a little information about that. – Trevor Nov 01 '21 at 14:34

1 Answers1

1

you need a constructor with [JsonConstructor] attribute. This code was tested and works properly

[JsonConstructor]
public License(String code, String message, JToken data, bool? success = null)
{
    if (success != null)
    {
        Success = (bool)success;
        Success_Data = JsonConvert.DeserializeObject<Success_Data>(data.ToString());
    }
    else
    {
        Code = code;
        Message = message;
        Error_Data = JsonConvert.DeserializeObject<Error_Data>(data.ToString());
    }
}

and remove [JsonProperty(PropertyName = "error_data")] since there is no this json property. Leave just

 public Error_Data Error_Data { get; set; }
Serge
  • 40,935
  • 4
  • 18
  • 45