Why is my JSON Response not being Deserialized on my Client into the same Generic List Type as the Origin IEnumerable Type on the Web API server?

一曲冷凌霜 提交于 2020-01-06 01:30:06

问题


If I understand Ufuk Hacıoğulları here

I can simplify this code:

using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
    if (webResponse.StatusCode == HttpStatusCode.OK)
    {
        var reader = new StreamReader(webResponse.GetResponseStream());
        string s = reader.ReadToEnd();
        var arr = JsonConvert.DeserializeObject<JArray>(s);
        if (arr.Count <= 0) break;

        foreach (JObject obj in arr)
        {
            id = obj.Value<int?>("Id") ?? 0;
            var _deptId = obj.Value<int?>("deptId") ?? 0;
            var _subdeptId = obj.Value<int?>("subdeptId") ?? 0;
            var _deptIdSubdeptId = Convert.ToDouble(String.Format("{0}.{1}", _deptId, _subdeptId));
            var _subdeptName = obj.Value<string>("subdeptName") ?? "";

            subDeptList.subDepartments.Add(new HHSUtils.Subdepartment
            {
                Id = id,
                deptIdSubdeptId = (float)_deptIdSubdeptId,
                subDeptName = _subdeptName
            });
        } // foreach
    } // if ((webResponse.StatusCode == HttpStatusCode.OK)
} // using HttpWebResponse

...if I were to "use custom types instead of JArray or JObject types"

If I understand what he's saying, I could replace this line:

var arr = JsonConvert.DeserializeObject<JArray>(s);

...with something like:

var subDeptList = new SubdeptsList();
. . .
var arr = JsonConvert.DeserializeObject<Subdepartment>(s);
foreach (HHSUtils.Subdepartment obj in arr)
{
    subDeptList.subDepartments.Add(obj);
} 

Yet doing so fails with, "Exception: Cannot deserialize JSON array into type 'HHS.HHSUtils+Subdepartment'."

What the server passes is an IEnumerable which is defined there as:

public class Redemption
{
    [Key]
    public long Id { get; set; }
    [Required]
    public string RedemptionId { get; set; }
    [Required]
    public string RedemptionName { get; set; }
    [Required]
    public string RedemptionItemId { get; set; }
    [Required]
    public double RedemptionAmount { get; set; }
    public string RedemptionDept { get; set; }
    public string RedemptionSubDept { get; set; }
}

And it converts that data to JSON when passing it back; in the client, I'm attempting to convert the sent JSON back to this:

public class Redemption
{
    public long Id { get; set; }
    public string RedemptionId { get; set; }
    public string RedemptionItemId { get; set; }
    public string RedemptionName { get; set; }
    public double RedemptionAmount { get; set; }
    public string RedemptionDept { get; set; }
    public string RedemptionSubDept { get; set; }
}

...with the code shown above. The only mismatch I can see (besides the class member "decorations" (Key, Required) the Redemption has on the server, which are missing on the client), is that on the server the generic list is an IEnumerable, whereas on the client it's a List:

public class SubdeptsList
{
    public List<Subdepartment> subDepartments = new List<Subdepartment>();
}

So how can I more directly transfer the JSON object to my client, rather than use the JArray/JObject? Is it really feasible?


回答1:


This is what I ended up with; Ufuk's suggestion has led to much more streamlined/elegant code:

// the old way:
using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
    if (webResponse.StatusCode == HttpStatusCode.OK)
    {
        var reader = new StreamReader(webResponse.GetResponseStream());
        string s = reader.ReadToEnd();
        var arr = JsonConvert.DeserializeObject<JArray>(s);
        if (arr.Count <= 0) break; 

        foreach (JObject obj in arr)
        {
            id = obj.Value<int?>("Id") ?? 0;
            var _redemptionId = obj.Value<string>("RedemptionId") ?? "";
            var _redemptionItemId = obj.Value<string>("RedemptionItemId") ?? "";
            var _redemptionName = obj.Value<string>("RedemptionName") ?? "";
            double _redemptionAmount = obj.Value<double?>("RedemptionAmount") ?? 0.0;
            var _redemptionDept = obj.Value<string>("RedemptionDept") ?? "";
            var _redemptionSubdept = obj.Value<string>("RedemptionSubDept") ?? "";

            redemptionsList.redemptions.Add(new Redemption
            {
                Id = id,
                RedemptionId = _redemptionId,
                RedemptionItemId = _redemptionItemId,
                RedemptionName = _redemptionName,
                RedemptionAmount = _redemptionAmount,
                RedemptionDept = _redemptionDept,
                RedemptionSubDept = _redemptionSubdept
            });
        } // foreach
    } // if ((webResponse.StatusCode == HttpStatusCode.OK)
} // using HttpWebResponse

And now the new and improved way:

using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
    if (webResponse.StatusCode == HttpStatusCode.OK)
    {
        var reader = new StreamReader(webResponse.GetResponseStream());
        string jsonizedRedemptions = reader.ReadToEnd();
        List<Redemption> redemptions = JsonConvert.DeserializeObject<List<Redemption>>(jsonizedRedemptions);
        if (redemptions.Count <= 0) break;

        foreach (Redemption redemption in redemptions)
        {
            redemptionsList.redemptions.Add(redemption);
        }
    } // if ((webResponse.StatusCode == HttpStatusCode.OK)
} // using HttpWebResponse


来源:https://stackoverflow.com/questions/20508080/why-is-my-json-response-not-being-deserialized-on-my-client-into-the-same-generi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!