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

MVC中Controller与View双向传值问题:折叠时ViewData数据为空

问题根源分析

你遇到的核心问题是ViewData的生命周期限制:ViewData只在当前HTTP请求中有效,每次点击折叠按钮发起新请求时,服务器都会创建一个全新的ViewData实例,之前存储的状态自然就丢失了,这就是为什么折叠操作时objectvalue会变成null的原因。

解决方案:改用Session持久化状态

Session是跨请求保存用户级数据的容器,正好适合这种需要在多次请求间保留UI状态的场景。下面是修改后的代码:

控制器代码修改

[HttpGet]
public ActionResult RegionHeaderItem(int regionId)
{
    // 从Session中获取已有的状态字典,没有则返回null
    var sessionItem = Session["RegionDashboardHeader"] as IDictionary<int, bool>;
    
    if (sessionItem != null)
    {
        // 切换对应regionId的状态
        if (sessionItem.ContainsKey(regionId))
        {
            sessionItem[regionId] = !sessionItem[regionId];
        }
        else
        {
            sessionItem.Add(regionId, true);
        }
    }
    else
    {
        // 首次请求时初始化状态字典
        sessionItem = new Dictionary<int, bool>();
        sessionItem.Add(regionId, true);
    }
    
    // 将更新后的状态存回Session
    Session["RegionDashboardHeader"] = sessionItem;
    
    var regionVMObj = this.GetRegionDetails(regionId);
    return PartialView(regionVMObj);
}

视图代码修改

// 从Session读取状态,而不是ViewData
var sessionItem = Session["RegionDashboardHeader"] as IDictionary<int, bool>;
var display = sessionItem == null ? false : sessionItem.ContainsKey(Model.Id) ? sessionItem[Model.Id] : false;
可选方案:前端存储状态(更轻量)

如果这个展开/折叠状态只是纯UI需求,不需要和服务器端逻辑绑定,推荐直接用前端的localStorage或sessionStorage来保存状态,这样可以减少服务器请求,提升性能:

前端交互代码(示例用jQuery)

// 绑定展开/折叠按钮的点击事件
$('.region-toggle-btn').on('click', function() {
    const regionId = $(this).data('region-id');
    // 读取当前存储的状态,没有则初始化空对象
    const state = JSON.parse(localStorage.getItem('RegionDashboardHeader')) || {};
    // 切换状态
    state[regionId] = !state.hasOwnProperty(regionId) || !state[regionId];
    // 保存回localStorage
    localStorage.setItem('RegionDashboardHeader', JSON.stringify(state));
    
    // 直接切换DOM显示(如果不需要重新加载PartialView的话)
    $(`#region-content-${regionId}`).toggle();
});

视图中读取前端状态

const regionId = @Model.Id;
const state = JSON.parse(localStorage.getItem('RegionDashboardHeader')) || {};
const display = state.hasOwnProperty(regionId) ? state[regionId] : false;

// 初始化时设置显示状态
if (display) {
    $(`#region-content-${regionId}`).show();
} else {
    $(`#region-content-${regionId}`).hide();
}
方案对比
  • Session方案:适合需要服务器端同步状态的场景(比如结合权限控制),但要注意Session的过期时间配置,以及高并发下的服务器负载。
  • 前端存储方案:更轻量,无需服务器交互,适合纯UI状态保存,但如果状态需要和服务器逻辑关联(比如权限控制后才能展开)则不适用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:01:11