没有为HttpStatusCode.Unauthorized显示aspnet webapi 2响应有效负载

时间:2014-12-18 13:32:48

标签: c# json asp.net-web-api asp.net-web-api2 http-status-code-401

我有一个ActionFilterAttribute会覆盖OnActionExecuting。如果用户未经过身份验证,我想返回401 Unauthorized状态和Response类型的JSON对象,并带有自定义消息和其他属性

public class Response
{
    public Boolean Error { get; set; }
    public IList<string> Messages { get; set; }
    public object Data { get; set; }
}

这就是我的所作所为:

public override void OnActionExecuting(HttpActionContext actionContext)
{
    //some code here

    var response = new Response();
    response.AddMessage(true, Util.Localization.Authentication.Validation_UserNotAuthenticated);

    actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
    {
        Content = new ObjectContent(typeof(Response), response, new JsonMediaTypeFormatter())
    };
}

当客户提出请求时,响应标题(来自Google Chrome开发人员工具 - 网络):

HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 18 Dec 2014 13:19:12 GMT
Content-Length: 83

嗯,带有Response对象的JSON不会显示给客户端。

如果我只将HttpStatusCode更改为OK,则会显示JSON:

actionContext.Response = new HttpResponseMessage(HttpStatusCode.OK)
{
    Content = new ObjectContent(typeof(Response), response, new JsonMediaTypeFormatter())
};

此外,如果我将HttpStatusCode保留为Unauthorized,但将Type更改为string,则文本会正常显示给客户:

actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
    Content = new ObjectContent(typeof(string), "test string", new JsonMediaTypeFormatter())
};

当我获得未经授权的Http状态时,如何发送自定义JSON对象?

Thnaks

1 个答案:

答案 0 :(得分:2)

我假设您正在使用控制器上的内置AuthorizeAttribute来保护您的API。我认为它不起作用的原因是因为AuthorizationFilters(比如AuthorizeAttribute)在WebApi管道中比ActionFilters早发生。有关详细信息,请参见此处:

https://damienbod.wordpress.com/2014/01/04/web-api-2-using-actionfilterattribute-overrideactionfiltersattribute-and-ioc-injection/

因此,您的代码永远不会执行,因为AuthorizeAttribute已经失败并返回其默认响应(401消息没有正文)。

执行所需操作的最简单方法是继承自定义授权属性,例如MyAuthorizeAttribute,继承自AuthorizeAttribute并更改其处理错误的方式。然后用[MyAuthorize]而不是[Authorize]来装饰您的控制器。

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        var jsonFormatter = new JsonMediaTypeFormatter();

        var response = new Response();
        response.AddMessage(true, Util.Localization.Authentication.Validation_UserNotAuthenticated); 

        actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
        {
            ReasonPhrase = "Unauthorized",
            Content = new ObjectContent(typeof(Response), response, new JsonMediaTypeFormatter())
        };


    }
}