如果不存在此类属性,则忽略反序列化

时间:2015-04-18 18:08:27

标签: c# json json.net deserialization json-deserialization

我正在使用私人网络服务,这是我无法控制的。

我正在使用登录服务,这是即将对结果进行解除分类的类

[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; }

}

这是我试过的

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;
        }
    }

如果登录凭据为true,则服务返回LoginInfo详细信息,否则它将不提供任何信息,只提供状态,消息和代码。

问题是Json Deseralizer总是试图去除所有东西,即使试图设置忽略空值,但似乎没有效果。由于我的服务没有返回null,它不会提供对象本身。目前我处理使用JsonDeserializeErrorHandler设置errorhandled属性为true。 我引用了this also

JsonResult成功时

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

JsonResult出错时

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

如何更优雅地克服这种情况

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

1 个答案:

答案 0 :(得分:1)

您的问题是,在一种情况下,您会在另一个{"session_token":"12", ...}属性中获得一个对象[]和一个空数组data。空数组不是 null 。这意味着您不能使用相同的类型来反序列化此类JSON。

我的建议是将dynamic用于data属性,然后解析此值:

[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;
            }
        }
    }
}

您可以在LoginInfo属性中使用更多逻辑。例如,您可以根据状态等解析它。

注意:您的成功JSON无效,我想这只是一个复制/粘贴问题。