我有一个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
答案 0 :(得分:2)
我假设您正在使用控制器上的内置AuthorizeAttribute来保护您的API。我认为它不起作用的原因是因为AuthorizationFilters(比如AuthorizeAttribute)在WebApi管道中比ActionFilters早发生。有关详细信息,请参见此处:
因此,您的代码永远不会执行,因为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())
};
}
}