创建新的 IHttpActionResult 操作结果方法
Creating new IHttpActionResult action result methods
有没有一种方法可以使用新的 IHttpActionResult
界面来 return HttpStatusCode.NoContent
响应消息?
我目前正在使用 return new HttpResponseMessage( HttpStatusCode.NoContent );
并想将其转换为 return NoContent();
.
IHttpActionResult
已经有 Ok()
、Conflict()
和 NotFound()
,但我找不到我需要的 Forbidden()
和 NoContent()
在我的项目中使用。
添加其他结果类型是否容易?
no-content
结果没有便捷方法,因为默认情况下,当操作 return 时 void
,响应将具有 HTTP 状态 204。
如果您希望在操作中明确指出,您还可以 return 来自操作的 StatusCode(HttpStatusCode.NoContent)
或
ResponseMessage(new HttpResponseMessage(HttpStatusCode.NoContent)).
Unauthorized() 便捷方法为您提供 401 状态,因此,对于 Forbidden (403),您还必须使用 StatusCode(HttpStatusCode.Forbidden)
或
ResponseMessage(new HttpResponseMessage(HttpStatusCode.Forbidden))
我发现这个 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
}
}
如果您想在响应中包含原因短语而不向 ApiController 添加子class,请构建一个 ResponseMessage 对象,并通过 ResponseMessage() 方法从操作中 return 它。试试这个:
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
}
}
我尝试了@Intrepid 实现,但 运行 遇到了一些问题。我在这里看到两个解决方案:
解决方案一:
部分:return Forbidden();
不应该工作。
编译器无法识别。
应该是:return new ForbiddenResult(Request, "my reason");
更新 1
方案二:
我认为这是@Interpid 在他的实施中的意图,但他遗漏了一些东西。
为了使用 return Forbidden();
,CommonApiController
应该使用 return 自定义 IHttpActionResult
用于 Forbidden
和 [=17= 的功能进行更新]
class 应该是这样的:
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 的回答是正确的。为了使他的实施工作,我在这里缺少什么?
您现在可以使用以下 (.Net Standard):
return StatusCode(HttpStatusCode.NoContent);
或(.Net Core 2.1+)
return NoContent();
这对我来说效果很好:
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");
有没有一种方法可以使用新的 IHttpActionResult
界面来 return HttpStatusCode.NoContent
响应消息?
我目前正在使用 return new HttpResponseMessage( HttpStatusCode.NoContent );
并想将其转换为 return NoContent();
.
IHttpActionResult
已经有 Ok()
、Conflict()
和 NotFound()
,但我找不到我需要的 Forbidden()
和 NoContent()
在我的项目中使用。
添加其他结果类型是否容易?
no-content
结果没有便捷方法,因为默认情况下,当操作 return 时 void
,响应将具有 HTTP 状态 204。
如果您希望在操作中明确指出,您还可以 return 来自操作的 StatusCode(HttpStatusCode.NoContent)
或
ResponseMessage(new HttpResponseMessage(HttpStatusCode.NoContent)).
Unauthorized() 便捷方法为您提供 401 状态,因此,对于 Forbidden (403),您还必须使用 StatusCode(HttpStatusCode.Forbidden)
或
ResponseMessage(new HttpResponseMessage(HttpStatusCode.Forbidden))
我发现这个 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
}
}
如果您想在响应中包含原因短语而不向 ApiController 添加子class,请构建一个 ResponseMessage 对象,并通过 ResponseMessage() 方法从操作中 return 它。试试这个:
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
}
}
我尝试了@Intrepid 实现,但 运行 遇到了一些问题。我在这里看到两个解决方案:
解决方案一:
部分:return Forbidden();
不应该工作。
编译器无法识别。
应该是:return new ForbiddenResult(Request, "my reason");
更新 1
方案二:
我认为这是@Interpid 在他的实施中的意图,但他遗漏了一些东西。
为了使用 return Forbidden();
,CommonApiController
应该使用 return 自定义 IHttpActionResult
用于 Forbidden
和 [=17= 的功能进行更新]
class 应该是这样的:
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 的回答是正确的。为了使他的实施工作,我在这里缺少什么?
您现在可以使用以下 (.Net Standard):
return StatusCode(HttpStatusCode.NoContent);
或(.Net Core 2.1+)
return NoContent();
这对我来说效果很好:
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");