【问题标题】:Querying Json with Linq, Cannot access child value使用 Linq 查询 Json,无法访问子值
【发布时间】:2021-07-18 12:52:24
【问题描述】:

我是 JSON 的 C# 新手。我想用 Nvidia API 选择“featuredProduct”部分,但我有一个错误

无法访问 Newtonsoft.Json.Linq.JProperty 上的子值。

此代码适用于“searchedProducts”部分。

你能解释一下为什么吗?

const string url = "";
const int refresh = 3000;

string json = getGpuFromNvidia(url);

var jsonParse = JObject.Parse(json);

var result = jsonParse["searchedProducts"]["featuredProduct"]
    .Where(n => n["isFounderEdition"].Value<bool>() == true)
    .Select(p => new CarteGraphique
    {
        displayName = (string)p["displayName"],
        prdStatus = (string)p["prdStatus"],
        directPurchaseLink = (string)p["retailers"][0]["directPurchaseLink"]
    })
    .ToList();

【问题讨论】:

  • 为什么不为您从 API 获取的 JSON 创建一个类结构并将 JSON 反序列化为该类的对象...json2csharp.com 您可以在对象集合上轻松使用 LINQ,然后是 JObject 和它的属性。
  • featuredProduct 是一项您只能将 select 与项目列表一起使用的项目

标签: c# json api linq


【解决方案1】:

我在 VS 中测试了这段代码

 string json = ...your code
var jsonObj = JsonConvert.DeserializeObject<NvidiaRoot>(json);

var result = jsonObj.searchedProducts.productDetails
    .Where(n => n.isFounderEdition)
    .Select(p => new
    {
    displayName = p.displayName,
    prdStatus = p.prdStatus,
    directPurchaseLink = p.retailers[0].directPurchaseLink
    })
    .ToList();

输出

[
    {
        "displayName": "NVIDIA RTX 3090",
        "prdStatus": "out_of_stock",
        "directPurchaseLink": "https://www.ldlc.com/fiche/PB89455870.html"
    },
    {
        "displayName": "NVIDIA RTX 3070",
        "prdStatus": "out_of_stock",
        "directPurchaseLink": "https://www.ldlc.com/fiche/PB74221588.html"
    },
    {
        "displayName": "NVIDIA RTX 3060 Ti",
        "prdStatus": "out_of_stock",
        "directPurchaseLink": "https://www.ldlc.com/fiche/PB54012144.html"
    },
    {
        "displayName": "NVIDIA RTX 3070 Ti",
        "prdStatus": "out_of_stock",
        "directPurchaseLink": null
    },
    {
        "displayName": "NVIDIA RTX 3080 Ti",
        "prdStatus": "out_of_stock",
        "directPurchaseLink": null
    }
]

更新

如果您只需要功能产品

    var featuredProduct = jsonObj.searchedProducts.featuredProduct;
            var result = new
            {
                displayName = featuredProduct.displayName,
                prdStatus = featuredProduct.prdStatus,
                directPurchaseLink = featuredProduct.retailers[0].directPurchaseLink
            };

短输出

{
    "displayName": "NVIDIA RTX 3080",
    "prdStatus": "out_of_stock",
    "directPurchaseLink": "https://www.ldlc.com/fiche/PB15921567.html"
}

完整输出

var result = jsonObj.searchedProducts.featuredProduct;

{
    "displayName": "NVIDIA RTX 3080",
    "totalCount": 1,
    "productID": 30045,
    "imageURL": "https://assets.nvidia.partners/images/png/nvidia-geforce-rtx-3080.png",
    "productTitle": "NVIDIA GEFORCE RTX 3080",
    "digitialRiverID": "",
    "productSKU": "NVGFT080",
    "productUPC": "NVGFT080_FR",
    "productUPCOriginal": "NVGFT080",
    "productPrice": "€719.00",
    "productAvailable": false,
    "productRating": null,
    "customerReviewCount": null,
    "isFounderEdition": true,
    "isFeaturedProduct": true,
    "certified": false,
    "manufacturer": "NVIDIA",
    "locale": "FR",
    "isFeaturedProdcutFoundInSecondSearch": false,
    "category": "GPU",
    "gpu": "RTX 3080",
    "purchaseOption": "",
    "prdStatus": "out_of_stock",
    "minShipDays": null,
    "maxShipDays": null,
    "shipInfo": null,
    "isOffer": false,
    "offerText": "",
    "retailers": [
        {
            "productId": 30045,
            "productTitle": "NVIDIA GEFORCE RTX 3080",
            "logoUrl": "https://assets.nvidia.partners/logos/geforce/retailer-ldlc.png",
            "isAvailable": true,
            "salePrice": "719.00",
            "directPurchaseLink": "https://www.ldlc.com/fiche/PB15921567.html",
            "purchaseLink": "https://www.ldlc.com/fiche/PB15921567.html",
            "hasOffer": false,
            "offerText": null,
            "partnerId": "45",
            "storeId": "45",
            "upc": "NVGFT080_FR",
            "sku": "NVGFT080",
            "stock": 0,
            "retailerName": "https://www.ldlc.com",
            "type": 80
        }
    ],
    "productInfo": [
        {
            "name": "cooling_system",
            "value": "Fan"
        },
        {
            "name": "gpu_boost_clock_speed",
            "value": "1.71 GHz"
        },
        {
            "name": "gpu_memory_size",
            "value": "10 GB"
        }
    ],
    "compareProductInfo": [
        {
            "name": "cooling_system",
            "value": "Fan"
        },
        {
            "name": "gpu_clock_speed",
            "value": "1.44 GHz"
        },
        {
            "name": "gpu_boost_clock_speed",
            "value": "1.71 GHz"
        },
        {
            "name": "gpu_memory_size",
            "value": "10 GB"
        }
    ]
}

    public class NvidiaRoot
    {
        public object categories { get; set; }
        public List<Filter> filters { get; set; }
        public object filterGroups { get; set; }
        public object search { get; set; }
        public string version { get; set; }
        public List<Sort> sort { get; set; }
        public Pagination pagination { get; set; }
        public SearchedProducts searchedProducts { get; set; }
        public Disclaimer disclaimer { get; set; }
    }

    public class FilterValue
    {
        public string dispValue { get; set; }
        public object dispValueDesription { get; set; }
        public object groupType { get; set; }
        public int units { get; set; }
        public bool @checked { get; set; }
        public object imageURL { get; set; }
        public bool isValidate { get; set; }
    }

    public class Filter
    {
        public string displayName { get; set; }
        public string filterField { get; set; }
        public string displayMaxValues { get; set; }
        public string fieldType { get; set; }
        public int? selectedMinRangeVal { get; set; }
        public int? selectedMaxRangeVal { get; set; }
        public int? defaultMinRangeVal { get; set; }
        public int? defaultMaxRangeVal { get; set; }
        public string unitsOfMeasure { get; set; }
        public bool @checked { get; set; }
        public object units { get; set; }
        public List<FilterValue> filterValues { get; set; }
        public string dataType { get; set; }
        public bool showCount { get; set; }
        public int filterDisplayOrder { get; set; }
    }

    public class Sort
    {
        public string displayName { get; set; }
        public string value { get; set; }
        public bool selected { get; set; }
    }

    public class Pagination
    {
        public int page { get; set; }
        public int limit { get; set; }
        public int totalRecords { get; set; }
        public bool featuredProductIncludedInCount { get; set; }
    }

    public class Retailer
    {
        public int productId { get; set; }
        public string productTitle { get; set; }
        public string logoUrl { get; set; }
        public bool isAvailable { get; set; }
        public string salePrice { get; set; }
        public string directPurchaseLink { get; set; }
        public string purchaseLink { get; set; }
        public bool hasOffer { get; set; }
        public object offerText { get; set; }
        public string partnerId { get; set; }
        public string storeId { get; set; }
        public string upc { get; set; }
        public string sku { get; set; }
        public int stock { get; set; }
        public string retailerName { get; set; }
        public int type { get; set; }
    }

    public class ProductInfo
    {
        public string name { get; set; }
        public string value { get; set; }
    }

    public class CompareProductInfo
    {
        public string name { get; set; }
        public string value { get; set; }
    }

    public class FeaturedProduct
    {
        public string displayName { get; set; }
        public int totalCount { get; set; }
        public int productID { get; set; }
        public string imageURL { get; set; }
        public string productTitle { get; set; }
        public string digitialRiverID { get; set; }
        public string productSKU { get; set; }
        public string productUPC { get; set; }
        public string productUPCOriginal { get; set; }
        public string productPrice { get; set; }
        public bool productAvailable { get; set; }
        public object productRating { get; set; }
        public object customerReviewCount { get; set; }
        public bool isFounderEdition { get; set; }
        public bool isFeaturedProduct { get; set; }
        public bool certified { get; set; }
        public string manufacturer { get; set; }
        public string locale { get; set; }
        public bool isFeaturedProdcutFoundInSecondSearch { get; set; }
        public string category { get; set; }
        public string gpu { get; set; }
        public string purchaseOption { get; set; }
        public string prdStatus { get; set; }
        public object minShipDays { get; set; }
        public object maxShipDays { get; set; }
        public object shipInfo { get; set; }
        public bool isOffer { get; set; }
        public string offerText { get; set; }
        public List<Retailer> retailers { get; set; }
        public List<ProductInfo> productInfo { get; set; }
        public List<CompareProductInfo> compareProductInfo { get; set; }
    }

    public class ProductDetail
    {
        public string displayName { get; set; }
        public int totalCount { get; set; }
        public int productID { get; set; }
        public string imageURL { get; set; }
        public string productTitle { get; set; }
        public string digitialRiverID { get; set; }
        public string productSKU { get; set; }
        public string productUPC { get; set; }
        public string productUPCOriginal { get; set; }
        public string productPrice { get; set; }
        public bool productAvailable { get; set; }
        public object productRating { get; set; }
        public object customerReviewCount { get; set; }
        public bool isFounderEdition { get; set; }
        public bool isFeaturedProduct { get; set; }
        public bool certified { get; set; }
        public string manufacturer { get; set; }
        public string locale { get; set; }
        public bool isFeaturedProdcutFoundInSecondSearch { get; set; }
        public string category { get; set; }
        public string gpu { get; set; }
        public string purchaseOption { get; set; }
        public string prdStatus { get; set; }
        public object minShipDays { get; set; }
        public object maxShipDays { get; set; }
        public object shipInfo { get; set; }
        public bool isOffer { get; set; }
        public string offerText { get; set; }
        public List<Retailer> retailers { get; set; }
        public List<ProductInfo> productInfo { get; set; }
        public List<CompareProductInfo> compareProductInfo { get; set; }
    }

    public class SearchedProducts
    {
        public int totalProducts { get; set; }
        public bool featuredProductIncludedInCount { get; set; }
        public bool featuredProductsFlag { get; set; }
        public FeaturedProduct featuredProduct { get; set; }
        public List<ProductDetail> productDetails { get; set; }
        public List<object> suggestedProductDetails { get; set; }
    }

    public class Disclaimer
    {
        public string text { get; set; }
    }




【讨论】:

  • 感谢您的回答。 json反序列化功能需要创建这么重的类架构吗?因为我只需要 3 个字段。在这种情况下,反序列化功能仍然是正确的解决方案吗?我的问题是将 FeaturedProduct 和 SearchedProducts 的数据整合在一起。在您的示例中,未列出 FeaturedProduct (rtx 3080)。提前谢谢你
【解决方案2】:

你可以试试下面的代码。

获得特色产品。示例工作代码Here

var jsonParse = JObject.Parse(json);

var featuredProduct = jsonParse["searchedProducts"]["featuredProduct"];
var f = new CarteGraphique
{
     displayName = featuredProduct["displayName"].ToString(),
     prdStatus = featuredProduct["prdStatus"].ToString(),
     directPurchaseLink = featuredProduct["retailers"][0]["directPurchaseLink"].ToString()
};
Console.WriteLine("Featured Product Details : " + f.displayName + ", " + f.prdStatus + ", " + f.directPurchaseLink);

【讨论】:

    猜你喜欢
    • 2021-12-26
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2023-03-24
    • 2012-09-09
    • 1970-01-01
    相关资源
    最近更新 更多