web-dev-qa-db-ja.com

OK以外の応答に対してIHttpActionResultを使用してコンテンツを返す

Web API 2コントローラーから戻る場合、応答がOK(状況200)であれば、応答と共にコンテンツを返すことができます。

    public IHttpActionResult Get()
    {
        string myResult = ...
        return Ok(myResult);
    }

可能であれば、可能な場合は組み込みの結果タイプをここで使用します。 https://msdn.Microsoft.com/ja-jp/library/system.web.http.results(v=vs.118)。 aspx

私の質問は、他の種類の応答(200ではない)に対して、どうやってそれと共にメッセージ(文字列)を返すことができるのですか?たとえば、私はこれを行うことができます:

    public IHttpActionResult Get()
    {
       return InternalServerError();
    }

しかしこれではない:

    public IHttpActionResult Get()
    {
       return InternalServerError("Message describing the error here");
    }

理想的には、これを一般化して、IHttpActionResultの任意の実装でメッセージを送り返せるようにします。

私はこれをする必要がありますか(そして私自身の応答メッセージを構築します):

    public IHttpActionResult Get()
    {
       HttpResponseMessage responseMessage = ...
       return ResponseMessage(responseMessage);
    }

それとももっと良い方法がありますか?

155
mayabelle

私は結局次のような解決策を考えました。

public class HttpActionResult : IHttpActionResult
{
    private readonly string _message;
    private readonly HttpStatusCode _statusCode;

    public HttpActionResult(HttpStatusCode statusCode, string message)
    {
        _statusCode = statusCode;
        _message = message;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        HttpResponseMessage response = new HttpResponseMessage(_statusCode)
        {
            Content = new StringContent(_message)
        };
        return Task.FromResult(response);
    }
}

...これは次のように使用できます。

public IHttpActionResult Get()
{
   return new HttpActionResult(HttpStatusCode.InternalServerError, "error message"); // can use any HTTP status code
}

私は改善のための提案を受け付けています。 :)

29
mayabelle

これを使うことができます:

return Content(HttpStatusCode.BadRequest, "Any object");
378
Shamil Yakupov

HttpRequestMessagesExtensions.CreateErrorResponseSystem.Net.Http名前空間)を次のように使用できます。

public IHttpActionResult Get()
{
   return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Message describing the error here"));
}

Web APIのコンテンツネゴシエーションを利用するために、要求に基づいて応答を作成することをお勧めします。

49
user1620220

次のこともできます。

return InternalServerError(new Exception("SOME CUSTOM MESSAGE"));
15
ilans

ASP.NET Web API 2では、任意のResponseMessageResponseMessageResult で囲むことができます。

public IHttpActionResult Get()
{
   HttpResponseMessage responseMessage = ...
   return new ResponseMessageResult(responseMessage);
}

場合によっては、これが望ましい結果を得る最も簡単な方法かもしれませんが、一般的に System.Web.Http.Results でさまざまな結果を使用するのが好ましいかもしれません。

7
sfuqua

ResponseMessageを返すことで、任意のステータスコードで何かを返すことに興味がある人は誰でも:

//CreateResponse(HttpStatusCode, T value)
return ResponseMessage(Request.CreateResponse(HttpStatusCode.XX, object));
7
CularBytes

シンプル:

return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Your message"));

System.Net.Http および System.Net を参照することを忘れないでください。

3
Rodrigo Reis

この記事を読むことをお勧めします。提案どおりに既存のHttpResponseを使用する方法はたくさんありますが、Web Api 2を利用したい場合は、次のような組み込みのIHttpActionResultオプションを使用してみてください。

return Ok() 

または

return NotFound()

Web Apiコントローラーの正しい戻りタイプを選択してください

2
wegunterjr

@mayabelleあなたはIHttpActionResultコンクリートを作成し、このようにそれらのコードをラップすることができます:

public class NotFoundPlainTextActionResult : IHttpActionResult
{
    public NotFoundPlainTextActionResult(HttpRequestMessage request, string message)
    {
        Request = request;
        Message = message;
    }

    public string Message { get; private set; }
    public HttpRequestMessage Request { get; private set; }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(ExecuteResult());
    }

    public HttpResponseMessage ExecuteResult()
    {
        var response = new HttpResponseMessage();

        if (!string.IsNullOrWhiteSpace(Message))
            //response.Content = new StringContent(Message);
            response = Request.CreateErrorResponse(HttpStatusCode.NotFound, new Exception(Message));

        response.RequestMessage = Request;
        return response;
    }
}
1
Quoc Nguyen

例外として、私は通常やる

 catch (Exception ex)
        {
            return InternalServerError(new ApplicationException("Something went wrong in this request. internal exception: " + ex.Message));
        }
0
ahsant

この答えはShamil Yakupovの答えに基づいており、文字列ではなく実際のオブジェクトです。

using System.Dynamic;

dynamic response = new ExpandoObject();
response.message = "Email address already exist";

return Content<object>(HttpStatusCode.BadRequest, response);
0
Kugan Kumar

私は同じ問題を抱えていました。 return Ok("some text");のようにそれらを呼び出すために、私は私のapiコントローラ用のカスタム結果を作成したいです。

それから私はこれをやった:1)singletoneでカスタム結果タイプを作成する

public sealed class EmptyResult : IHttpActionResult
{
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.NoContent) { Content = new StringContent("Empty result") });
    }
}

2)新しい方法でカスタムコントローラを作成します。

public class CustomApiController : ApiController
{
    public IHttpActionResult EmptyResult()
    {
        return new EmptyResult();
    }
}

そして、私はこのように私のコントローラでそれらを呼び出すことができます:

public IHttpActionResult SomeMethod()
    {
       return EmptyResult();
    }
0
Merchezatter

C#HttpStatusCodeで定義されていないHTTPコードをサポートするより詳細な例。

public class MyController : ApiController
{
    public IHttpActionResult Get()
    {
        HttpStatusCode codeNotDefined = (HttpStatusCode)429;
        return Content(codeNotDefined, "message to be sent in response body");
    }
}

Contentは、抽象クラスApiController(コントローラーのベース)で定義された仮想メソッドです。以下の宣言を参照してください。

protected internal virtual NegotiatedContentResult<T> Content<T>(HttpStatusCode statusCode, T value);
0
themefield

上記のことは本当に役に立ちます。

Webサービスを作成している間、あなたがサービスのケースを取る場合は非常に高く評価されるでしょう。出力の均一性を保つようにしました。また、コメントや実際のエラーメッセージを出すこともできます。 Webサービスコンシューマは、IsSuccessがtrueであるかどうかを確認することしかできないか、そうでない場合は問題があることを確認でき、状況に応じて動作できます。

  public class Response
    {
        /// <summary>
        /// Gets or sets a value indicating whether this instance is success.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance is success; otherwise, <c>false</c>.
        /// </value>
        public bool IsSuccess { get; set; } = false;

        /// <summary>
        /// Actual response if succeed 
        /// </summary>
        /// <value>
        /// Actual response if succeed 
        /// </value>
        public object Data { get; set; } = null;

        /// <summary>
        /// Remark if anythig to convey
        /// </summary>
        /// <value>
        /// Remark if anythig to convey
        /// </value>
        public string Remark { get; set; } = string.Empty;
        /// <summary>
        /// Gets or sets the error message.
        /// </summary>
        /// <value>
        /// The error message.
        /// </value>
        public object ErrorMessage { get; set; } = null;


    }  




[HttpGet]
        public IHttpActionResult Employees()
        {
            Response _res = new Response();
            try
            { 
                DalTest objDal = new DalTest(); 
                _res.Data = objDal.GetTestData();
                _res.IsSuccess = true;
                return Ok<Response>(_res);
            }
            catch (Exception ex)
            {
                _res.IsSuccess = false;
                _res.ErrorMessage = ex;
                return ResponseMessage(Request.CreateResponse(HttpStatusCode.InternalServerError, _res )); 
            } 
        }

もしあればあなたは提案をすることを歓迎しています:)

0
Amol Khandagale