Return content with IHttpActionResult for non-OK r

2019-01-12 16:27发布

For returning from a Web API 2 controller, I can return content with the response if the response is OK (status 200) like this:

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

If possible, I want to use the built-in result types here when possible: https://msdn.microsoft.com/en-us/library/system.web.http.results(v=vs.118).aspx

My question is, for another type of response (not 200), how can I return a message (string) with it? For example, I can do this:

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

but not this:

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

Ideally I want this to be generalized so that I can send a message back with any of the implementations of IHttpActionResult.

Do I need to do this (and build my own response message):

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

or is there a better way?

15条回答
贼婆χ
2楼-- · 2019-01-12 16:35

You can use HttpRequestMessagesExtensions.CreateErrorResponse (System.Net.Http namespace), like so:

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

It is preferable to create responses based on the request to take advantage of Web API's content negotiation.

查看更多
叼着烟拽天下
3楼-- · 2019-01-12 16:37

Anyone who is interested in returning anything with any statuscode with returning ResponseMessage:

//CreateResponse(HttpStatusCode, T value)
return ResponseMessage(Request.CreateResponse(HttpStatusCode.XX, object));
查看更多
对你真心纯属浪费
4楼-- · 2019-01-12 16:39

@mayabelle you can create IHttpActionResult concrete and wrapped those code like this:

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;
    }
}
查看更多
【Aperson】
5楼-- · 2019-01-12 16:39

this answer is based on Shamil Yakupov answer, with real object instead of string.

using System.Dynamic;

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

return Content<object>(HttpStatusCode.BadRequest, response);
查看更多
再贱就再见
6楼-- · 2019-01-12 16:43

Simple:

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

Remember to reference System.Net.Http and System.Net.

查看更多
三岁会撩人
7楼-- · 2019-01-12 16:44

I ended up going with the following solution:

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

... which can be used like this:

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

I'm open to suggestions for improvement. :)

查看更多
登录 后发表回答