[解決済み] TryParse方式でjsonをデシリアライズする
2023-04-15 12:30:58
質問
私が所有していない)サービスにリクエストを送信すると、要求されたJSONデータで応答するか、または次のようなエラーで応答することがあります。
{
"error": {
"status": "error message",
"code": "999"
}
}
どちらの場合も、HTTPレスポンスコードは200 OKなので、これではエラーがあるかどうか判断できません。 そこで、次のようなものを用意しました。
bool TryParseResponseToError(string jsonResponse, out Error error)
{
// Check expected error keywords presence
// before try clause to avoid catch performance drawbacks
if (jsonResponse.Contains("error") &&
jsonResponse.Contains("status") &&
jsonResponse.Contains("code"))
{
try
{
error = new JsonSerializer<Error>().DeserializeFromString(jsonResponse);
return true;
}
catch
{
// The JSON response seemed to be an error, but failed to deserialize.
// Or, it may be a successful JSON response: do nothing.
}
}
error = null;
return false;
}
ここで、標準的な実行パスにあるかもしれない空のcatch節がありますが、これは悪い匂いです...。まあ、悪臭というより、臭いですね。
の良い方法をご存知ですか? "TryParse"。 を行うために、レスポンスを キャッチを避ける を避けるためです。
[EDIT】をご覧ください。]
感謝 Yuval Itzchakov の回答を見て、そのように改善しました。
bool TryParseResponse(string jsonResponse, out Error error)
{
// Check expected error keywords presence :
if (!jsonResponse.Contains("error") ||
!jsonResponse.Contains("status") ||
!jsonResponse.Contains("code"))
{
error = null;
return false;
}
// Check json schema :
const string errorJsonSchema =
@"{
'type': 'object',
'properties': {
'error': {'type':'object'},
'status': {'type': 'string'},
'code': {'type': 'string'}
},
'additionalProperties': false
}";
JsonSchema schema = JsonSchema.Parse(errorJsonSchema);
JObject jsonObject = JObject.Parse(jsonResponse);
if (!jsonObject.IsValid(schema))
{
error = null;
return false;
}
// Try to deserialize :
try
{
error = new JsonSerializer<Error>.DeserializeFromString(jsonResponse);
return true;
}
catch
{
// The JSON response seemed to be an error, but failed to deserialize.
// This case should not occur...
error = null;
return false;
}
}
catch節は残しておきました...念のため。
どのように解決するのですか?
とは
Json.NET
を使うと、スキーマに照らし合わせてjsonを検証することができます。
string schemaJson = @"{
'status': {'type': 'string'},
'error': {'type': 'string'},
'code': {'type': 'string'}
}";
JsonSchema schema = JsonSchema.Parse(schemaJson);
JObject jobj = JObject.Parse(yourJsonHere);
if (jobj.IsValid(schema))
{
// Do stuff
}
そして、それをTryParseメソッド内で使用します。
public static T TryParseJson<T>(this string json, string schema) where T : new()
{
JsonSchema parsedSchema = JsonSchema.Parse(schema);
JObject jObject = JObject.Parse(json);
return jObject.IsValid(parsedSchema) ?
JsonConvert.DeserializeObject<T>(json) : default(T);
}
では、そうしてください。
var myType = myJsonString.TryParseJson<AwsomeType>(schema);
更新しました。
スキーマ検証はNewtonsoft.Jsonのメインパッケージに含まれなくなったことに注意してください。 Newtonsoft.Json.Schemaを追加する必要があります。 パッケージを追加する必要があります。
更新2:
コメントにあるように、"JSONSchema" は価格モデルを持っています、つまり 無料ではありません。 . すべての情報を見ることができます はこちら
関連
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】ファイルやアセンブリ、またはその依存関係の1つをロードできませんでした。
-
[解決済み] 正しいJSONコンテンツタイプは何ですか?
-
[解決済み] JSONでコメントを使用することはできますか?
-
[解決済み] なぜGoogleはJSONレスポンスにwhile(1);を前置するのでしょうか?
-
[解決済み] cURLでJSONデータをPOSTするにはどうすればよいですか?
-
[解決済み] JavaScriptでJSONをきれいに印刷する
-
[解決済み] Microsoft JSONの日付はどのようにフォーマットするのですか?
-
[解決済み] .NETでC#オブジェクトをJSON文字列に変換するには?
-
[解決済み] JSONをC#のダイナミックオブジェクトにデシリアライズする?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C# [解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#.
-
[解決済み】トランスポート接続からデータを読み取れない:既存の接続は、リモートホストによって強制的に閉じられました。
-
[解決済み】バックスラッシュを含むパス文字列のエスケープシーケンスが認識されない件
-
[解決済み】C# - パスに不正な文字がある場合
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み】インデックスが範囲外でした。コレクションパラメータname:indexのサイズより小さく、非負でなければなりません。
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない
-
[解決済み】別のスレッドがこのオブジェクトを所有しているため、呼び出し側のスレッドはこのオブジェクトにアクセスできない
-
[解決済み] JSONをC#のダイナミックオブジェクトにデシリアライズする?