我如何实现 IHttpActionResult 以使其遵守 Accept header?

How do I implement IHttpActionResult so that it respects the Accept header?

我想在我的 ApiController 中覆盖 BadRequest() 以便它 returns 一个 object 带有验证错误。这是我实现 "RichBadRequest" 结果的第一次尝试:

public class RichBadRequestResponse : BadRequestResult
{
    public IEnumerable<string> Errors { get; set; } = new string[0];
    public string Message { get; set; }

    private HttpRequestMessage _request;
    public RichBadRequestResponse(HttpRequestMessage request) : base(request)
    {
        _request = request;
    }

    public override Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var dataObj = new
        {
            errors = Errors.ToArray(),
            message = Message ?? string.Join(", ", Errors)
        };
        if (_request.Headers.Accept.Contains(new MediaTypeWithQualityHeaderValue("applicaiton/xml")))
        {
            Console.WriteLine("Foo");
        }
        var resp = _request.CreateResponse(HttpStatusCode.BadRequest, dataObj);
        return Task.FromResult(resp);
    }
}

然后在我的控制器中我只有:

public class MyApiController : ApiController
{
    protected override BadRequestResult BadRequest()
    {
        return BadRequest("There was an error with your request", null);
    }

    protected RichBadRequestResponse BadRequest(string message, IEnumerable<string> validationErrors)
    {
        validationErrors = validationErrors ?? new string[0];
        var result = new RichBadRequestResponse(Request)
        {
            Message = "There was an error with your request",
            Errors = validationErrors.ToArray()
        };
        return result;
    }
}

这很好用...但是它不遵守接受header。无论出于何种原因,这似乎总是作为 JSON object 返回。我做错了什么?

通过你我发现 CreateResponse 没有返回 XML 而 CreateErrorResponse 正在返回 JSON/XML 或根据 Accept header.

在这里,在 CreateErrorResponse 中,您可以根据需要添加字典 collection。

    public override Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var dataObj = new
        {
            errors = errors.ToArray(),
            message = Message ?? string.Join(", ", errors)
        };

        if (_request.Headers.Accept.Contains(new MediaTypeWithQualityHeaderValue("applicaiton/xml")))
        {
            Console.WriteLine("Foo");
        }
        ///// Changed Line
        var resp = _request.CreateErrorResponse(HttpStatusCode.BadRequest, yourDictionaryCollection);
        return Task.FromResult(resp);
    }