创建新的 IHttpActionResult 操作结果方法
Posted
技术标签:
【中文标题】创建新的 IHttpActionResult 操作结果方法【英文标题】:Creating new IHttpActionResult action result methods 【发布时间】:2015-04-05 06:11:45 【问题描述】:有没有办法可以使用新的IHttpActionResult
接口返回HttpStatusCode.NoContent
响应消息?
我目前正在使用return new HttpResponseMessage( HttpStatusCode.NoContent );
并希望将其转换为return NoContent();
。
IHttpActionResult
已经有 Ok()
、Conflict()
和 NotFound()
,但我找不到需要在我的项目中使用的 Forbidden()
和 NoContent()
。
添加其他结果类型有多容易?
【问题讨论】:
【参考方案1】:这对我很有效:
public class CodeAndReason : IHttpActionResult
private readonly HttpStatusCode code;
private readonly string reason;
public CodeAndReason(HttpStatusCode code, string reason)
this.code = code;
this.reason = reason;
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
var response = new HttpResponseMessage(code)
ReasonPhrase = reason,
Content = new StringContent(reason),
;
return Task.FromResult(response);
public static IHttpActionResult NotFound(string reason)
return new CodeAndReason(HttpStatusCode.NotFound, reason);
public static IHttpActionResult Conflict(string reason)
return new CodeAndReason(HttpStatusCode.Conflict, reason);
public static IHttpActionResult Unauthorized(string reason)
return new CodeAndReason(HttpStatusCode.Unauthorized, reason);
用作:
return CodeAndReason.NotFound("Record blah not found");
【讨论】:
【参考方案2】:您现在可以使用以下(.Net 标准):
return StatusCode(HttpStatusCode.NoContent);
或(.Net Core 2.1+)
return NoContent();
【讨论】:
【参考方案3】:我尝试了@Intrepid 实现,但遇到了一些问题。我在这里看到两种解决方案:
解决方案 1:
该部分:return Forbidden();
不应该工作。
编译器无法识别。
应该是:return new ForbiddenResult(Request, "my reason");
更新 1
解决方案 2:
我认为这是@Interpid 在他的实现中的意图,但他遗漏了一些东西。
为了使用return Forbidden();
,CommonApiController
应该使用为Forbidden
和NoContent
返回自定义IHttpActionResult
的函数进行更新
该类应如下所示:
public abstract class CommonApiController: ApiController
protected ForbiddenResult Forbidden()
return new ForbiddenResult(this.Request);
protected ForbiddenResult Forbidden(string reason)
return new ForbiddenResult(this.Request, reason);
protected NoContentResult NoContent()
return new NoContentResult(this.Request);
public class ForbiddenResult: IHttpActionResult
private readonly HttpRequestMessage _request;
private readonly string _reason;
public ForbiddenResult(HttpRequestMessage request, string reason)
_request = request;
_reason = reason;
public ForbiddenResult(HttpRequestMessage request)
_request = request;
_reason = "Forbidden";
public Task < HttpResponseMessage > ExecuteAsync(CancellationToken cancellationToken)
var response = _request.CreateResponse(HttpStatusCode.Forbidden, _reason);
return Task.FromResult(response);
public class NoContentResult: IHttpActionResult
private readonly HttpRequestMessage _request;
private readonly string _reason;
public NoContentResult(HttpRequestMessage request, string reason)
_request = request;
_reason = reason;
public NoContentResult(HttpRequestMessage request)
_request = request;
_reason = "No Content";
public Task < HttpResponseMessage > ExecuteAsync(CancellationToken cancellationToken)
var response = _request.CreateResponse(HttpStatusCode.NoContent, _reason);
return Task.FromResult(response);
无论如何,如果我错了,@Interpid 的回答是正确的。为了使他的实施工作,我在这里缺少什么?
【讨论】:
更新了答案。添加了另一个替代解决方案。我认为第二个解决方案是@Interpid 最初的意思。 我认为您的想法是正确的。这应该是公认的答案。 注意:您不应返回带有 204 No Content 的内容正文。我会从代码中删除“受保护的 NoContentResult NoContent(字符串原因)”方法。请参阅***.com/a/23374724/2463738 了解更多信息。 @valentin 注意。我更新了问题。感谢您的关注【参考方案4】:no-content
结果没有方便的方法,因为默认情况下,当操作返回 void
时,响应将具有 HTTP 状态 204。
如果您希望在操作中明确指出这一点,您还可以从您的操作中返回 StatusCode(HttpStatusCode.NoContent)
或
ResponseMessage(new HttpResponseMessage(HttpStatusCode.NoContent)).
Unauthorized() 便捷方法为您提供 401 状态,因此,对于 Forbidden (403),您还必须使用 StatusCode(HttpStatusCode.Forbidden)
或
ResponseMessage(new HttpResponseMessage(HttpStatusCode.Forbidden))
【讨论】:
未经授权=401。禁止=403。 很好,这是最好的回应。 在某些情况下返回void
不是一个选项,因为您希望在验证中使用 BadRequest 或其他一些状态代码进行响应,仅在成功时发送 NoContent。返回StatusCode(HttpStatusCode.NoContent)
为我解决了这个问题,这是一个比公认答案更干净的解决方案。【参考方案5】:
如果您想在响应中包含原因短语而不向 ApiController 添加子类,请构建一个 ResponseMessage 对象并通过 ResponseMessage() 方法从操作中返回它。试试这个:
public class InvoiceController : ApiController
public async Task<IHttpActionResult> Post([FromBody]Invoice invoice)
if(User.IsInRole("Readonly"))
var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
response.ReasonPhrase = "User has the Readonly role";
return ResponseMessage(response);
// Rest of code
【讨论】:
【参考方案6】:我发现了这个example site,它展示了如何添加自定义的IHttpActionResult
方法,我已经使用它成功地创建了Forbidden()
和NoContent()
方法。
public abstract class CommonApiController : ApiController
public class ForbiddenResult : IHttpActionResult
private readonly HttpRequestMessage _request;
private readonly string _reason;
public ForbiddenResult(HttpRequestMessage request,string reason)
_request = request;
_reason = reason;
public ForbiddenResult(HttpRequestMessage request)
_request = request;
_reason = "Forbidden";
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
var response = _request.CreateResponse(HttpStatusCode.Forbidden,_reason);
return Task.FromResult(response);
public class NoContentResult : IHttpActionResult
private readonly HttpRequestMessage _request;
private readonly string _reason;
public NoContentResult(HttpRequestMessage request,string reason)
_request = request;
_reason = reason;
public NoContentResult(HttpRequestMessage request)
_request = request;
_reason = "No Content";
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
var response = _request.CreateResponse(HttpStatusCode.NoContent,_reason);
return Task.FromResult(response);
然后我可以这样使用它:
public class InvoiceController : CommonApiController
public async Task<IHttpActionResult> Post([FromBody]Invoice invoice)
if(User.IsInRole("Readonly"))
return Forbidden();
// Rest of code
【讨论】:
以上是关于创建新的 IHttpActionResult 操作结果方法的主要内容,如果未能解决你的问题,请参考以下文章
返回 IHttpActionResult 时如何对 Web api 操作方法进行单元测试?
将HttpResponseBase转换为IHttpActionResult
使用 c# 使用 IHttpActionResult 将请求类型作为 XML 发送
[使用C#使用IHttpActionResult将请求类型发送为XML