有没有办法可以使用新的IHttpActionResult
界面返回HttpStatusCode.NoContent
响应消息?
我目前正在使用return new HttpResponseMessage( HttpStatusCode.NoContent );
并希望将其转换为return NoContent();
。
IHttpActionResult
已经有Ok()
,Conflict()
和NotFound()
,但我无法找到我需要使用的Forbidden()
和NoContent()
在我的项目中。
添加其他结果类型有多容易?
答案 0 :(得分:47)
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))
答案 1 :(得分:24)
我发现此example site显示了如何添加自定义IHttpActionResult
方法,并且我已经使用它来创建Forbidden()
和NoContent()
方法并取得了巨大成功。< / p>
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
}
}
答案 2 :(得分:8)
我尝试了@Intrepid实现,但遇到了一些问题。我在这里看到两个解决方案:
解决方案1:
部分:return Forbidden();
不应该有用。
编译器无法识别这一点。
应该是:return new ForbiddenResult(Request, "my reason");
更新1
解决方案2:
我认为这是@Interpid在实施中的意图,但他遗漏了一些东西。
要使用return Forbidden();
,CommonApiController
应使用返回IHttpActionResult
和Forbidden
的自定义NoContent
的函数进行更新
该课程应如下所示:
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的回答是正确的。我在这里错过了什么让他的实施工作?
答案 3 :(得分:3)
如果要在不向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
}
}
答案 4 :(得分:1)
您现在可以使用以下(.Net标准):
return StatusCode(HttpStatusCode.NoContent);
或(.Net Core 2.1 +)
return NoContent();
答案 5 :(得分:0)
这对我来说很好:
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");