You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server(.NET Core 6)中ProtectedSessionStorage使用异常:代码执行退出与序列化错误排查问询

问题分析与解决方案

让我们一步步解决你遇到的两个问题:

1. 初始代码中「直接退出作用域」的问题

你最初的OnInitialized方法用了async void,这是Blazor组件生命周期方法的大忌!

Blazor的组件生命周期方法(比如OnInitialized)如果需要异步操作,必须返回async Task而不是async void。async void主要用于UI事件处理,在生命周期方法中使用它会导致Blazor框架无法追踪异步任务的完成状态,看起来就像是代码「直接退出了作用域」,后续代码不会执行,而且异常也很难被捕获。

修正后的代码应该是这样:

@code {
    [Inject]
    public SessionService SessionService { get; set; } = default!;
    
    // 把async void改成async Task,推荐用OnInitializedAsync更符合异步规范
    protected override async Task OnInitializedAsync()
    {
        await InitUser(); // 必须await异步方法,确保执行完成
        LoadInterface();
    }

    protected async Task InitUser()
    {
        try
        {
            User user = new User("id", "location");
            await SessionService.SetUserProperty(user);
            // 现在这部分代码会正常执行了
            if(/* 你的检查条件 */)
            {
                // 一些其他检查
            }
        }
        catch(Exception ex)
        {
            // 现在异常也能被正确捕获
            Console.WriteLine($"初始化用户出错:{ex.Message}");
        }
    }
}

2. 浏览器控制台的序列化/反序列化错误

这个错误的核心是你的User类构造函数参数和类属性不匹配,导致System.Text.Json无法完成反序列化。

错误信息明确指出:

Each parameter in the deserialization constructor on type 'MyProject.Models.Shared.User' must bind to an object property or field on deserialization. Each parameter name must match with a property or field on the object.

举个例子,假设你的User类是这样写的:

public class User
{
    // 属性名是UserId和UserLocation
    public string UserId { get; set; }
    public string UserLocation { get; set; }

    // 构造函数参数是id和location,和属性名不匹配
    public User(string id, string location)
    {
        UserId = id;
        UserLocation = location;
    }
}

这时Json序列化器无法把构造函数的id参数映射到UserId属性,就会抛出错误。你可以通过以下几种方式解决:

方法一:让构造函数参数名和属性名匹配(大小写不敏感)

修改构造函数参数名,和属性名保持一致:

public class User
{
    public string UserId { get; set; }
    public string UserLocation { get; set; }

    // 参数名改成userId和userLocation,和属性名对应
    public User(string userId, string userLocation)
    {
        UserId = userId;
        UserLocation = userLocation;
    }
}

方法二:给属性添加JsonPropertyName特性

如果不想修改构造函数参数名,可以用特性明确指定参数和属性的映射关系:

using System.Text.Json.Serialization;

public class User
{
    [JsonPropertyName("id")] // 指定序列化时对应"id"字段
    public string UserId { get; set; }
    [JsonPropertyName("location")] // 指定序列化时对应"location"字段
    public string UserLocation { get; set; }

    public User(string id, string location)
    {
        UserId = id;
        UserLocation = location;
    }
}

方法三:添加无参构造函数

如果你的User类不需要依赖构造函数初始化,添加一个无参构造函数也能解决问题(Json序列化器可以通过无参构造函数创建实例,再反射赋值属性):

public class User
{
    public string UserId { get; set; }
    public string UserLocation { get; set; }

    // 添加无参构造函数
    public User() { }

    public User(string id, string location)
    {
        UserId = id;
        UserLocation = location;
    }
}

总结

  1. 组件生命周期异步方法必须返回Task,用async Task代替async void;
  2. 确保User类的构造函数参数和属性能被Json序列化器正确映射,选择上面任意一种方法都可以解决序列化错误。

内容的提问来源于stack exchange,提问作者Berzohr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 12:42:26