简体   繁体   English

xamarin 上的 HttpClient PostAsync 什么也不做

[英]HttpClient PostAsync on xamarin does nothing

I have a piece of code我有一段代码

var formContent =
    new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("grant_type", "password"),
        new KeyValuePair<string, string>("username", _userName),
        new KeyValuePair<string, string>("password", _password)
    });

var response = await InternalClient.PostAsync("/Token", formContent).ConfigureAwait(false);

It works fine when i use it in my desktop app, but this very same piece fails on Xamarin.Android.当我在我的桌面应用程序中使用它时它工作正常,但在 Xamarin.Android 上同样的部分失败了。 I can access my web site from emulators browser, so it's not the case of not having the connection between these two.我可以从模拟器浏览器访问我的网站,所以这不是这两者之间没有连接的情况。 Even more interesting part - GetAsync works absolutely fine.更有趣的部分 - GetAsync 工作得非常好。 PostAsync always fails with TaskCancelledException because of timeout.由于超时,PostAsync 总是以 TaskCancelledException 失败。 All the PostAsync calls do not hit the server at all.所有 PostAsync 调用根本不会命中服务器。
My activity where this is executed:我执行此操作的活动:

var isAuthSuccess = _mainClient.Authenticate();

isAuthSuccess.ContinueWith(task =>
{
    RunOnUiThread(() =>
    {
        if (isAuthSuccess.Result)
        {
            ReleaseEventHandlers();

            var nav = ServiceLocator.Current.GetInstance<INavigationService>();
            nav.NavigateTo("MainChatWindow", _mainClient);
        }

        button.Enabled = true;
    });
});

And the Authenticate method:和 Authenticate 方法:

public async Task<bool> Authenticate()
{
    var getTokenOperation = new AsyncNetworkOperation<string>(GetTokenOperation);
    var token = await getTokenOperation.Execute().ConfigureAwait(false);

    if (getTokenOperation.IsCriticalFailure)
    {
        SetCriticalFailure(getTokenOperation.FailureReason);
    }

    if (getTokenOperation.IsFailure == false)
    {
        InternalClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
        return true;
    }

    else
    {
        AuthenticationFailEncounteredEvent("Authentication fail encountered: " + getTokenOperation.FailureReason);
        return false;
    }
}

Get token operation:获取令牌操作:

private async Task<string> GetTokenOperation()
{
    var formContent =
            new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("grant_type", "password"),
                new KeyValuePair<string, string>("username", _userName),
                new KeyValuePair<string, string>("password", _password)
            });

    var response = await InternalClient.PostAsync("/Token", formContent).ConfigureAwait(false);
    response.EnsureSuccessStatusCodeVerbose();

    var responseJson = await response.Content.ReadAsStringAsync();

    var jObject = JObject.Parse(responseJson);
    var token = jObject.GetValue("access_token").ToString();

    return token;
}

And the wrapper - AsyncNetworkOperation和包装器 - AsyncNetworkOperation

public class AsyncNetworkOperation<T>
{
    public bool IsFailure { get; set; }

    public bool IsCriticalFailure { get; set; }

    public string FailureReason { get; set; }

    public bool IsRepeatable { get; set; }

    public int RepeatsCount { get; set; }

    public Func<Task<T>> Method { get; set; }

    public AsyncNetworkOperation(Func<Task<T>> method, int repeatsCount)
    {
        Method = method;
        IsRepeatable = true;
        RepeatsCount = repeatsCount;
    }

    public AsyncNetworkOperation(Func<Task<T>> method)
    {
        Method = method;
    }

    public async Task<T> Execute()
    {
        try
        {
            return await Method().ConfigureAwait(false);
        }

        ...exception handling logics
    }
}

Calling PostAsync right in the activity behaves the same - waits for quite a long time and then fails with TaskCancelledException because of timeout.在活动中正确调用 PostAsync 的行为相同 - 等待很长时间,然后由于超时而失败并出现 TaskCancelledException。

For all the struggling with the same issue - this is related to SSL (self signed cert in my case).对于所有在同一问题上苦苦挣扎的人 - 这与 SSL(在我的情况下为自签名证书)有关。 If you are trying to connect to your server via HTTPS - try using plain HTTP first, my app can work with HTTP fine while HTTPS hangs to death.如果您尝试通过 HTTPS 连接到您的服务器 - 首先尝试使用纯 HTTP,我的应用程序可以正常使用 HTTP,而 HTTPS 挂起。

I have had other problems with PostAsync() also and it is also not as customizable as SendAsync() in terms of editing the headers and things like that.我也遇到了PostAsync()其他问题,并且在编辑标题和诸如此类的事情方面,它也不像SendAsync()那样可定制。 I would recommend SendAsync() :我会推荐SendAsync()

HttpRequestMessage  request = new HttpRequestMessage(HttpMethod.Post, "/Token") { Content = formContent };
HttpResponseMessage message = await InternalClient.SendAsync(request, HttpCompletionOption.ResponseContentRead).ConfigureAwait(false);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM