MVC 3 API自定义响应正文出错

时间:2013-01-11 14:00:04

标签: c# asp.net-mvc json http-status-codes

我正在尝试使用登录方法+其他人编写API。登录时出现问题,我想使用自定义响应正文向客户端返回自定义HTTP错误代码。问题在于错误时请求被重定向到主页。

[HttpPost]
[AllowAnonymous]
public JsonResult ApiLogIn(LoginModel model)
{
    if (ModelState.IsValid)
    {
        var outcome = _authService.LogIn(model);

        if (outcome == LogInOutcome.Success)
        {
            return Json(new { }); // Empty on success
        }
        else
        {
            Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            return Json(new { reason = outcome.ToString() });
        }
    }

    Response.StatusCode = (int)HttpStatusCode.BadRequest;
    return Json(new { }); // Empty or invalid model
}

如何阻止它在出错时被重定向?

1 个答案:

答案 0 :(得分:1)

问题在于,在请求生命周期的后期,FormsAuth模块会检查Response.StatusCode是否为401,如果是,则重定向到登录页面。

您可以尝试使用其他状态代码(例如403,授予它不适合您的方案)。另一种选择是将Response.StatusCode的设置延迟到401,直到Global.asax中的EndRequest事件为止。

我通过向Context.Items添加标记并检查EndRequest中是否存在标记来解决此问题:

Global.asax.cs - 添加此方法

protected void Application_EndRequest(Object sender, EventArgs e)
{
    if(Context.Items["AjaxPermissionDenied"] is bool) // FormsAuth module intercepts 401 response codes and does a redirect to the login page. 
    {
        Context.Response.StatusCode = 401;
        Context.Response.StatusDescription = "Permission Denied";
        Context.Response.End();
        return;
    }
}

在您的控制器中

[HttpPost]
[AllowAnonymous]
public JsonResult ApiLogIn(LoginModel model)
{
    if (ModelState.IsValid)
    {
        var outcome = _authService.LogIn(model);

        if (outcome == LogInOutcome.Success)
        {
            return Json(new { }); // Empty on success
        }
        else
        {
            Context.Items["AjaxPermissionDenied"] = true;
            return Json(new { reason = outcome.ToString() });
        }
    }

    Response.StatusCode = (int)HttpStatusCode.BadRequest;
    return Json(new { }); // Empty or invalid model
}