非常に単純な OData v4 コントローラーを作成しました。Pet
コントローラーには基本的に、次のエンティティの Entity Framework に基づく CRUD メソッドが含まれています。
public class Pet
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public int Age { get; set; }
}
ここで重要なことPet.Age
は、必須プロパティが null 非許容であることです。
コントローラー自体は次のとおりです (Post
メソッドのみが示されています)。
public class PetController : ODataController
{
private DatabaseContext db = new DatabaseContext();
// POST: odata/Pet
public IHttpActionResult Post(Pet pet)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Pet.Add(pet);
db.SaveChanges();
return Created(pet);
}
// Other controller methods go here...
}
そして、これは私のWebApiConfig
コントローラー構成です:
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Pet>("Pet");
config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
データベースに新しいものを作成したい場合は、次のようなリクエストPet
を発行します。POST
POST http://localhost:8080/odata/Pet
Content-type: application/json
{ Name: "Cat", Age: 5 }
ただし、JSON 要求ペイロードでプロパティを単純に省略できるAge
ため、JSON デシリアライザーは既定値の を使用しますが0
、400 Bad Request
代わりにステータスを返す必要があります。この問題はアンダーポスティングと呼ばれます。
通常の WebApi コントローラーを使用すると、簡単に解決できます (解決策については、こちらで説明しています)。を作成し、コントローラーが実際のエンティティPetViewModel
の代わりに を受け入れるようにするだけです。PetViewModel
Pet
public class PetViewModel
{
// Make the property nullable and set the Required attribute
// to distinguish between "zero" and "not set"
[Required]
public int? Age { get; set; }
// Other properties go here...
}
次に、コントローラーでエンティティに変換PetViewModel
しPet
、通常どおりデータベースに保存します。
残念ながら、このアプローチは OData コントローラーでは機能しません。メソッドをの代わりにPost
acceptに変更すると、次のエラーが表示されます。PetViewModel
Pet
System.Net.Http.UnsupportedMediaTypeException: MediaTypeFormatter を使用して、メディア タイプ 'application/json' のコンテンツからタイプ 'PetViewModel' のオブジェクトを読み取ることができません。
System.Net.Http.HttpContentExtensions.ReadAsAsync [T] (HttpContent コンテンツ、型の種類、IEnumerable'1 フォーマッター、IFormatterLogger formatterLogger、CancellationToken cancelToken) で
System.Net.Http.HttpContentExtensions.ReadAsAsync (HttpContent コンテンツ、型の種類、IEnumerable'1 フォーマッター、IFormatterLogger formatterLogger、CancellationToken cancelToken) で
System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync (HttpRequestMessage 要求、Type タイプ、IEnumerable`1 フォーマッター、IFormatterLogger formatterLogger、CancellationToken cancelToken) で
では、OData コントローラーを使用するときに過少投稿を防ぐ方法はありますか?