Возврат содержимого с помощью 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);
    }

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

14 132

14 ответов:

вы можете использовать это:

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

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

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

предпочтительно создавать ответы на основе запроса, чтобы воспользоваться преимуществами согласования содержимого веб-API.

в конечном итоге я пошел со следующим решением:

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
}

Я открыт для предложений по улучшению. :)

вы также можете сделать:

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

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

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

In ASP.NET Web API 2, Вы можете обернуть любой ResponseMessage на ResponseMessageResult:

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

в некоторых случаях это может быть самый простой способ получить желаемый результат, хотя в целом может быть предпочтительнее использовать различные результаты в

@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;
    }
}

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

тогда я сделал это: 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();
    }

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

using System.Dynamic;

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

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

для исключений, я обычно делаю

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

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

при создании веб-сервисов, Если вы возьмете случай потребителя услуг, он будет очень признателен. Я старался поддерживать равномерность вывода. Также вы можете дать замечание или фактическое сообщение об ошибке. Потребитель веб-службы может только проверить 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 )); 
            } 
        }

вы можете дать предложения, если таковые имеются :)

Я бы рекомендовал прочитать этот пост. Существует множество способов использования существующего HttpResponse, как это предлагается, но если вы хотите воспользоваться веб-Api 2, то посмотрите на использование некоторых встроенных параметров IHttpActionResult, таких как

return Ok() 

или

return NotFound()

Выберите правильный тип возврата для контроллеров Web Api

просто:

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

Не забудьте указать System. Net. Http и System.Net.

извините за поздний ответ, почему бы вам не просто использовать

return BadRequest("your message");

Я использую его для всех моих IHttpActionResult ошибки его работы хорошо

вот документация : https://msdn.microsoft.com/en-us/library/system.web.http.apicontroller.badrequest(v=vs.118).aspx