HttpClient& WebAPI不可预测的重定向302

时间:2014-03-05 06:46:19

标签: c# asp.net wpf asp.net-web-api dotnet-httpclient

我有一个WPF应用程序,它使用HttpClient在另一台服务器上调用Web API方法。一切正常,但有时,特别是当客户端应用程序唤醒时(从电源暂停),对同一服务器方法的调用返回Found:302而不是OK:200。

Web API方法实际上并没有做任何事情,它只有一个[Authorize]属性来确保用户通过身份验证。通常,如果用户未经过身份验证,则会返回404。 顺便说一句,我没有明确地使用ASP.NET表单身份验证,但是重定向是将客户端发送到login.aspx,这不存在。

这是代码: Web API方法(.NET 4.5):

[HttpGet]
public HttpStatusCodeResult IsAuthenticated()
{
    return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK);
}

WPF App客户端代码(.NET 4.0):

public async Task<bool> IsAuthenticated()
{
    try
    {
        Uri address = new Uri(AuthUrl);

        var cookieJar = ReadCookiesFromDisk(COOKIE_FILE);
        if (cookieJar.Count == 0)
            return false;
        var handler = new HttpClientHandler
        {
            CookieContainer = cookieJar,
            UseCookies = true,
            UseDefaultCredentials = false,
            AllowAutoRedirect = false
        };

        var client = new HttpClient(handler)
        {
            BaseAddress = address
        };

        int timeout = 15000;
        var task = client.GetAsync(address.ToString());
        Task[] tasks = new Task[1];
        tasks[0] = task;
        if (Task.WaitAny(tasks, timeout) != -1)
        {
            // task completed within timeout
            // checking for redirect, but this should not happen!!!
            HttpResponseMessage response = task.Result;
            if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Redirect)
                return true;
            else
                return false;
        }
        else
        {
            // timeout logic
            return false;
        }
    }
    catch (Exception e)
    {
        EventLogger.Log(e);
        return false;
    }
}

客户端验证码:

public async Task<string> Login(string data)
        {
            try
            {
                Uri address = new Uri(LoginUrl);
                HttpContent content = new StringContent(data, Encoding.UTF8);

                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
                var cookieJar = ReadCookiesFromDisk(COOKIE_FILE);
                var handler = new HttpClientHandler
                {
                    CookieContainer = cookieJar,
                    UseCookies = true,
                    UseDefaultCredentials = false,
                    AllowAutoRedirect = false
                };

                var client = new HttpClient(handler)
                {
                    BaseAddress = address
                };
                HttpResponseMessage response = await client.PostAsync(address.ToString(), content);
                response.EnsureSuccessStatusCode();
                string body = await response.Content.ReadAsStringAsync();

                Uri uri = new Uri(UrlBase);
                var responseCookies = cookieJar.GetCookies(uri);
                if (responseCookies[".ASPXAUTH"] != null)
                    WriteCookiesToDisk(COOKIE_FILE, cookieJar);
                return body;
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

服务器:

public JsonResult LogOn(string userInfo)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            LogOnModel model = serializer.Deserialize<LogOnModel>(userInfo);
            JsonMessage error = null;
            if (ModelState.IsValid)
            {
                try
                {
                    if (WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
                    {
                        if (WebSecurity.IsConfirmed(model.UserName))
                        {
                            if (model.RememberMe)
                                Response.Cookies[0].Expires = DateTime.Now.AddDays(30);
                            else
                                Response.Cookies[0].Expires = DateTime.Now.AddDays(7);

                            var person = Dc.People.FirstOrDefault(x => x.UserName == model.UserName);
                            string fullName = string.Empty;
                            string email = string.Empty;
                            if (person != null)
                            {
                                fullName = string.Format("{0} {1}", person.FirstName, person.LastName);
                                email = person.Email;
                                //fill the session to create the session cookie
                                Session["1"] = 1;
                            }
                            var message = new { FailCount = 0, Message = WebSecurity.GetUserId(model.UserName).ToString(), Success = true, SuccessCount = 0, RedirectUrl = "#/conversations/priority", Name = fullName, UserEmail = email, UserHandle = model.UserName, UserAvatar = person.Avatar };
                            return Json(message);
                        }
                        else
                        {
                            error = new JsonMessage { FailCount = 0, Message = "Your aren't authorised to login", Success = false, SuccessCount = 0 };
                            TempData["Error"] = "Your are not authorised to login";
                            return Json(error);

                        }
                    }
                    else
                    {

                        TempData["Error"] = "The user name or password provided is incorrect.";
                        error = new JsonMessage { FailCount = 0, Message = "The user name or password provided is incorrect.", Success = false, SuccessCount = 0 };
                        return Json(error);
                    }
                }
                catch (Exception ex)
                {
                    TempData["Error"] = ex.Message;
                    error = new JsonMessage { FailCount = 0, Message = ex.Message, Success = false, SuccessCount = 0 };
                }
            }

            return Json(error);
        }

1 个答案:

答案 0 :(得分:-1)

更改以下代码

 HttpResponseMessage response = await client.PostAsync(address.ToString(), content);

 HttpResponseMessage response = await client.PostAsync(address.ToString(), content).ConfigureAwait(false);

以上语句有时会在使用ASync时显示死锁问题。因此,当您为异步任务配置await为false时,它将以正确的方式工作。