简体   繁体   中英

Ignore deserialize when no such property exist

I'm consuming a private web service , which is not in my control.

i'm consuming a login service, This is class about to deseralized the result

[DataContract]
public class BaseDTO
{
    [DataMember]
    public string status { get; set; }

    [DataMember]
    public string msg { get; set; }

    [DataMember]
    public string code { get; set; }

    [DataMember(Name = "data", IsRequired = false)]
    public LoginDTO LoginInfo{ get; set; }
}

[DataContract]
public class LoginDTO 
{
    [DataMember]
    public string FirstName{ get; set; }

    [DataMember]
    public string LastName{ get; set; }

}

Here what i tried

public async Task<BaseDTO> InsertString(MyObject insertParameters)
    {
        try
        {
            using (var _client = new HttpClient())
            {
                _client.BaseAddress = new Uri(baseServiceUri);
                _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                HttpContent insertHttpcontent = new StringContent(JsonConvert.SerializeObject(insertObject));

                var response = await _client.PostAsync(new Uri(baseAccessPoint, UriKind.Relative), insertHttpcontent);

                //Throws exception when its invalid
                //response.EnsureSuccessStatusCode();

                var responseResult = await response.Content.ReadAsStringAsync();


                return JsonConvert.DeserializeObject<BaseDTO>(responseResult, new JsonSerializerSettings()
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    Error = JsonDeserializeErrorHandler,
                });
            }


        }
        catch (Exception ex)
        {

            throw;
        }
    }

If the login credentials are true service is returning the LoginInfo details ,else it will not provide any information just the status,msg and code.

The problem is the Json Deseralizer always try to Deseralize everything even if tried to set ignore null value , but doesn't seems working. As my service is not returning null, It will not provide the object itself. Currently i handle using JsonDeserializeErrorHandler setting errorhandled property to true. I have referenced this also

JsonResult When success

{"status":"success","msg":"Welcome!!","code":"","data":{"session_token":"bdadee2cb7597fbb5ceed550ca389440","firsname":"test1","lastname":"test2"}}}}

JsonResult When Error

{"status":"warning","msg":"Incorrect Username or MPIN","code":"","data":[]}

How do i overcome this scenario more gracefully

    #region DeserializeErrorHandling
    private void JsonDeserializeErrorHandler(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs e)
    {
        //var currentError = e.ErrorContext.Error.Message;
        e.ErrorContext.Handled = true;
    }
    #endregion

Your problem is that in one case you get an object {"session_token":"12", ...} and an empty array [] in another for data property. Empty array is not null . That means that you can not use the same type for deserializing such JSON.

My suggestion is to use dynamic for data property and then parse this value:

[DataContract]
public class BaseDTO
{
    // Rest of the properties

    [DataMember]
    public dynamic data { get; set; }

    public LoginDTO LoginInfo
    {
        get
        {
            var jObjectData = data as JObject;
            if (jObjectData == null)
            {
                return null;
            }

            try
            {
                return jObjectData.ToObject<LoginDTO>();
            }
            catch
            {
                return null;
            }
        }
    }
}

You can use more logic in LoginInfo property. For example you could parse it based on status and etc.

Note: your success JSON is invalid, I guess it's just a copy/paste issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM