RESTful Web サービスの作成に関して WebAPI を試している間、1 つのことが一貫して私を悩ませてきました: Null 非許容型をどうするか?
オブジェクトの例:
public class Product {
public Guid Id {get; set;}
public string Name {get; set;}
public decimal Price {get; set;}
public bool InStock {get; set;}
}
コントローラーメソッドの例:
public void Put (Product product){
productRepository.Update(product);
}
json 呼び出し PUT の例:
{
"Id": "8E28961C-C99E-4EED-9F33-44D33C107A33",
"Name": "Generic Bottled Water"
}
そのため、現在、ジレンマが残っています。json 呼び出しには、リクエストにPrice
またはInStock
プロパティが含まれていないため、デシリアライズされたPrice=0
およびInstock=false
. この段階では、これらの値が意図的に設定されているのか、または存在しないためにデフォルト設定されているのかを知ることができないため、リクエストを検証することは不可能です。
それらをNULL可能にしましょう!ギャラリーから誰かが泣くのが聞こえます。はい、確かに?
、各宣言の最後に少し追加することで、すべての値の型を null 可能にすることができました。しかし、これはひどい考えであり、null 許容型の乱用です。モデル ビュー コントロールは何らかの理由で分離されており、コントローラーがモデルを使用する方法をモデルが気にする必要がある場合は、懸念の分離が無効になっています。
強制的にすべてのプロパティを通過させてください! 他の誰かが泣いているのが聞こえます。ただし、余分なデータが飛び交うため、帯域幅の浪費につながります。
それで、答えは何ですか。この問題に関する私の 2 セントは、コントローラーのためにコア モデルを危険にさらしたくない場合、また、API コンシューマーに毎回完全なオブジェクトを送信するよう強制したくない場合は、1 つが残るということです。解決。
渡されたものはすべてコレクションにシリアル化され、コレクションを検証して、必要なすべてのプロパティが存在するかどうかを判断します。したがって、次のようになる可能性があります。
public void Put (Guid productId, Dictionary<string, object> productDictionary){
...retrieve and validate existing product.
if (productDictionary.ContainsKey("Price"))
existingProduct.Price = productDictionary["Price"];
if (productDictionary.ContainsKey("InStock"))
existingProduct.Price = productDictionary["InStock"];
productRepository.Update(existingProduct);
}
正直なところ、私はこの方法が特に好きではありませんが、実際の代替手段は見当たりません。すべてのオブジェクト プロパティを null 可能にしたくはありませんし、クライアントにすべてのデータを強制的に通過させたくもありません。
この問題を回避する方法について、より良い提案はありますか? おそらく、私が見逃している検証句またはライブラリがありますか? これに対処できるアーキテクチャパターンはありますか?
オブジェクト モデルへのシリアライゼーションは、少し間違った経済だと本当に感じています。
編集
DTO を調査していて、それらが今後の道だとは本当に思わないので、この質問を再開しました。それらは複雑さを増し、保守性を低下させますが、同時に、辞書やコレクション以上のものを提供することはありません。