Xamarin中使用HttpWebResponse出现System.NullReferenceException异常如何解决
问题诱发原因
这个空引用异常并非代码中request对象为空导致,根源是Xamarin平台的托管HTTP实现栈,和控制台程序所用的桌面/.NET Core运行时网络栈逻辑不一致,核心触发点有三个:
- 旧版本Xamarin默认使用托管版本的
HttpWebRequest实现,对AutomaticDecompression配置的GZip解压逻辑存在已知bug:内部处理压缩响应头时未做非空校验,相关解压处理对象未完成初始化就被调用,直接抛出空引用。 - StackOverflow目前强制要求TLS 1.2及以上版本的HTTPS连接,Xamarin老项目默认TLS配置为1.0/1.1,握手失败后内部异常处理逻辑存在缺陷,没有抛出正常的
WebException,错误抛出空引用异常。 - 若在UI主线程调用同步的
GetResponse()方法,会触发Xamarin平台的主线程网络请求拦截,拦截逻辑异常时也会抛出空引用。
修复方案
按优先级从高到低操作即可:
修改项目HTTP栈配置(修复率最高)
- Xamarin.Android项目:右键项目进入「属性-Android选项-高级设置」,将HTTP实现从默认的「Managed(托管)」切换为
AndroidClientHandler(安卓原生网络栈),TLS版本选择TLS 1.2+。 - Xamarin.iOS项目:右键项目进入「属性-iOS生成」,将HTTP实现从默认的「Managed」切换为
NSUrlSession(iOS原生网络栈),TLS版本选择TLS 1.2+。
原生网络栈对HTTPS握手、压缩解压的实现更完善,不存在托管栈的已知bug,修改完成后原有代码基本可以直接运行。
- Xamarin.Android项目:右键项目进入「属性-Android选项-高级设置」,将HTTP实现从默认的「Managed(托管)」切换为
代码层面兼容调整
如果暂时不能修改项目配置,对原有代码做如下调整:- 在创建网络请求前显式指定支持的TLS版本,添加代码:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13; - 移除
request.AutomaticDecompression = DecompressionMethods.GZip配置,拿到响应流后手动处理GZip解压,规避托管栈的解压逻辑bug。 - 禁止在UI主线程调用同步的
GetResponse()方法,将网络请求逻辑放到后台线程执行,或者改用异步的GetResponseAsync()方法。
- 在创建网络请求前显式指定支持的TLS版本,添加代码:
长期维护推荐方案:替换为HttpClient实现
HttpWebRequest属于老旧网络API,Xamarin平台官方已不再针对其做兼容性修复,长期开发建议替换为官方推荐的HttpClient,搭配原生handler使用,稳定性更高,示例代码:string html = string.Empty; string url = "https://stackoverflow.com/"; // 安卓项目用AndroidClientHandler,iOS项目替换为NSUrlSessionHandler即可,会自动适配压缩、TLS配置 using (var handler = new AndroidClientHandler()) { handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; using (var client = new HttpClient(handler)) { html = await client.GetStringAsync(url); } }
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

