特定のプロパティをデシリアライズ。 JSON.NETを使ってこれを行うことはできますか?JSON.NETは、私は次のよう<code>JSON</code>のテキストを持っている
答えて
public T GetFirstInstance<T>(string propertyName, string json)
{
using (var stringReader = new StringReader(json))
using (var jsonReader = new JsonTextReader(stringReader))
{
while (jsonReader.Read())
{
if (jsonReader.TokenType == JsonToken.PropertyName
&& (string)jsonReader.Value == propertyName)
{
jsonReader.Read();
var serializer = new JsonSerializer();
return serializer.Deserialize<T>(jsonReader);
}
}
return default(T);
}
}
public class MyType
{
public string Text { get; set; }
}
public void Test()
{
string json = "{ \"PropOne\": { \"Text\": \"Data\" }, \"PropTwo\": \"Data2\" }";
MyType myType = GetFirstInstance<MyType>("PropOne", json);
Debug.WriteLine(myType.Text); // "Data"
}
このアプローチでは、オブジェクト全体をデシリアライズする必要がありません。しかし、これは、jsonがの場合には、大幅にであり、デシリアライズするプロパティが比較的早い場合にのみ、パフォーマンスが向上することに注意してください。それ以外の場合は、jcwrequests answerショーのように、すべてをデシリアライズして必要な部分を抜き出してください。
JsonIgnore
を使用すると、Json.Netによってプロパティが完全に無視され、シリアル化とデシリアライズの両方が行われます。
また、linkにチェックを入れてください。
私はむしろ、私は 'PropOne'と' PropTwo'を表す2つの別々のクラスを持っている、 'PropOne'と' PropTwo'の両方が含まれている複合オブジェクトを持っていません。 – Omar
オブジェクトをシリアル化していますか? – NomadTraveler
それが私がJSONを作成しているということを意味するならば、私はJSONを第三者に送ります。 – Omar
var json = "{ "PropOne": { "Text": "Data" } "PropTwo": "Data2" }";
JObject o = JObject.Parse(json);
var val = o.PropTwo;
JSON Linqプロバイダを使用すると、オブジェクトを既知の型に逆シリアル化する必要はありません。
JSONはそれほど大きくないので、私はMatt Johnsonの提案を受け取り、すべてを逆シリアル化します。
var jObject = JObject.Parse(json);
var jToken = jObject.GetValue("PropTwo");
PropTwoClass value = jToken.ToObject(typeof(PropTwoClass));
Omar's answerに簡単な解決策は、ラッパーを持っているだろう。答えをjcwrequestsのおかげで、私はこの方法を使用することができました。
class Wrapper
{
public PropOneClass PropOne;
}
JsonConvert.Deserialize<Wrapper>(json).PropOne
私のテストでは、約30%速くなっています。
Matt's answerこれはバグがありますが、はるかに速い解決方法です。 これを修正する試みです。 このメソッドは、ルートレベルで一致するプロパティのみを返します。 開始トークンと終了トークンのカウントにはまだまだ単純なアプローチがありますが、有効なJSONの場合はおそらく動作します。
Matt、これをあなたの答えに自由にコピーしてください。
public T GetFirstInstance<T>(string propertyName, string json)
{
using (var stringReader = new StringReader(json))
using (var jsonReader = new JsonTextReader(stringReader))
{
int level = 0;
while (jsonReader.Read())
{
switch (jsonReader.TokenType)
{
case JsonToken.PropertyName:
if (level != 1)
break;
if ((string)jsonReader.Value == propertyName)
{
jsonReader.Read();
return (T)jsonReader.Value;
}
break;
case JsonToken.StartArray:
case JsonToken.StartConstructor:
case JsonToken.StartObject:
level++;
break;
case JsonToken.EndArray:
case JsonToken.EndConstructor:
case JsonToken.EndObject:
level--;
break;
}
}
return default(T);
}
}
- 1. Json.NETは、私は次のようなJSON文字列を持っているランタイム
- 2. のみ、私は次のモデルを持っている場合Json.Net
- 3. は、私はこのようなクラス階層を持ってJSON.NET
- 4. JavaScriptのキャンバスは、私は次のような問題を持っているテキスト
- 5. は、私は次の内容のファイルを持っているテキスト
- 6. は、私は次のようexceptionHandlerのを持っている
- 7. 私はこのような性質とのインタフェースを持っているJSON.net
- 8. は、私は次のテキストを持っている}、{#内
- 9. は、ブートストラップ:私は、次のブートストラップコードを持っているテキスト
- 10. は、次のように私はクラスを持っているクラス
- 11. Pythonは次のように私はURLを持っている
- 12. は、私は、次のようなXMLファイルを持っている
- 13. は、次のように私は、ヘッダファイルを持っている
- 14. は、私は次のような問題を持っている
- 15. は、私は次のようにJSONオブジェクトを持っている
- 16. は、私は次のようなデータを持っているストリーム
- 17. は、私は次のように私は、目標を持っているのbuild.xmlを持っているのAnt
- 18. は、私は次のマークアップを持っている<a>タグ
- 19. 私は次のようなマークアップを持っているのdiv
- 20. 私は次のようなボタンを持っているjQueryの
- 21. 次のように私は、テーブルのデータを持っている
- 22. 次のように私は、XMLを持っているのjavascript
- 23. は、私は次のように持っている力componentDidMount
- 24. 私は、次のテキストをtxtファイル持っている辞書
- 25. 次のように私はテーブルを持っているハイブ
- 26. 、私は次のようなデータを持っているオブジェクト
- 27. 私は次のようにUiCollectionViewCellクラスを持っている
- 28. は、次のように私がイベントを持っているイベント
- 29. 私は次のような実装を持っているカテゴリ
- 30. JAXB、私は次のようなクラスを持っている
再利用性を向上させるために若干更新されました。 –
このメソッドは、ツリーのルートだけでなく、どのレベルでも最初のプロパティ "PropOne"をキャッチします。 レベルを追跡し、ルートレベルで正しいプロパティ名のみを受け入れることで修正できます。 – hultqvist
これは、デコードしているJSON文字列が何であるか不明な場合や、それを理解するためにプロパティを読み取る必要がある場合にも便利です。 – starbeamrainbowlabs