c# – 切换到IPV6时HttpClient抛出异常 – 从iOS Store拒绝

我正在研究一个Xamarin项目的奇怪问题,我很难过……

我使用HTTPClient来发出异步请求.但是,我的应用程序因未能满足Apple的IPV6要求而被应用商店拒绝.也就是说,当通过IPV6连接时,我使用HTTPClient发出的请求失败.奇怪的是,只有当应用程序在IPV4网络上启动然后切换到IPV6网络时才会失败.如果我在连接到IPV6网络时重新启动应用程序,它会成功!此外,如果我启动连接到IPV6的应用程序然后切换到IPV4网络,它也会成功.它仅在IPV4中启动然后切换到IPV6时失败.

这非常奇怪 – 就像HttpClient缓存一样,但我们为每个请求创建一个新的客户端.我没有使用IP地址 – 只是一个地址,而且,正如我所提到的,当应用程序开始连接到仅IPV6网络时,它可以正常工作.它只是从IPV4到IPV6的转换,这似乎导致了这个问题.

PCL中存在的代码

var client = new HttpClient();
var urlToCall = new Uri("https://www.something.com/someapi/v1");
// Add some headers
...
response = client.GetAsync(urlToCall);

并且堆栈跟踪:

Trace.Message": "Error: ConnectFailure (Network is unreachable)
at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00065] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:946 
at System.Threading.Tasks.TaskFactory`1[TResult].FromAsyncCoreLogic (IAsyncResult iar,System.Func`2 endFunction,System.Action`1 endAction,System.Threading.Tasks.Task`1 promise,Boolean requiresSynchronization) <0x10019c730 + 0x0005b> in <filename unkNown>:0 
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptiondispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:199 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () <0x10013ccc0 + 0x0001b> in <filename unkNown>:0 
at System.Net.Http.httpclienthandler+<SendAsync>c__async0.MoveNext () [0x003d6] in /Library/Frameworks/Xamarin.iOS.framework/Versions/9.6.1.9/src/mono/mcs/class/System.Net.Http/System.Net.Http/httpclienthandler.cs:372 
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptiondispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:199 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () <0x10013ccc0 + 0x0001b> in <filename unkNown>:0 
at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x000a9] in /Library/Frameworks/Xamarin.iOS.framework/Versions/9.6.1.9/src/mono/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs:274 
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptiondispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:199 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 
at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () <0x10013c8c0 + 0x0001b> in <filename unkNown>:0 
at MyApp.RestClient.RestService`2+<SendHttpRequest>d__10[TInput,TOutput].MoveNext () [0x00259] in <filename unkNown>:0 
Network is unreachable
at System.Net.sockets.socket.Connect (System.Net.EndPoint remoteEP) [0x000bc] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net.sockets/Socket.cs:1235 
at System.Net.WebConnection.Connect (System.Net.HttpWebRequest request) [0x001c2] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net/WebConnection.cs:213

以前有人见过这样的事吗?有没有人知道如何修复甚至调试这个?

解决方法

在iOS Build设置中,将HttpClient Implementation设置为使用NSURLSession.

Link to Xamarin Documentation

The default continues to be an HttpClient that is powered by HttpWebRequest,while you can Now optionally switch to an implementation that uses iOS’s,tvOS’s or OS X’s native transports (NSUrlSession or CFNetwork depending on the OS). The upside is smaller binaries,and faster downloads,the downside is that it requires the event loop to be running for async operations to be executed.

iOS Build Settings

您使用的是主机名,而不是硬编码的IPv4 IP地址,这是个好消息!如果您使用的是硬编码的IPv4 IP地址,Apple将拒绝您的应用.

确保检查主机名是否可以解析IPv6 IP地址. System.Net.Dns中还有一些有用的方法可以帮助您解析IP地址,以查看IPv6是否可用.

您也可以尝试使用.MapToIPv6()扩展方法Link to MSDN documentation.

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...