0

I have a class library project in .net. I can't use 3rd party assemblies, only Microsoft assemblies allowed.

I have a return class from web API like below. I try to Deserialize string to this class and it's not working but it works for other classes. I think the problem is the 'T' class accepting.

my class;

public class ApiResponse<T>
{
    public T Value { get; set; }

    public bool HasError { get; set; }

    public string ErrorMessage { get; set; }

    public string DetailedErrorMessage { get; set; }

    public string ErrorCode { get; set; }

    public ApiResponse(string errorCode, string errorMessage, string detailedErrorMessage = "")
    {
        this.ErrorMessage = errorMessage;
        this.ErrorCode = errorCode;
        this.HasError = true;
        this.DetailedErrorMessage = detailedErrorMessage;
    }

    public ApiResponse(T value)
    {
        this.Value = value;
        this.HasError = false;
        ErrorMessage = string.Empty;
    }

    public ApiResponse()
    {
        this.HasError = false;
        ErrorMessage = string.Empty;
    }

    public ApiResponse(OLException e)
    {
        ErrorCode = e.ErrorCode;
        ErrorMessage = e.Message;
        HasError = true;
        DetailedErrorMessage = e.StackTrace;
    }

    public ApiResponse(Exception e)
    {
        ErrorMessage = e.Message;
        HasError = true;
        DetailedErrorMessage = e.StackTrace;
    }
}

and here is my Deserialize function.

private T JsonDeserialize<T>(string jsonString)
{
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
    T obj = (T)ser.ReadObject(ms);
    return obj;
}

and here is the How I use the following method

ApiResponse<bool> response = JsonDeserialize<ApiResponse<bool>>(responseString);

Response string -->

{"value":false,"hasError":true,"errorMessage":"user1 client already exists.","detailedErrorMessage":"","errorCode":null}

There is no error just response class seems null after deserialize but as you see, the response string has some values.

enter image description here

4
  • What's the error? what's the json like? and what type T are you using for JsonDeserialize? Commented Apr 22, 2020 at 19:13
  • edit the question with additional information. please check again. Commented Apr 22, 2020 at 19:17
  • Are you using .NET Core or .NET FW? Commented Apr 22, 2020 at 20:05
  • I'm using .net core Commented Apr 22, 2020 at 22:09

4 Answers 4

3

You've already referenced System.Text.Json (Microsoft), so you can just do this:

static T DeserializeEasyWay<T>(string input)
{
    return JsonSerializer.Deserialize<T>(input, 
        new JsonSerializerOptions{PropertyNameCaseInsensitive = true});
}

I tested with your string. It works.

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

1 Comment

I'd suggest using the Name property of the DataMemberAttribute instead. It's possible to have both a "value", "Value" and "vAlUe" property in the json.
2

The DataContractJsonSerializer is a case sensitive, then it consider the property value and Value are different.

To resolve the issue, you could change the class ApiResponseto:

[DataContract]
public class ApiResponse<T>
{
    [DataMember(Name = "value")]
    public T Value { get; set; }

    [DataMember(Name = "hasError")]
    public bool HasError { get; set; }

    [DataMember(Name = "errorMessage")]
    public string ErrorMessage { get; set; }

    [DataMember(Name = "detailedErrorMessage")]
    public string DetailedErrorMessage { get; set; }

    [DataMember(Name = "errorCode")]
    public string ErrorCode { get; set; }

    // add other method ...
}

I hope this helps you fix the issue.

Comments

1

If you're targeting .NET Core 3.x, you may use System.Text.Json API with case insensitive properties names

var properties = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
var response = JsonSerializer.Deserialize<ApiResponse<bool>>(jsonString, properties);

It's also possible to get it through Nuget for .NET Core 2.x or .NET Framework 4.7.2 or 4.8.

For old .NET Framework you can use built-in JavaScriptSerializer

var response = new JavaScriptSerializer().Deserialize<ApiResponse<bool>>(jsonString);

In this case you'll need to add System.Web.Extensions.dll to the project references and System.Web.Script.Serialization to using directives

Comments

0

You seem to be missing the annotations for the DataContractJsonSerializer.

[DataContract]
public class ApiResponse<T>
{
    [DataMember]
    public T Value { get; set; }
    [DataMember]
    public bool HasError { get; set; }
    [DataMember]
    public string ErrorMessage { get; set; }
    [DataMember]
    public string DetailedErrorMessage { get; set; }
    [DataMember]
    public string ErrorCode { get; set; }

.... etc...

2 Comments

I try before but It didn't help. I found the problem, the problem is case sensitivity but I don't know is there a setting for case sensitivity in DataContractJsonSerializer. Because I can't use any 3rd part assembly like Newtonsoft.
I don't believe there is an option in DataContractJsonSerializer for case insensitivity. I think in this case you'd have to modify your application to handle this either with middleware, or if it's a desktop application, with a class to change this before attempting to deserialise the data.

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.