Return Web 中的对象以及 409 冲突错误 API 2 POST 由 Entity Framework 支持的调用?
Return an object along with a 409 Conflict error in a Web API 2 POST call backed by Entity Framework?
我有一个 C# Entity Framework Web API 2 控制器。当前,当尝试通过 POST 方法为主文本字段创建具有相同文本的对象时,我 return a 409 冲突错误 作为 StatusCode 结果表明添加被认为是重复的。
我想要做的是 return 触发重复错误的服务器端对象。所以我需要一些类似于 Ok() 方法的东西,但是 return 的变体 409 Conflict 错误作为 HTTP 状态代码 而不是 HTTP OK 状态代码。
有这种事吗?我怎样才能做到这一点?如果我能做到这一点,客户端就不必在收到 409 冲突错误后对服务器进行后续 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);
}
编辑:此解决方案适用于 v5 之前的 WebApi,如果您使用的是 v5 或更高版本,请参阅 。
您可以 return 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);
}
我遇到了与 ASP.NET Core 1.0 RC2 类似的问题,但是我遇到了 DbUpdateConcurrencyException
,使用乐观并发我不想让我的用户更新已经更新的对象。
我还想 return 更新后的对象给调用的用户。我可以创建一个新的 CreatedAtAction
并将 StatusCode
设置为 StatusCodes.Status409Conflict
context.Entry(user).State = EntityState.Modified;
try
{
await context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!UserExists(id))
{
return NotFound();
}
else
{
//remove the user we just added, otherwise it will not goto
//the database to obtain the updated user
context.Entry(user).State = EntityState.Detached;
var updatedUser = await context.Users.SingleOrDefaultAsync(m => m.Id == id);
if (updatedUser == null)
{
return NotFound();
}
var returnAction = CreatedAtAction("PutUser", new { id = user.Id }, updatedUser);
returnAction.StatusCode = StatusCodes.Status409Conflict;
return returnAction;
}
}
你应该return内容:
return Content(HttpStatusCode.Conflict, original);
Content
是 ApiController
class 上的方法,它将使用提供的 HttpStatusCode
和内容创建 NegotiatedContentResult
。无需像接受的答案那样在 ApiController class 上创建自己的扩展方法。
来到这里寻求有关 ASP.NET 核心 HTTP 409 的帮助 - 这是相关的,只是解决相同问题的新方法。
冲突操作结果
return Conflict(new { message = $"An existing record with the id '{id}' was already found."});
我有一个 C# Entity Framework Web API 2 控制器。当前,当尝试通过 POST 方法为主文本字段创建具有相同文本的对象时,我 return a 409 冲突错误 作为 StatusCode 结果表明添加被认为是重复的。
我想要做的是 return 触发重复错误的服务器端对象。所以我需要一些类似于 Ok() 方法的东西,但是 return 的变体 409 Conflict 错误作为 HTTP 状态代码 而不是 HTTP OK 状态代码。
有这种事吗?我怎样才能做到这一点?如果我能做到这一点,客户端就不必在收到 409 冲突错误后对服务器进行后续 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);
}
编辑:此解决方案适用于 v5 之前的 WebApi,如果您使用的是 v5 或更高版本,请参阅
您可以 return 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);
}
我遇到了与 ASP.NET Core 1.0 RC2 类似的问题,但是我遇到了 DbUpdateConcurrencyException
,使用乐观并发我不想让我的用户更新已经更新的对象。
我还想 return 更新后的对象给调用的用户。我可以创建一个新的 CreatedAtAction
并将 StatusCode
设置为 StatusCodes.Status409Conflict
context.Entry(user).State = EntityState.Modified;
try
{
await context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!UserExists(id))
{
return NotFound();
}
else
{
//remove the user we just added, otherwise it will not goto
//the database to obtain the updated user
context.Entry(user).State = EntityState.Detached;
var updatedUser = await context.Users.SingleOrDefaultAsync(m => m.Id == id);
if (updatedUser == null)
{
return NotFound();
}
var returnAction = CreatedAtAction("PutUser", new { id = user.Id }, updatedUser);
returnAction.StatusCode = StatusCodes.Status409Conflict;
return returnAction;
}
}
你应该return内容:
return Content(HttpStatusCode.Conflict, original);
Content
是 ApiController
class 上的方法,它将使用提供的 HttpStatusCode
和内容创建 NegotiatedContentResult
。无需像接受的答案那样在 ApiController class 上创建自己的扩展方法。
来到这里寻求有关 ASP.NET 核心 HTTP 409 的帮助 - 这是相关的,只是解决相同问题的新方法。
冲突操作结果
return Conflict(new { message = $"An existing record with the id '{id}' was already found."});