新しいIHttpActionResult
インターフェイスを使用して_HttpStatusCode.NoContent
_応答メッセージを返す方法はありますか?
現在return new HttpResponseMessage( HttpStatusCode.NoContent );
を使用していますが、これをreturn NoContent();
に変換したいと思います。
IHttpActionResult
はすでにOk()
、Conflict()
、およびNotFound()
を取得していますが、Forbidden()
およびNoContent()
プロジェクトで使用する必要があります。
他の結果タイプを追加するのは簡単ですか?
これを見つけました サンプルサイト カスタム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
}
}
デフォルトでは、アクションがvoid
を返す場合、応答のHTTPステータスは204になるため、_no-content
_の結果に便利なメソッドはありません。
アクションで明示的に指定したい場合は、アクションからStatusCode(HttpStatusCode.NoContent)
を返すか、
_ResponseMessage(new HttpResponseMessage(HttpStatusCode.NoContent)).
_
Unauthorized()簡易メソッドは401ステータスを提供するため、Forbidden(403)の場合は、StatusCode(HttpStatusCode.Forbidden)
または
_ResponseMessage(new HttpResponseMessage(HttpStatusCode.Forbidden))
_
@Intrepid実装を試してみましたが、いくつかの問題に遭遇しました。ここに2つの解決策があります:
解決策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の答えが正しければ。彼の実装を機能させるためにここで何が欠けていますか?
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
}
}
以下を使用できるようになりました(.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");