为何第二次调用LocalStorage GetAsync方法无法获取值?
我基于JS文件实现了LocalStorage服务,用GetAsync方法获取存储的授权Token对象(包含UserID、UserName、UserSurname三个字段)。
相关代码如下:
localStorage.js
function get(key) { console.log('getItem') return localStorage.getItem(key) }
ILocalStorageService.cs
public async Task<T> GetAsync<T>(string key) where T : class { var data = await jsRuntime.InvokeAsync<string>("get", key); Console.Write("getItem"); if (string.IsNullOrEmpty(data)) { Console.WriteLine("LocalStorageService: token is null"); return null; } return JsonSerializer.Deserialize<T>(data); }
Token.cs
public class Token { public string UserID { get; set; } public string UserName { get; set; } public string UserSurname { get; set; } }
我两次调用该方法:第一次在页面加载的授权逻辑中可正常获取Token;第二次调用时,Chrome控制台显示两次getItem,但调试到var data = await jsRuntime.InvokeAsync<string>("get", key);就终止,既无返回值也无报错,控制台没输出“Operator is get”。第二次调用代码如下:
var operatorToken = await localStorageService.GetAsync<Token>(nameof(Token)); Guid operatorID = Guid.Parse(operatorToken.UserID); Console.WriteLine("Operator is get");
请问为何第二次无法获取值,该如何修复?
可能原因1:异步上下文阻塞(死锁)
第二次调用的代码可能处于同步方法中,强行用.Result/.Wait()等待异步操作,导致.NET端的异步回调被阻塞。JS层虽然执行了get方法并打印日志,但.NET端无法继续执行后续代码,出现无响应的情况。
可能原因2:Token数据异常或空引用
第一次调用后,Token可能被意外清除、篡改,或者序列化/反序列化失败。此时GetAsync返回null,但调用代码直接访问operatorToken.UserID会抛出NullReferenceException,由于异常未被捕获且处于异步上下文,导致执行终止且无明显报错。
修复步骤
确保异步调用全程使用
await
必须在async方法中调用异步方法,禁止用.Result/.Wait()阻塞线程:// 错误示例(同步方法阻塞异步调用) public void SomeSyncMethod() { var token = localStorageService.GetAsync<Token>(nameof(Token)).Result; // 易导致死锁 } // 正确示例 public async Task SomeAsyncMethod() { var operatorToken = await localStorageService.GetAsync<Token>(nameof(Token)); // 先校验返回值 if(operatorToken == null) { Console.WriteLine("Token不存在或已失效"); return; } Guid operatorID = Guid.Parse(operatorToken.UserID); Console.WriteLine("Operator is get"); }添加异常捕获与数据校验
给GetAsync方法和调用处增加异常处理与数据校验,定位问题:- 修改
ILocalStorageService.cs:public async Task<T> GetAsync<T>(string key) where T : class { try { var data = await jsRuntime.InvokeAsync<string>("get", key); Console.WriteLine(".NET端获取数据:" + data); // 新增日志排查 if (string.IsNullOrEmpty(data)) { Console.WriteLine("LocalStorageService: token is null"); return null; } return JsonSerializer.Deserialize<T>(data); } catch(Exception ex) { Console.WriteLine("LocalStorage获取失败:" + ex.Message); return null; } } - 修改第二次调用代码:
var operatorToken = await localStorageService.GetAsync<Token>(nameof(Token)); if(operatorToken == null || string.IsNullOrEmpty(operatorToken.UserID)) { Console.WriteLine("Token无效或不存在"); return; } // 用TryParse避免格式错误抛出异常 if(Guid.TryParse(operatorToken.UserID, out Guid operatorID)) { Console.WriteLine("Operator is get,ID:" + operatorID); } else { Console.WriteLine("UserID格式错误"); }
- 修改
验证LocalStorage实际存储内容
在Chrome控制台执行localStorage.getItem('Token'),检查返回的JSON是否有效、是否包含UserID字段。如果数据异常,排查第一次存储Token的代码是否正确序列化对象。
内容的提问来源于stack exchange,提问作者Roman Nichi

