C# Try/Catch未捕获空API请求URI异常的解决方案
问题场景
调用返回JSON响应的API时,存在传入空值作为请求URL的问题,原有实现代码如下:
try { HttpResponseMessage response = client.GetAsync(WorkItemsListUri).Result; response.EnsureSuccessStatusCode(); ResponseContent = await response.Content.ReadAsStringAsync(); JsonResponseContent = JsonConvert.DeserializeObject<WorkItemsListModel>(ResponseContent); } catch(HttpRequestException e) { System.Diagnostics.Debug.WriteLine("CAUGHT EXCEPTION:"); System.Diagnostics.Debug.WriteLine(e); }
应用首次加载时WorkItemsListUri属性为空,属性默认定义如下:
public string WorkItemsListUri { get; set; } = String.Empty;
该属性仅在用户执行点击操作后才会被注入正确的API URL,但页面加载时代码会自动执行。由于原有catch块仅捕获HttpRequestException类型异常,无法拦截空URI触发的InvalidOperationException,会抛出如下未处理异常:
处理请求时发生未处理的异常。
InvalidOperationException: 提供的请求URI无效。请求URI必须为绝对URI,或必须设置BaseAddress。
需求目标:页面可正常加载无报错,待URL正确赋值后,代码可正常发起请求并展示返回结果。
可行实现方案
按照以下步骤调整即可满足需求:
- 增加请求前置校验:发起API调用前先判断
WorkItemsListUri是否为合法非空URL,页面首次加载URL为空时直接跳过请求逻辑,从根源避免无效调用。 - 补全异常捕获范围:在原有
HttpRequestException捕获逻辑基础上,新增InvalidOperationException类型的异常捕获,避免未预期的异常导致页面崩溃。 - 增加URL赋值后的自动触发逻辑:改写
WorkItemsListUri属性的实现,当属性被赋值为有效URL后,自动触发请求逻辑拉取数据,完成后自动更新页面展示。 - 修正原有异步代码的问题:去掉
.Result的同步阻塞写法,统一使用await做异步调用,避免异步上下文死锁。
调整后的完整参考代码:
// 抽离独立的数据请求方法,支持页面加载、URL更新后复用 private async Task FetchWorkItemsList() { // 前置校验:URL为空或格式不合法时直接返回,不发起请求 if (string.IsNullOrWhiteSpace(WorkItemsListUri) || !Uri.IsWellFormedUriString(WorkItemsListUri, UriKind.Absolute)) { return; } try { HttpResponseMessage response = await client.GetAsync(WorkItemsListUri); response.EnsureSuccessStatusCode(); ResponseContent = await response.Content.ReadAsStringAsync(); JsonResponseContent = JsonConvert.DeserializeObject<WorkItemsListModel>(ResponseContent); // 此处追加页面UI更新逻辑,将返回结果绑定到视图展示 } catch (HttpRequestException e) { System.Diagnostics.Debug.WriteLine("HTTP请求异常:"); System.Diagnostics.Debug.WriteLine(e); } catch (InvalidOperationException e) { System.Diagnostics.Debug.WriteLine("请求配置异常:"); System.Diagnostics.Debug.WriteLine(e); } } // 页面加载生命周期入口 protected override async void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); // 首次加载时调用,因URL为空会直接跳过,不会抛出异常 await FetchWorkItemsList(); } // 改写WorkItemsListUri属性,赋值后自动触发请求 private string _workItemsListUri = string.Empty; public string WorkItemsListUri { get => _workItemsListUri; set { _workItemsListUri = value; OnPropertyChanged(nameof(WorkItemsListUri)); // 用户操作注入URL后,自动发起请求拉取数据 _ = FetchWorkItemsList(); } }
注意点:
前置URL校验相比纯靠异常捕获处理空值的方案性能更高,逻辑边界更清晰;抽离独立请求方法的写法可以避免重复代码,后续需要刷新数据时直接调用该方法即可。
内容的提问来源于stack exchange,提问作者elektra
相关产品推荐
相关产品推荐

