it-roy-ru.com

Возврат содержимого с помощью IHttpActionResult для ответа не OK

Для возврата из контроллера Web API 2 я могу вернуть содержимое с ответом, если ответ в порядке (состояние 200), например так:

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

Если возможно, я хочу использовать встроенные типы результатов здесь, когда это возможно: https://msdn.Microsoft.com/en-us/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);
    }

или есть лучший способ?

147
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");
369
Shamil Yakupov

Вы можете использовать HttpRequestMessagesExtensions.CreateErrorResponse (System.Net.Http namespace), например так:

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

Любой, кто заинтересован в возвращении чего-либо с любым кодом состояния с возвратом ResponseMessage:

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

В ASP.NET Web API 2 вы можете заключить любую ResponseMessage в ResponseMessageResult :

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

В некоторых случаях это может быть самый простой способ получить желаемый результат, хотя обычно может быть предпочтительнее использовать различные результаты в System.Web.Http.Results .

6
sfuqua

Просто:

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

1
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

этот ответ основан на ответе Шамиля Якупова, с реальным объектом вместо строки.

using System.Dynamic;

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

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

У меня такая же проблема. Я хочу создать собственный результат для моих контроллеров API, чтобы называть их как return Ok("some text");

Затем я сделал это: 1) Создайте пользовательский тип результата с помощью синглета

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

Выше вещи действительно полезны.

При создании веб-сервисов, если вы воспользуетесь услугами, потребитель будет очень благодарен. Я пытался поддерживать единообразие вывода. Также вы можете дать замечание или актуальное сообщение об ошибке. Потребитель веб-службы может только проверить, верно ли IsSuccess или нет, иначе он будет уверен в наличии проблемы и будет действовать в соответствии с ситуацией. 

  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