使用动态数据显式转换Newtonsoft.Json.Linq.JObject时出错

时间:2018-03-20 15:01:10

标签: c# json json.net

我正在尝试反序列化以下json:

{
"oxide":{
    "Al2O3":"0.3",
    "CaO":"0.3",
    "FeO":"0.3",
    "MgO":"0.3",
    "MnO":"0.3",
    "SiO2":"0.3"
},
"temperature": "1800"

}

当我以这种方式转换时,everthing有效:

        Oxides oxides = new Oxides();
        string oxidequery = req.Query["oxide"];
        string temperature = req.Query["temperature"];

        string requestBody = new StreamReader(req.Body).ReadToEnd();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
        oxide.Al2O3 = data?.oxide.Al2O3;
        oxide.CaO = data?.oxide.CaO;
        oxide.FeO = data?.oxide.FeO;
        oxide.MgO = data?.oxide.MgO;
        oxide.MnO = data?.oxide.MnO;
        oxide.SiO2 = data?.oxide.SiO2;
        double tempDouble = temperature ?? data?.temperature;

但是当我这样做时它不起作用:

        Oxides oxides = new Oxides();
        string oxidequery = req.Query["oxide"];
        string temperature = req.Query["temperature"];

        string requestBody = new StreamReader(req.Body).ReadToEnd();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
        oxide = (Oxides)data?.oxide;
        double tempDouble = temperature ?? data?.temperature;

在第二个方法中我得到了错误

  

无法将'Newtonsoft.Json.Linq.JObject'类型转换为'Oxides'。

我缺少什么?我已经搜索过并发现我必须显式转换data.oxide,但我已经这样做了。

2 个答案:

答案 0 :(得分:2)

试试这个:

dynamic data = JsonConvert.DeserializeObject<dynamic>(requestBody);
oxide = ((JObject)data?.oxide).ToObject<Oxides>();

答案 1 :(得分:0)

我相信您的问题在于您Stream阅读动态内容。当我遇到类似问题时,我作为对象返回。

    public object DownloadFromApi(string url)
    {
        if (WebRequest.Create(url) is HttpWebRequest request)
        {
            request.Method = "GET";
            request.ContentType = "application/json";

            try
            {
                using (Stream response = request.GetResponse().GetResponseStream())
                    if (response != null)
                        using (var reader = new StreamReader(response))
                            return JsonConvert.DeserializeObject(reader.ReadToEnd());
            }

            catch (HttpRequestException exception)
            {
                ApplicationProvider.Log.Error($"An unhandled HTTP error has occurred.{Environment.NewLine}{exception.Message}");
                throw new Exception(exception.Message);
            }
        }

        ApplicationProvider.Log.Error($"Web request failed due to null value. {url}");
        throw new Exception($"A null parameter or response has occurred for {url}");
    }

此转换似乎解决了我的问题,即对象被错误地反序列化为不正确的类型。所以我能够做以下事情来阅读我的对象。

    private static IEnumerable<AssetDataModel> GetAllDataForAsset(AssetModel asset)
    {
        dynamic apiResponse = new ApiRequestUtility().DownloadFromApi(optiAssetDataWithinRangeUrl);
        for (var index = 0; index != apiResponse.Items.Count; index++)
            yield return new AssetDataModel
            {
                Id = apiResponse["Items"][index].id,
                ResourceId = apiResponse["Items"][index].value[0].resourceId,
                Timestamp = apiResponse["Items"][index].timeValue,
                Value = apiResponse["Items"][index].value[0].value
            };
    }

当我遍历响应以构建我的数据集合时,这允许正确的转换。因此,一些奇怪的尝试反序列化浮动而不是小数似乎可以通过我们的实验室数据来缓解。

还想指出,返回作为对象但仍然具有动态的返回类型以在运行时确定。