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

C# MVC 3 API自定义响应正文出错,c#,asp.net-mvc,json,http-status-codes,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);

我正在尝试使用登录方法+其他方法编写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
}

如何防止它在出现错误时被重定向?

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

您可以尝试一个不同的状态代码(比如403,当然这不太适合您的场景)。另一个选项是延迟将
Response.StatusCode
设置为401,直到Global.asax中出现
EndRequest
事件

我通过在
上下文中添加一个标志来解决这个问题。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
}