使用IHttpActionResult返回内容以获得非OK响应

时间:2015-02-18 16:29:34

标签: c# asp.net-web-api httpresponse

对于从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);
    }

还是有更好的方法吗?

16 个答案:

答案 0 :(得分:381)

您可以使用:

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

答案 1 :(得分:50)

您可以使用HttpRequestMessagesExtensions.CreateErrorResponseSystem.Net.Http命名空间),如下所示:

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

最好根据请求创建响应,以利用Web API的内容协商。

答案 2 :(得分:29)

我最终得到了以下解决方案:

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
}

我愿意接受改进建议。 :)

答案 3 :(得分:15)

你也可以这样做:

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

答案 4 :(得分:7)

有兴趣通过返回ResponseMessage返回任何状态代码的人:

list = (ListView) findViewById(R.id.list1);

答案 5 :(得分:7)

在ASP.NET Web API 2中,您可以将任何ResponseMessage包装在ResponseMessageResult中:

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

在某些情况下,这可能是获得所需结果的最简单方法,尽管通常最好在System.Web.Http.Results中使用各种结果。

答案 6 :(得分:3)

简单:

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

记住要引用 System.Net.Http System.Net

答案 7 :(得分:2)

我建议阅读这篇文章。有很多种方法可以按照建议使用现有的HttpResponse,但是如果你想利用Web Api 2,那么看一下使用一些内置的IHttpActionResult选项,比如

return Ok() 

return NotFound()

Choose the right return type for Web Api Controllers

答案 8 :(得分:1)

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

答案 9 :(得分:1)

一个更详细的示例,其中支持未在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);

答案 10 :(得分:0)

我遇到了同样的问题。我想为我的api控制器创建自定义结果,称之为 _file = "notebook.txt" while True: print("(1) Read the notebook) \n" "(2) Add note \n" "(3) Empty the notebook \n" "(4) Quit") selection = int(input("Please select one:")) if selection == 1: with open(_file, "r") as filename: content = filename.read() print(content) elif selection == 2: with open(_file, "a") as filename: note = input("Your note:") filename.write(note) elif selection == 3: with open(_file, "w") as filename: filename.write('') elif selection == 4: break

然后我这样做了: 1)使用单线创建自定义结果类型

file

2)使用新方法创建自定义控制器:

return Ok("some text");

然后我可以在我的控制器中调用它们,就像这样:

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

答案 11 :(得分:0)

这个答案是基于Shamil Yakupov的回答,用真实对象而不是字符串。

using System.Dynamic;

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

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

答案 12 :(得分:0)

对于例外情况,我通常会这样做

int (*a)[5] = new int[1][5];
a=a+1;
delete[] a;

答案 13 :(得分:0)

以上内容非常有用。

在创建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 )); 
            } 
        }

如果有的话,欢迎提出建议:)

答案 14 :(得分:0)

你可以使用这个:

        //Provide a secret key to Encrypt and Decrypt the Token
        var SecretKey = Encoding.ASCII.GetBytes
             ("YourKey-2374-OFFKDI940NG7:56753253-tyuw-5769-0921-kfirox29zoxv");

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = false,
        ValidateAudience = false,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = "http://localhost:45092/",
        ValidAudience = "http://localhost:45092/",
        IssuerSigningKey = new SymmetricSecurityKey(
            SecretKey),
        ClockSkew = TimeSpan.Zero
    }
);

答案 15 :(得分:-1)

对不起,迟到的回答为什么不简单使用

return BadRequest("your message");

我将其用于所有IHttpActionResult错误,并且效果良好

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