3

c# と json.net を使用して、OctoPart API ( http://octopart.com/api/docs/v3/rest-api ) からの結果を逆シリアル化しようとしています。

大部分のデータを逆シリアル化しても問題はありませんが、Part.specs 属性 ( http://octopart.com/api/docs/v3/rest-api#notes-part.specs )で問題が発生しています。返品する商品によって変わります。

Part.Specs に関する API の内容は次のとおりです。

Part インスタンスに添付された specs 属性は、属性の短い名前 ("voltage_rating_dc" など) をQualitativeValueおよびQuantitativeValueインスタンスにマッピングする JSON オブジェクトです。
(Qual|Quant)itativeValue オブジェクトの値プロパティはすべて JSON 配列であることに注意してください。これは、複数の出力電圧を持つ電源などの多値属性に対応するためです。

クラスを維持したいので、カスタム JConverter を実装する必要があると思いますか? 私はこの質問を見ていましたが、属性を QualitativeValue / QuantitativeValue クラスに逆シリアル化できるため、この例に適用する方法がよくわかりませんでした

これが私のパートクラスです

public class Part
{
    public string __class__ { get; set; }
    public string uid { get; set; }
    public long uid_v2 { get; set; }
    public string mpn { get; set; }
    public Manufacturer manufacturer { get; set; }
    public Brand brand { get; set; }
    public string octopart_url { get; set; }
    public List<PartOffer> offers { get; set; }
    public List<Datasheet> datasheets { get; set; }
    public List<ComplianceDocument> compliance_documents { get; set; }
    public List<Description> descriptions { get; set; }
    public List<ImageSet> imagesets { get; set; }
    public Dictionary<string, string> specs { get; set; }
    public List<string> category_uids { get; set; }
    public List<ExternalLinks> external_links { get; set; }
}

API からの結果 (PartsMatchResponse) の例を次に示します。

{
    "__class__": "PartsMatchResponse",
    "msec": 183,
    "request": {
        "__class__": "PartsMatchRequest",
        "exact_only": false,
        "queries": [
            {
                "__class__": "PartsMatchQuery",
                "brand": null,
                "limit": 10,
                "mpn": "ERJ8BWFR010V",
                "mpn_or_sku": null,
                "q": "",
                "reference": null,
                "seller": null,
                "sku": null,
                "start": 0
            }
        ]
    },
    "results": [
        {
            "__class__": "PartsMatchResult",
            "error": null,
            "hits": 1,
            "items": [
                {
                    "__class__": "Part",
                    "brand": {
                        "__class__": "Brand",
                        "name": "Panasonic - ECG",
                        "uid": "4c528d5878c09b95"
                    },
                    "category_uids": [
                        "7542b8484461ae85",
                        "cd01000bfc2916c6",
                        "5c6a91606d4187ad"
                    ],
                    "compliance_documents": [],
                    "datasheets": null,
                    "external_links": {
                        "__class__": "ExternalLinks",
                        "evalkit_url": null,
                        "freesample_url": null,
                        "product_url": null
                    },
                    "imagesets": null,
                    "manufacturer": {
                        "__class__": "Manufacturer",
                        "name": "Panasonic - ECG",
                        "uid": "c20a0700af7c11cd"
                    },
                    "mpn": "ERJ8BWFR010V",
                    "octopart_url": "http://octopart.com/erj8bwfr010v-panasonic+-+ecg-7979066",
                    "offers": null,
                    "specs": {
                        "case_package": {
                            "__class__": "QualitativeValue",
                            "attribution": {
                                "__class__": "Attribution",
                                "first_acquired": null,
                                "sources": []
                            },
                            "value": [
                                "1206"
                            ]
                        },
                        "case_package_si": {
                            "__class__": "QualitativeValue",
                            "attribution": {
                                "__class__": "Attribution",
                                "first_acquired": null,
                                "sources": []
                            },
                            "value": [
                                "3216"
                            ]
                        },
                        "lead_free_status": {
                            "__class__": "QualitativeValue",
                            "attribution": {
                                "__class__": "Attribution",
                                "first_acquired": null,
                                "sources": [
                                    {
                                        "__class__": "Source",
                                        "name": "Future Electronics",
                                        "uid": "e4032109c4f337c4"
                                    }
                                ]
                            },
                            "value": [
                                "Lead Free"
                            ]
                        },
                        "lifecycle_status": {
                            "__class__": "QualitativeValue",
                            "attribution": {
                                "__class__": "Attribution",
                                "first_acquired": null,
                                "sources": []
                            },
                            "value": [
                                "Not Listed by Manufacturer"
                            ]
                        },
                        "pin_count": {
                            "__class__": "QuantitativeValue",
                            "attribution": {
                                "__class__": "Attribution",
                                "first_acquired": null,
                                "sources": [
                                    {
                                        "__class__": "Source",
                                        "name": "Farnell",
                                        "uid": "58989d9272cd8b5f"
                                    }
                                ]
                            },
                            "max_value": null,
                            "min_value": null,
                            "unit": null,
                            "value": [
                                "2"
                            ]
                        },
                        "power_rating": {
                            "__class__": "QuantitativeValue",
                            "attribution": {
                                "__class__": "Attribution",
                                "first_acquired": null,
                                "sources": [
                                    {
                                        "__class__": "Source",
                                        "name": "Newark",
                                        "uid": "d294179ef2900153"
                                    }
                                ]
                            },
                            "max_value": null,
                            "min_value": null,
                            "unit": null,
                            "value": [
                                "0.5"
                            ]
                        },
                        "resistance": {
                            "__class__": "QuantitativeValue",
                            "attribution": {
                                "__class__": "Attribution",
                                "first_acquired": null,
                                "sources": [
                                    {
                                        "__class__": "Source",
                                        "name": "Farnell",
                                        "uid": "58989d9272cd8b5f"
                                    }
                                ]
                            },
                            "max_value": null,
                            "min_value": null,
                            "unit": null,
                            "value": [
                                "0.01"
                            ]
                        },
                        "resistance_tolerance": {
                            "__class__": "QualitativeValue",
                            "attribution": {
                                "__class__": "Attribution",
                                "first_acquired": null,
                                "sources": []
                            },
                            "value": [
                                "\u00b11%"
                            ]
                        },
                        "rohs_status": {
                            "__class__": "QualitativeValue",
                            "attribution": {
                                "__class__": "Attribution",
                                "first_acquired": null,
                                "sources": [
                                    {
                                        "__class__": "Source",
                                        "name": "Newark",
                                        "uid": "d294179ef2900153"
                                    }
                                ]
                            },
                            "value": [
                                "Compliant"
                            ]
                        }
                    },
                    "uid": "69e8a09b8cb4b62f",
                    "uid_v2": 797906654705
                }
            ],
            "reference": null
        }
    ]
}
4

2 に答える 2

1

JsonConverterはい、これを解決するにはカスタムが必要です。基本的にあなたがする必要があるのはこれです:

  1. QualitativeValueとクラスを定義QuantitativeValueして、共通の基本クラス (例: AbstractQValue) またはインターフェイスを持ちます。
  2. Partsクラスで、specsプロパティを a にしますDictionary<string, AbstractQValue>。これにより、属性名の変更が処理されます。
  3. JsonConverter具体的なインスタンス化を処理するカスタムを作成するQualitativeValueか、JSONQuantitativeValueの属性に基づいてカスタムを作成します。これを実装する方法の例については、この回答__class__を参照してください。
  4. 最後に、逆シリアル化を行うときは、カスタムのインスタンスをメソッドに渡すようにしてJsonConverterくださいJsonConvert.DeserializeObject

デモ

少し時間があったので、実際の例をまとめました。データのクラス定義は次のとおりです (簡潔にするために、無関係なもののほとんどを切り取っています)。

public class PartsMatchResponse
{
    public List<PartsMatchResult> results { get; set; }
}

public class PartsMatchResult
{
    public List<Part> items { get; set; }
}

public class Part
{
    public Manufacturer manufacturer { get; set; }
    public string mpn { get; set; }
    public Dictionary<string, AbstractQValue> specs { get; set; }
}

public class Manufacturer
{
    public string name { get; set; }
}

public abstract class AbstractQValue
{
    public List<string> value { get; set; }
}

public class QualitativeValue : AbstractQValue
{
}

public class QuantitativeValue : AbstractQValue
{
    public string unit { get; set; }
}

カスタムJsonConverterクラスは次のとおりです。

public class QValueJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(AbstractQValue).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, 
        Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        if (jo["__class__"].ToString() == "QuantitativeValue")
        {
            return jo.ToObject<QuantitativeValue>();
        }
        return jo.ToObject<QualitativeValue>();
    }

    public override void WriteJson(JsonWriter writer, 
        object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

デシリアライズ時にコンバーターを使用する方法を示すデモ プログラムを次に示します。

class Program
{
    static void Main(string[] args)
    {
        // (jsonString is defined as a constant below)

        PartsMatchResponse response = 
            JsonConvert.DeserializeObject<PartsMatchResponse>(jsonString, 
                new QValueJsonConverter());

        foreach (Part part in response.results[0].items)
        {
            Console.WriteLine("manufacturer: " + part.manufacturer.name);
            Console.WriteLine("mfr. part no: " + part.mpn);
            foreach (KeyValuePair<string, AbstractQValue> kvp in part.specs)
            {
                string unit = "";
                if (kvp.Value is QuantitativeValue) 
                    unit = ((QuantitativeValue)kvp.Value).unit;

                Console.WriteLine(kvp.Key + ": " + 
                    string.Join(", ", kvp.Value.value) + " " + unit);
            }
            Console.WriteLine();
        }
    }

    // Note: this is the same as the example JSON in the question, except 
    // I added units for some of the QuantitativeValue specs for demo purposes.

    const string jsonString = @"
        {
            ""__class__"": ""PartsMatchResponse"",
            ""msec"": 183,
            ""request"": {
                ""__class__"": ""PartsMatchRequest"",
                ""exact_only"": false,
                ""queries"": [
                    {
                        ""__class__"": ""PartsMatchQuery"",
                        ""brand"": null,
                        ""limit"": 10,
                        ""mpn"": ""ERJ8BWFR010V"",
                        ""mpn_or_sku"": null,
                        ""q"": """",
                        ""reference"": null,
                        ""seller"": null,
                        ""sku"": null,
                        ""start"": 0
                    }
                ]
            },
            ""results"": [
                {
                    ""__class__"": ""PartsMatchResult"",
                    ""error"": null,
                    ""hits"": 1,
                    ""items"": [
                        {
                            ""__class__"": ""Part"",
                            ""brand"": {
                                ""__class__"": ""Brand"",
                                ""name"": ""Panasonic - ECG"",
                                ""uid"": ""4c528d5878c09b95""
                            },
                            ""category_uids"": [
                                ""7542b8484461ae85"",
                                ""cd01000bfc2916c6"",
                                ""5c6a91606d4187ad""
                            ],
                            ""compliance_documents"": [],
                            ""datasheets"": null,
                            ""external_links"": {
                                ""__class__"": ""ExternalLinks"",
                                ""evalkit_url"": null,
                                ""freesample_url"": null,
                                ""product_url"": null
                            },
                            ""imagesets"": null,
                            ""manufacturer"": {
                                ""__class__"": ""Manufacturer"",
                                ""name"": ""Panasonic - ECG"",
                                ""uid"": ""c20a0700af7c11cd""
                            },
                            ""mpn"": ""ERJ8BWFR010V"",
                            ""octopart_url"": ""http://octopart.com/erj8bwfr010v-panasonic+-+ecg-7979066"",
                            ""offers"": null,
                            ""specs"": {
                                ""case_package"": {
                                    ""__class__"": ""QualitativeValue"",
                                    ""attribution"": {
                                        ""__class__"": ""Attribution"",
                                        ""first_acquired"": null,
                                        ""sources"": []
                                    },
                                    ""value"": [
                                        ""1206""
                                    ]
                                },
                                ""case_package_si"": {
                                    ""__class__"": ""QualitativeValue"",
                                    ""attribution"": {
                                        ""__class__"": ""Attribution"",
                                        ""first_acquired"": null,
                                        ""sources"": []
                                    },
                                    ""value"": [
                                        ""3216""
                                    ]
                                },
                                ""lead_free_status"": {
                                    ""__class__"": ""QualitativeValue"",
                                    ""attribution"": {
                                        ""__class__"": ""Attribution"",
                                        ""first_acquired"": null,
                                        ""sources"": [
                                            {
                                                ""__class__"": ""Source"",
                                                ""name"": ""Future Electronics"",
                                                ""uid"": ""e4032109c4f337c4""
                                            }
                                        ]
                                    },
                                    ""value"": [
                                        ""Lead Free""
                                    ]
                                },
                                ""lifecycle_status"": {
                                    ""__class__"": ""QualitativeValue"",
                                    ""attribution"": {
                                        ""__class__"": ""Attribution"",
                                        ""first_acquired"": null,
                                        ""sources"": []
                                    },
                                    ""value"": [
                                        ""Not Listed by Manufacturer""
                                    ]
                                },
                                ""pin_count"": {
                                    ""__class__"": ""QuantitativeValue"",
                                    ""attribution"": {
                                        ""__class__"": ""Attribution"",
                                        ""first_acquired"": null,
                                        ""sources"": [
                                            {
                                                ""__class__"": ""Source"",
                                                ""name"": ""Farnell"",
                                                ""uid"": ""58989d9272cd8b5f""
                                            }
                                        ]
                                    },
                                    ""max_value"": null,
                                    ""min_value"": null,
                                    ""unit"": null,
                                    ""value"": [
                                        ""2""
                                    ]
                                },
                                ""power_rating"": {
                                    ""__class__"": ""QuantitativeValue"",
                                    ""attribution"": {
                                        ""__class__"": ""Attribution"",
                                        ""first_acquired"": null,
                                        ""sources"": [
                                            {
                                                ""__class__"": ""Source"",
                                                ""name"": ""Newark"",
                                                ""uid"": ""d294179ef2900153""
                                            }
                                        ]
                                    },
                                    ""max_value"": null,
                                    ""min_value"": null,
                                    ""unit"": ""Watt"",
                                    ""value"": [
                                        ""0.5""
                                    ]
                                },
                                ""resistance"": {
                                    ""__class__"": ""QuantitativeValue"",
                                    ""attribution"": {
                                        ""__class__"": ""Attribution"",
                                        ""first_acquired"": null,
                                        ""sources"": [
                                            {
                                                ""__class__"": ""Source"",
                                                ""name"": ""Farnell"",
                                                ""uid"": ""58989d9272cd8b5f""
                                            }
                                        ]
                                    },
                                    ""max_value"": null,
                                    ""min_value"": null,
                                    ""unit"": ""Ohm"",
                                    ""value"": [
                                        ""0.01""
                                    ]
                                },
                                ""resistance_tolerance"": {
                                    ""__class__"": ""QualitativeValue"",
                                    ""attribution"": {
                                        ""__class__"": ""Attribution"",
                                        ""first_acquired"": null,
                                        ""sources"": []
                                    },
                                    ""value"": [
                                        ""\u00b11%""
                                    ]
                                },
                                ""rohs_status"": {
                                    ""__class__"": ""QualitativeValue"",
                                    ""attribution"": {
                                        ""__class__"": ""Attribution"",
                                        ""first_acquired"": null,
                                        ""sources"": [
                                            {
                                                ""__class__"": ""Source"",
                                                ""name"": ""Newark"",
                                                ""uid"": ""d294179ef2900153""
                                            }
                                        ]
                                    },
                                    ""value"": [
                                        ""Compliant""
                                    ]
                                }
                            },
                            ""uid"": ""69e8a09b8cb4b62f"",
                            ""uid_v2"": 797906654705
                        }
                    ],
                    ""reference"": null
                }
            ]
        }";
}

最後に、上記のプログラムの出力は次のとおりです。

manufacturer: Panasonic - ECG
mfr. part no: ERJ8BWFR010V
case_package: 1206
case_package_si: 3216
lead_free_status: Lead Free
lifecycle_status: Not Listed by Manufacturer
pin_count: 2
power_rating: 0.5 Watt
resistance: 0.01 Ohm
resistance_tolerance: ±1%
rohs_status: Compliant
于 2013-10-16T14:19:13.127 に答える
0

JSON をモデル化するには、これらのクラスが必要です。

public class OctopartObject
{
    public string __class__ { get; set; }
    public int msec { get; set; }
    public Request request { get; set; }
    public List<Result> results { get; set; }
}

public class Query
{
    public string __class__ { get; set; }
    public object brand { get; set; }
    public int limit { get; set; }
    public string mpn { get; set; }
    public object mpn_or_sku { get; set; }
    public string q { get; set; }
    public object reference { get; set; }
    public object seller { get; set; }
    public object sku { get; set; }
    public int start { get; set; }
}

public class Request
{
    public string __class__ { get; set; }
    public bool exact_only { get; set; }
    public List<Query> queries { get; set; }
}

public class Brand
{
    public string __class__ { get; set; }
    public string name { get; set; }
    public string uid { get; set; }
}

public class Manufacturer
{
    public string __class__ { get; set; }
    public string name { get; set; }
    public string uid { get; set; }
}

public class Item
{
    public string __class__ { get; set; }
    public Brand brand { get; set; }
    public Manufacturer manufacturer { get; set; }
    public string mpn { get; set; }
    public string octopart_url { get; set; }
    public List<object> offers { get; set; }
    public string uid { get; set; }
    public object uid_v2 { get; set; }
}

public class Result
{
    public string __class__ { get; set; }
    public object error { get; set; }
    public int hits { get; set; }
    public List<Item> items { get; set; }
    public object reference { get; set; }
}

次に、JSON.NET & .NET 4.5 を使用して、次のようにします。

HttpClient client = new HttpClient();

// Send a request asynchronously and continue when complete
HttpResponseMessage clientResult = await client.GetAsync(_address);

// Check that response was successful or throw exception
clientResult.EnsureSuccessStatusCode();

// Read response asynchronously as JToken and write out top facts for each country
string jsonString = await clientResult.Content.ReadAsStringAsync();

OctopartObject obj = JsonConvert.DeserializeObject<OctopartObject>(jsonString);

_address URI から受け取ったデータをモデル化する素敵なオブジェクトができます。

私はまだこれを完全にテストしていないので、いくつかの問題があるかもしれません. しかし、私はこれについて数時間苦労してきましたが、最終的にはうまくいっていると思われるものを見つけました。これは基本のみを返すため、データシートや追加のフィールドでは機能しないと確信しています。しかし、基本的にはこのサイトを使用してオブジェクト モデルを取得し、ルート モデルの名前を OctopartObject に変更しました。

于 2013-10-28T22:13:40.480 に答える