我创建了一个Web API,但是当我在控制器中调用它时,它总是给出相同的StatusCode,即“OK”

时间:2016-11-03 13:05:51

标签: c# asp.net-mvc-4 asp.net-web-api2

我的API代码在下面给出了我们创建login api的地方:

public class AccountController : ApiController
{
    private static readonly ILogWrapper Log = LogManagerWrapper.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

    private ApplicationSignInManager _signInManager;
    /// <summary>
    /// Gets this instance.
    /// </summary>
    /// <returns>HttpResponseMessage.</returns>
    /// 
    public ApplicationSignInManager SignInManager
    {
        get
        {
            return _signInManager ?? HttpContext.Current.GetOwinContext().Get<ApplicationSignInManager>();
        }
        private set { _signInManager = value; }
    }

    /// <summary>
    /// Gets this instance.
    /// </summary>
    /// <returns>HttpResponseMessage.</returns>
    /// 
    [HttpGet]
    public async Task<HttpResponseMessage> Get(string email,string password,bool remember)
    {
        var result = SignInStatus.Failure;
        try
        {
            result = await SignInManager.PasswordSignInAsync(email, password, remember, shouldLockout: false);
        }
        catch (Exception ex)
        {
            Log.Error("Error in login = " + ex.Message, ex);

        }
        return Request.CreateResponse(HttpStatusCode.OK, result);
    }
}

控制器代码是:

[HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        // This doen't count login failures towards lockout only two factor authentication
        // To enable password failures to trigger lockout, change to shouldLockout: true
        var code = HttpStatusCode.NotFound;
        try
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("http://localhost:52958/");
            client.DefaultRequestHeaders.Accept.Clear();
            var res = await client.GetAsync("api/Account/Get?email=" + model.UserName + "&password=" + model.Password + "&remember=" + model.RememberMe + "");
            code = res.StatusCode;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        switch (code)
        {
            case HttpStatusCode.OK:
                return RedirectToLocal(returnUrl);
            default:
                ModelState.AddModelError("", "Invalid login attempt.");
                return View(model);
        }
    }

当我通过swagger执行此API时,它会很好地保留它,如果身份验证详细信息正确则它总是显示成功,否则它会给出失败但是当我通过控制器调用此API时,我总是可以获得状态。我如何获得正确的状态代码?

1 个答案:

答案 0 :(得分:0)

应该返回200 OK。在基于Web Api请求返回的状态代码的switch语句中,如果返回200,则执行临时重定向。临时重定向实际上是301,但是Web浏览器通过在重定向中发出URL的新请求来响应,并且来自该请求的响应(假设一切正常)将是200。

如果您的Web Api返回错误状态代码,您将返回一个视图,该视图将产生200(再次假设返回该视图时一切正常)。

这实际上是应该的方式。您的Web Api失败的事实不应传播到您的MVC响应中。从用户的角度来看,它们要么被重定向,要么返回到上一个视图,并显示错误消息。那是理想的。您不希望将500返回给用户,因为Web Api返回500.然后用户卡在错误页面。相反,您优雅地恢复,向用户发送响应(作为200),其中包含一条消息,说明他们的请求无法处理,稍后再试,等等。换句话说,你解释出了什么问题,但是你'仍然向用户提供成功的回复。

这真的是两件不同的事情。向用户提供成功的响应并不意味着一切都按预期发生。它只是意味着浏览器具有可以使用的功能,可以呈现给用户。在这种情况下,这就是你想要的,因为用户需要了解发生的事情,有能力解决他们的错误等等。