【问题标题】:NameResolutionFailure Nightmare: Even ModernHttpClient is failingNameResolutionFailure 噩梦:甚至 ModernHttpClient 都失败了
【发布时间】:2015-10-01 04:54:50
【问题描述】:

当我在我的 MVVM Cross Android 应用程序中发出 Web 请求 (GET) 时,我经常收到 NameResolutionFailure 错误。

我已经尝试了论坛中提供的很多关于这个问题的建议,因为这是一个常见的问题,但我无法解决这个问题。

我当前的尝试使用 NuGet 包 ModernHttpClient 来执行 Web 请求。发生同样的错误 - 无法将域解析为 IP - 但是错误消息与我使用 HttpWebRequest 时发生的情况略有不同,所以我想这是一个轻微的改进?

java.net.UnknownHostException:无法解析主机“jsonplaceholder.typicode.com”:没有与主机名关联的地址

您能否就为什么总是失败提供建议?也许是我的方法没有真正利用ModernHttpClient

以下代码是我的IRestService 类的一部分,它位于Core PCL 中,而不是在 Android 项目中。

public async Task MakeRequest(WebHeaderCollection headers = null)
{

    var handler = new NativeMessageHandler();
    string requestUrl = "http://jsonplaceholder.typicode.com/posts/1";

    try
    {
        using (var client = new HttpClient(handler))
        {
            //client.BaseAddress = new Uri(baseAddress);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var response = await client.GetAsync(requestUrl);

            if (response.IsSuccessStatusCode)
            {
                var stream = await response.Content.ReadAsStreamAsync();
                var reader = new StreamReader(stream);
                Mvx.Trace("Stream: {0}", reader.ReadToEnd());
            }
        }
    }
    catch (WebException ex)
    {
        Mvx.Trace("MakeRequest Error: '{0}'", ex.Message);
    }

    return;
}

PS:我也尝试过使用 Cheesebarons ModernHttpClient MVVM Cross 插件,但这会导致发布模式下的编译错误,并且没有关于它有哪些方法和类的文档 - 也许它不再受支持?

PPS: 是的,我的清单具有 Internet 权限(我检查了选项和实际清单文件以确认)

【问题讨论】:

  • 有些人说这可能是网络问题。您是否尝试过其他网络,包括蜂窝网络? forums.xamarin.com/discussion/7327/…
  • @Eraph 感谢您的评论。不幸的是,我尝试过家庭 wifi、便携式 wifi 拇指驱动器和 4g 没有运气
  • 这在我的 Genymotion 模拟器 (Nexus) 和实际的华为手机上也失败了。就像其他人所说的那样,几周前使用 HttpWebRequest 可以正常工作,但现在突然不行了。
  • 也可以尝试在xamarin官方论坛发帖,Cheesebaron比较活跃,他用这个名字作为用户名,你可以把他加入主题

标签: c# xamarin mvvmcross


【解决方案1】:

不再需要 MvvmCross 的 ModernHttpClient 插件,所以不要使用它。

因此,由于您在 AndroidManifest 中设置了 Internet 权限,因此问题出在其他地方。我在某些 Android 设备上体验过,对某些 Internet 资源的第一次调用失败并出现与您遇到的相同错误。我通常解决这个问题的方法是重试调用。

有多种方法可以做到这一点。

  1. 您可以创建自己的 HttpClientHandler 来包装来自 ModernHttpClient 的处理程序,并在其中创建自己的重试处理。
  2. 您可以使用 Polly 等库重试

我倾向于后者。因此,如果您添加 Polly NuGet,您可以很快测试这是否可以为您解决问题:

var policy = Policy.WaitAndRetryAsync(
    5, 
    retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
    (ex, span) => {
        Mvx.Trace("Retried because of {0}", ex);
    }
);

然后重试您的任务,例如:

await policy.ExecuteAsync(() => MakeRequest(someHeaders)).ConfigureAwait(false);

通常在第二次尝试时异常消失。

我在 Nexus 5、Nexus 7 和三星 Galaxy SII 上看到过这个问题,但在其他设备上没有。如果您在调试之前切换设备上的 WiFi 也可能会有所帮助。

在任何情况下,您的应用都应该有某种重试逻辑,因为 Internet 连接有时会不稳定。

【讨论】:

  • 谢谢!我可以吻你:P 已经为此苦苦挣扎了好几天。
猜你喜欢
  • 2014-11-05
  • 1970-01-01
  • 2013-02-24
  • 2010-12-21
  • 2020-03-14
  • 2010-11-13
  • 2010-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多