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

Blazor组件间传递ResponseData对象问题求助

Blazor组件间传递ResponseData对象的解决方案

问题场景

在LoginCode.razor.cs中发起HTTP请求,将返回的JSON反序列化为ResponseData对象后,需要在SecondMain.razor组件中调用并展示该对象的数据。尝试用NavigationManager.NavigateTo传递对象失败,因为该方法无法直接传递对象。

相关代码信息

JSON响应示例

{"success":{"code":22,"message":"Authentication succeeded","data":"some data","timetolive":86400,"mobilenumber":null}}

ResponseData类定义

namespace AdminFrontend.Services
{
    public class ResponseData
    {
        public SuccessData success { get; set; }
        public ErrorData error { get; set; }
    }

    public class SuccessData
    {
        public int code { get; set; }
        public string message { get; set; }
        public string data { get; set; }
        public int timetolive { get; set; }
        public int mobilenumber { get; set; }
    }

    public class ErrorData
    {
        public int code { get; set; }
        public string message { get; set; }
        public string data { get; set; }
        public int timetolive { get; set; }
        public object mobilenumber { get; set; }
    }
}

当前尝试的代码片段

var response = await httpClient.SendAsync(request);
var antwort = await response.Content.ReadAsStringAsync();
try
{
    response.EnsureSuccessStatusCode();
    var responseData = JsonSerializer.Deserialize<ResponseData>(antwort);
    // Login succees;
    id = Convert.ToInt32(response.StatusCode);
    LoginApi loginApi = new LoginApi(id, antwort);

    _loginErrorMessages = loginApi.GetMessage();
    await InvokeAsync(() => appState.LoggedIn = true);
    navigationManager.NavigateTo($"/secondMain, {responseData}");

}
catch (HttpRequestException)
{
    LoginApi loginApi = new LoginApi(id, antwort);
    _loginErrorMessages = loginApi.GetMessage();
}

可行解决方案

方案1:扩展全局状态管理(AppState)

你已经用到了appState.LoggedIn,直接扩展这个状态类即可实现跨组件数据共享:

  1. 修改AppState类,添加ResponseData属性:
public class AppState
{
    public bool LoggedIn { get; set; }
    public ResponseData LoginResponse { get; set; }

    // 可选:添加状态变更事件,触发组件更新
    public event Action OnStateChanged;
    public void NotifyStateChanged() => OnStateChanged?.Invoke();
}
  1. 在Program.cs中注册为单例服务:
builder.Services.AddSingleton<AppState>();
  1. 在LoginCode.razor.cs中赋值并跳转:
var responseData = JsonSerializer.Deserialize<ResponseData>(antwort);
// ...其他登录逻辑
appState.LoginResponse = responseData;
appState.NotifyStateChanged(); // 触发状态更新
navigationManager.NavigateTo("/secondMain");
  1. 在SecondMain.razor中注入并使用:
@inject AppState AppState
@implements IDisposable

@if (AppState.LoginResponse != null)
{
    <div>
        <p>登录提示:@AppState.LoginResponse.success.message</p>
        <p>返回数据:@AppState.LoginResponse.success.data</p>
        <p>有效期:@AppState.LoginResponse.success.timetolive 秒</p>
    </div>
}

@code {
    protected override void OnInitialized()
    {
        AppState.OnStateChanged += StateHasChanged;
    }

    public void Dispose()
    {
        AppState.OnStateChanged -= StateHasChanged;
    }
}

方案2:使用本地存储(LocalStorage/SessionStorage)

适合需要持久化数据的场景(比如页面刷新后仍保留数据):

  1. 安装Blazored本地存储包:
Install-Package Blazored.LocalStorage
  1. 在Program.cs注册服务:
builder.Services.AddBlazoredLocalStorage();
  1. 在LoginCode.razor.cs中序列化存储:
@inject Blazored.LocalStorage.ILocalStorageService LocalStorage

// ...登录成功后
var responseData = JsonSerializer.Deserialize<ResponseData>(antwort);
await LocalStorage.SetItemAsync("LoginResponse", responseData);
navigationManager.NavigateTo("/secondMain");
  1. 在SecondMain.razor中读取数据:
@inject Blazored.LocalStorage.ILocalStorageService LocalStorage

@if (loginResponse != null)
{
    <div>
        <p>登录提示:@loginResponse.success.message</p>
        <p>返回数据:@loginResponse.success.data</p>
    </div>
}

@code {
    private ResponseData loginResponse;

    protected override async Task OnInitializedAsync()
    {
        loginResponse = await LocalStorage.GetItemAsync<ResponseData>("LoginResponse");
        // 可选:使用后移除数据,避免残留
        // await LocalStorage.RemoveItemAsync("LoginResponse");
    }
}

方案3:路由查询参数传递(仅适合非敏感简单数据)

将对象序列化为JSON字符串作为查询参数传递,注意不要传递敏感信息(URL会暴露数据):

  1. 在LoginCode.razor.cs中序列化并跳转:
var responseData = JsonSerializer.Deserialize<ResponseData>(antwort);
var serializedData = Uri.EscapeDataString(JsonSerializer.Serialize(responseData));
navigationManager.NavigateTo($"/secondMain?response={serializedData}");
  1. 在SecondMain.razor中读取并反序列化:
@inject NavigationManager NavigationManager

@if (loginResponse != null)
{
    <div>
        <p>登录提示:@loginResponse.success.message</p>
        <p>返回数据:@loginResponse.success.data</p>
    </div>
}

@code {
    private ResponseData loginResponse;

    protected override void OnInitialized()
    {
        var uri = new Uri(NavigationManager.Uri);
        var responseParam = System.Web.HttpUtility.ParseQueryString(uri.Query).Get("response");
        if (!string.IsNullOrEmpty(responseParam))
        {
            var deserializedData = Uri.UnescapeDataString(responseParam);
            loginResponse = JsonSerializer.Deserialize<ResponseData>(deserializedData);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 17:40:21