简体   繁体   English

从WebAPI 2端点返回自定义HTTP状态代码

[英]Return Custom HTTP Status Code from WebAPI 2 endpoint

I'm working on a service in WebAPI 2, and the endpoint currently returns an IHttpActionResult . 我正在使用WebAPI 2中的服务,并且端点当前返回IHttpActionResult I'd like to return a status code 422 , but since it's not in the HttpStatusCode enumeration, I'm at a loss as to how it would be sent, since all of the constructors require a parameter of HttpStatusCode 我想返回状态码422 ,但是由于它不在HttpStatusCode枚举中,所以我对如何发送该方法感到困惑,因为所有构造函数都需要HttpStatusCode的参数

As it stands now, I'm returning BadResult(message) , but returning a 422 + message would be more descriptive and useful for my clients. 就目前情况而言,我返回的是BadResult(message) ,但是返回422 +的消息对我的客户来说更具描述性和实用性。 Any ideas? 有任何想法吗?

According to C# specification: 根据C#规范:

The set of values that an enum type can take on is not limited by its enum members. 枚举类型可以采用的值集不受其枚举成员的限制。 In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type 特别是,枚举的基础类型的任何值都可以转换为枚举类型,并且是该枚举类型的不同有效值

Therefore you can cast status code 422 to HttpStatusCode. 因此,您可以将状态代码422强制转换为HttpStatusCode。

Example controller: 控制器示例:

using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace CompanyName.Controllers.Api
{
    [RoutePrefix("services/noop")]
    [AllowAnonymous]
    public class NoOpController : ApiController
    {
        [Route]
        [HttpGet]
        public IHttpActionResult GetNoop()
        {
            return new System.Web.Http.Results.ResponseMessageResult(
                Request.CreateErrorResponse(
                    (HttpStatusCode)422,
                    new HttpError("Something goes wrong")
                )
            );
        }
    }
}
 return Content((HttpStatusCode) 422, whatEver);

credit is for: Return content with IHttpActionResult for non-OK response 功劳是: 对于非OK响应,返回带有IHttpActionResult的内容

and your code must be <= 999 并且您的代码必须为<= 999

and please ignore codes between 100 to 200. 请忽略100到200之间的代码。

I use this way simple and elegant. 我用这种方式简单而优雅。

public ActionResult Validate(User user)
{
     return new HttpStatusCodeResult((HttpStatusCode)500, 
               "My custom internal server error.");
}

Then angular controller. 然后是角度控制器。

function errorCallBack(response) {            
$scope.response = {
   code: response.status,
   text: response.statusText
}});    

Hope it helps you. 希望对您有帮助。

For this you may need to use an Action Filter Attribute . 为此,您可能需要使用动作过滤器属性 Nothing fancy. 没有什么花哨。 Just create a class and inherit it from ActionFilterAttribute class in c#. 只需创建一个类并从c#中的ActionFilterAttribute类继承即可。 Then override a method named OnActionExecuting to implement this. 然后重写一个名为OnActionExecuting的方法以实现此目的。 Then just use this filter on the head of any controller. 然后,只需在任何控制器的头上使用此过滤器即可。 Following is a demo. 以下是一个演示。

On the condition when you need to produce custom status code based message in ActionFilterAttribute you can write in following way: 在需要在ActionFilterAttribute生成基于自定义状态代码的消息的情况下,可以通过以下方式编写:

        if (necessity_to_send_custom_code)
        {
            actionContext.Response = actionContext.Request.CreateResponse((HttpStatusCode)855, "This is custom error message for you");
        }

Hope this helps. 希望这可以帮助。

Another simplified example: 另一个简化的示例:

public class MyController : ApiController
{
    public IHttpActionResult Get()
    {
        HttpStatusCode codeNotDefined = (HttpStatusCode)422;
        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);

I'm using a custom Filter in my controllers that catches any exceptions and returns custom error results so I needed a way to return a custom message response based on the exception message. 我在控制器中使用了一个自定义过滤器,该过滤器会捕获所有异常并返回自定义错误结果,因此我需要一种基于异常消息返回自定义消息响应的方法。

I'm using JsonResult (found in the Microsoft.AspNetCore.Mvc namespace) to return a custom status code and messagesas such: 我正在使用JsonResult (位于Microsoft.AspNetCore.Mvc命名空间中)返回自定义状态代码和消息,例如:

public class DomainViolationFilter : ExceptionFilterAttribute
    {
        public override void OnException(ExceptionContext context)
        {
            switch (context.Exception)
            {
                case EntityNotFoundException e:
                    JsonResult toReturn = new JsonResult(e);
                    toReturn.StatusCode = 404;
                    context.Result = toReturn;
                    return;
            }
        }
    }

In my case, I'm serializing directly the exception object (ex) for simplicity but you should be returning only the relevant (and safe) data, or whatever you need in your use case. 就我而言,为简单起见,我直接对异常对象(ex)进行了序列化,但是您应该只返回相关(和安全)的数据,或用例中需要的任何数据。

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

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