C#エンティティフレームワークWeb API 2コントローラーがあります。現在[〜#〜] post [〜#〜]メソッドを介してメインテキストフィールドに同じテキストを持つオブジェクトを作成しようとすると、409競合errorStatusCode結果として、追加が重複と見なされることを示します。
私がやりたいのは、重複エラーをトリガーしたサーバー側オブジェクトも返すことです。したがって、Ok()メソッドに似たものが必要ですが、代わりに409 ConflictエラーをHTTPステータスコードとして返すバリアントHTTP OKステータスコード。
そんなことありますか?これどうやってするの?これを機能させることができれば、クライアントは409 Conflictエラーを受け取った後、既存のオブジェクトを取得するためにサーバーへの後続のGet呼び出しを行う必要はありません。
これが現在のPOSTメソッドです:
public IHttpActionResult PostCanonical(Canonical canonical)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Check for duplicate Canonical text for the same app name.
if (db.IsDuplicateCanonical(canonical.AppName, canonical.Text))
{
// It's a duplicate. Return an HTTP 409 Conflict error to let the client know.
return StatusCode(HttpStatusCode.Conflict);
}
db.CanonicalSentences.Add(canonical);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = canonical.ID }, canonical);
}
編集:このソリューションはWebApi以前のv5向けです。v5以上を使用している場合は this answer を参照してください。
NegotiatedContentResult<T>
を返すと、ステータスメッセージと、httpメッセージ本文に挿入するオブジェクトを指定できます。
コードを次のように変更します。
public IHttpActionResult PostCanonical(Canonical canonical)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Check for duplicate Canonical text for the same app name.
if (db.IsDuplicateCanonical(canonical.AppName, canonical.Text))
{
// It's a duplicate. Return an HTTP 409 Conflict error to let the client know.
var original = db.CanonicalSentences.First(c => c.ID == canonical.ID);
return new NegotiatedContentResult<T>(HttpStatusCode.Conflict, original, this);
}
db.CanonicalSentences.Add(canonical);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = canonical.ID }, canonical);
}
または、次のような拡張メソッドをラップすることもできます。
public static class HttpActionResultExtensions {
public static IHttpActionResult StatusCodeWithContent<T>(this ApiController @this, HttpStatusCode statusCode, T content) {
return new NegotiatedContentResult<T>(statusCode, content, @this);
}
}
そして、次のような拡張機能を使用します。
public IHttpActionResult PostCanonical(Canonical canonical)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Check for duplicate Canonical text for the same app name.
if (db.IsDuplicateCanonical(canonical.AppName, canonical.Text))
{
// It's a duplicate. Return an HTTP 409 Conflict error to let the client know.
var original = db.CanonicalSentences.First(c => c.ID == canonical.ID);
return StatusCodeWithContent(HttpStatusCode.Conflict, original)
}
db.CanonicalSentences.Add(canonical);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = canonical.ID }, canonical);
}
コンテンツを返す必要があります:
return Content(HttpStatusCode.Conflict, original);
Content
はApiController
クラスのメソッドであり、提供されたNegotiatedContentResult
とコンテンツを使用してHttpStatusCode
を作成します。受け入れられた回答のように、ApiControllerクラスに独自の拡張メソッドを作成する必要はありません。
ASP.NET Core HTTP 409のヘルプを探してここに到着しました-これは関連しており、この同じ問題を解決するための新しいアプローチです。
return Conflict(new { message = $"An existing record with the id '{id}' was already found."});