1

I am using below code to return Task but I'm not getting how to deserialize null value.

How to handle code if finalResult value is Null.

public async Task<T> PostAsync<T>(JObject parameters)
{
    string sasURL = await GenerateLogicAppSASUrl();
    var param = new StringContent(parameters.ToString(), Encoding.UTF8, "application/json");
    var httpCall = await client.PostAsync(sasURL, param);
    var result = await httpCall.Content.ReadAsStringAsync();
    var finalResult = JObject.Parse(result)["Column1"]?.ToString();  
    return  JsonConvert.DeserializeObject<T>(finalResult); // what to return if finalResult value here is null
}
chandra sekhar
  • 1,093
  • 4
  • 14
  • 27

3 Answers3

3

JsonConvert.DeserializeObject<T>() throws ArgumentNullException when argument is null.

You could either throw an exception if your finalResult variable is null, or return null from your method instead of deserializing it:

return finalResult == null ? default(T): JsonConvert.DeserializeObject<T>(finalResult);
kaffekopp
  • 2,551
  • 6
  • 13
  • @chrisb-de OP has mentioned it has null value – Mrinal Kamboj Aug 21 '19 at 10:14
  • sure. `await httpCall.Content.ReadAsStringAsync()` makes it possible to retrieve null. But i cannot see any restrictions on T itself. When you call the method like this `PostAsync(parameters)` the expected result might not be null at all. – chrisb-de Aug 21 '19 at 10:17
2

Solution 1:

var jsonSettings = new JsonSerializerSettings
                    {
                        NullValueHandling = NullValueHandling.Ignore,
                        MissingMemberHandling = MissingMemberHandling.Ignore
                    };

var result = JsonConvert.DeserializeObject<T>(data, jsonSettings); // jsonSettings are explicitly supplied

Json.Net example to understand the above setting

void Main()
{
    Test t = new Test 
    {
     Str = null,
     Val=1
    };

    var jsonSettings = new JsonSerializerSettings
    {
        NullValueHandling = NullValueHandling.Ignore,
        MissingMemberHandling = MissingMemberHandling.Ignore
    };

    var json = JsonConvert.SerializeObject(t,jsonSettings);

    json.Dump();    

    var result = JsonConvert.DeserializeObject<Test>(json, jsonSettings);

    result.Dump();
}

public class Test
{
    public string Str {get;set;}

    public int Val {get; set;}
}

Results:

enter image description here

Explanation:

  1. Null Value Handling Json settings ignore the null value during serialization
  2. During Deserialization same value is introduced with null value
  3. Null value has to be of the fields not whole object, if whole object is null then there's no serialization, deserialization required, it can be pre-empted via logic

Solution 2:

return (finalResult != null) ? JsonConvert.DeserializeObject<T>(finalResult) : default(T)

My preference is Solution1 as it will handle null values internally at the Serializer library level

Mrinal Kamboj
  • 11,300
  • 5
  • 40
  • 74
  • Solution1 throwing error as "System.ArgumentNullException: 'Value cannot be null. Parameter name: value'" – chandra sekhar Aug 21 '19 at 10:20
  • You are getting exception from Json.Net `DeserializeObject` call then i would be surprised, this is documented default way – Mrinal Kamboj Aug 21 '19 at 10:25
  • @Mrinal Kaboj: your first solution requires additional settings for JsonConvert.DeserializeObject. I imagine having those settings all over the code. In my opinion a nightmare. Just returning the default value when data is null seems to be the cleanest way. – chrisb-de Aug 21 '19 at 10:28
  • @chrisb-de not as bad that's we use patterns like Factory to avoid repetitive object creation, and make the code clean. In-fact these settings can also be at the project level – Mrinal Kamboj Aug 21 '19 at 10:29
  • Why whould you configure this on the project level or anywhere else at all, when a simple `if (data == null) return default;` would suffice? i do not see the benefit of introducing more complexity to solve such a trivial and predictable problem. So i'd rather prefer the second solution. :-) – chrisb-de Aug 21 '19 at 10:54
  • @chrisb-de, used default(T) it fixed my issue.Short & simple answer,Thank you – chandra sekhar Aug 21 '19 at 11:44
  • @chrisb-de, a default serializer setting is meant to be project wide or global with a scope of specific settings for few logical constructs. The statement which checks and returns null is a repetitive code, such logic is always better to be handled via Serializer instead of custom code. Keeps the design clean. – Mrinal Kamboj Aug 21 '19 at 13:23
  • @chandrasekhar check my updated answer which explains the working of the Serializer settings to handle null value. Null value shall be of the fields of the object, the complete object cannot be null – Mrinal Kamboj Aug 22 '19 at 05:01
0

You could create a extension string method like this:

public static dynamic Deserialize(this string stg, Type typeWanted)
    {
         var model = Activator.CreateInstance(typeWanted);

        if (string.IsNullOrEmpty(stg))
            return model;

        model = JsonConvert.DeserializeObject(stg, typeWanted);

        return model;
    }