简体   繁体   English

使用 IHttpActionResult 为非 OK 响应返回内容

[英]Return content with IHttpActionResult for non-OK response

For returning from a Web API 2 controller, I can return content with the response if the response is OK (status 200) like this:为了从 Web API 2 控制器返回,如果响应正常(状态 200),我可以返回包含响应的内容,如下所示:

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

If possible, I want to use the built-in result types here when possible如果可能的话,我想尽可能在​​这里使用内置的结果类型

My question is, for another type of response (not 200), how can I return a message (string) with it?我的问题是,对于另一种类型的响应(不是 200),我怎样才能用它返回消息(字符串)? 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.理想情况下,我希望将其通用化,以便我可以使用 IHttpActionResult 的任何实现发回消息。

Do I need to do this (and build my response message):我需要这样做(并构建我的响应消息):

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

or is there a better way?或者,还有更好的方法?

你可以使用这个:

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

You can use HttpRequestMessagesExtensions.CreateErrorResponse ( System.Net.Http namespace), like so:您可以使用HttpRequestMessagesExtensions.CreateErrorResponseSystem.Net.Http命名空间),如下所示:

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.最好根据请求创建响应以利用 Web API 的内容协商。

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.我愿意接受改进建议。 :) :)

你也可以这样做:

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

Simple:简单的:

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

Remember to reference System.Net.Http and System.Net .请记住参考System.Net.HttpSystem.Net

Anyone who is interested in returning anything with any statuscode with returning ResponseMessage:任何有兴趣返回任何状态码并返回 ResponseMessage 的人:

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

In ASP.NET Web API 2, you can wrap any ResponseMessage in a ResponseMessageResult :在 ASP.NET Web API 2 中,您可以将任何ResponseMessage包装在ResponseMessageResult中:

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

In some cases this may be the simplest way to get the desired result, although generally it might be preferable to use the various results in System.Web.Http.Results .在某些情况下,这可能是获得所需结果的最简单方法,尽管通常最好使用System.Web.Http.Results中的各种结果。

I would recommend reading this post.我建议阅读这篇文章。 There are tons of ways to use existing HttpResponse as suggested, but if you want to take advantage of Web Api 2, then look at using some of the built-in IHttpActionResult options such as有很多方法可以按照建议使用现有的 HttpResponse,但是如果您想利用 Web Api 2,请考虑使用一些内置的 IHttpActionResult 选项,例如

return Ok() 

or或者

return NotFound()

Choose the right return type for Web Api Controllers 为 Web Api 控制器选择正确的返回类型

A more detailed example with support of HTTP code not defined in C# HttpStatusCode .一个更详细的示例,支持 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 is a virtual method defined in abstract class ApiController , the base of the controller. Content是定义在抽象类ApiController中的一个虚拟方法,它是控制器的基础。 See the declaration as below:请参阅以下声明:

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

Below code / class really helpful to handle all type of responses.下面的代码/类对处理所有类型的响应非常有帮助。 May be success or fail etc.可能成功也可能失败等等。

Why should I use this?我为什么要使用这个? :

Suppose I am consuming web API service.假设我正在使用 Web API 服务。 There are some possibilities of output as below:输出的几种可能性如下:

  1. You might not get any result because of validation error由于验证错误,您可能不会得到任何结果
  2. You will get expected result你会得到预期的结果
  3. You will get error.你会得到错误。

So here I have solution to handle all the scenarios.所以在这里我有处理所有场景的解决方案。 Also I tried to maintain uniformity in the output.我也试图保持输出的一致性。 You can give remark or actual error message.您可以给出备注或实际的错误信息。 The web service consumer can only check IsSuccess true or not else will sure there is problem, and act as per situation. Web服务消费者只能检查IsSuccess是否为真,否则确定有问题,并根据情况采取行动。 There should be perfect communication between web API developer and web API consumer. Web API 开发者和 Web API 消费者之间应该有完美的沟通。 If result is not generating then why.如果结果没有产生那么为什么。 The comment or exception will acknowledge and they will act accordingly.评论或例外将承认,他们将采取相应的行动。 Hence this is best solution for web API consumer / user.因此,这是 Web API 消费者/用户的最佳解决方案。

Single response for all all type of results.所有类型结果的单一响应。

  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 Request.CreateResponse(HttpStatusCode.OK, _res);
            }
            catch (Exception ex)
            {
                _res.IsSuccess = false;
                _res.ErrorMessage = ex;
                return ResponseMessage(Request.CreateResponse(HttpStatusCode.InternalServerError, _res )); 
            } 
        }

You are welcome to give suggestion if any :)如果有任何建议,欢迎您提出建议:)

I am happy if anyone is using and get benefited.如果有人使用并从中受益,我很高兴。 Write me if any addition or modification makes this more improved, on akhandagale65@gmail.com.如果有任何添加或修改使这更加改进,请在 akhandagale65@gmail.com 上写信给我。

@mayabelle you can create IHttpActionResult concrete and wrapped those code like this: @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;
    }
}

I had the same problem.我有同样的问题。 I want to create custom result for my api controllers, to call them like return Ok("some text");我想为我的 api 控制器创建自定义结果,将它们称为return Ok("some text");

Then i did this: 1) Create custom result type with singletone然后我这样做了: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) Create custom controller with new method: 2)使用新方法创建自定义控制器:

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

And then i can call them in my controllers, like this:然后我可以在我的控制器中调用它们,如下所示:

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

this answer is based on Shamil Yakupov answer, with real object instead of string.此答案基于 Shamil Yakupov 答案,使用真实对象而不是字符串。

using System.Dynamic;

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

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

For exceptions, I usually do对于例外情况,我通常会这样做

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

Sorry for the late answer why don't you simple use对不起,你为什么不简单使用

return BadRequest("your message");

I use it for all my IHttpActionResult errors its working well我将它用于我所有的IHttpActionResult错误,它运行良好

here is the documentation : https://msdn.microsoft.com/en-us/library/system.web.http.apicontroller.badrequest(v=vs.118).aspx这是文档: https ://msdn.microsoft.com/en-us/library/system.web.http.apicontroller.badrequest(v=vs.118).aspx

你可以使用这个:

return BadRequest("No data is present in table!!");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM