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

MVC控制器设置Session后前端无法读取,求问题排查方案

问题核心:混淆了服务器Session与浏览器sessionStorage

哦,我一眼就看出问题所在了——你把服务器端的Session和浏览器端的sessionStorage当成同一个东西了!这俩完全是不同的存储机制,根本不互通:

  • 服务器的Session["Time"]是存在服务器的内存/会话存储里的,和浏览器的本地存储没有任何关联,前端JS根本没法直接读取服务器Session的值。
  • 你测试时用JS设置sessionStorage能生效,那是因为操作的是浏览器本地的存储,和服务器Session完全是两码事。

你的代码问题分析

控制器里确实正确设置了服务器Session,但前端JS去读取sessionStorage.Time,相当于在浏览器本地找一个完全不存在的键值对,自然不会生效。

正确的解决方案:让控制器直接返回判断结果

AJAX请求的核心就是获取服务器返回的数据,完全没必要绕Session这个弯路。我们可以修改控制器,直接返回JSON格式的重叠判断结果,然后前端JS解析这个响应即可。

第一步:修改控制器方法

把原来的void返回类型改成JsonResult,直接返回是否重叠的布尔值:

public JsonResult TimeCheck() 
{ 
    // 直接通过QueryString获取参数,不用手动拆分字符串,更可靠
    string sinceStr = Request.QueryString["since"];
    string untilStr = Request.QueryString["until"];

    using (ITExpertsContext db = new ITExpertsContext()) 
    { 
        int id = db.Users.FirstOrDefault(x => x.Email.Equals(User.Identity.Name)).UserId; 
        List<WorkingAt> currentHistory = db.WorkingAts.Where(x => x.UserId == id).ToList(); 
        TimeFrame frame = new TimeFrame(); 
        frame.Since = DateTime.Parse(sinceStr); 
        frame.Until = DateTime.Parse(untilStr); 
        
        bool isOverlap = false;
        foreach (WorkingAt w in currentHistory) 
        { 
            // 简化重叠判断逻辑,其实还可以写成更简洁的形式:!(w.Until <= frame.Since || w.Since >= frame.Until)
            if ((w.Since < frame.Until && w.Until > frame.Until) || (w.Since < frame.Since && w.Until > frame.Since)) 
            { 
                isOverlap = true;
                break; // 找到重叠就终止循环,提升效率
            } 
        } 
        // 返回JSON结果,允许GET请求访问
        return Json(new { IsOverlap = isOverlap }, JsonRequestBehavior.AllowGet); 
    } 
}

第二步:修改前端JS代码

不再去读sessionStorage,直接解析服务器返回的JSON响应。另外要注意AJAX是异步操作,原来的写法会导致函数提前返回值,建议用Promise重构来确保逻辑可靠:

// 用Promise封装异步检查逻辑
function TimeCheck() {
    return new Promise((resolve, reject) => {
        var since = $("#Since").val();
        var until = $("#Until").val();
        var request = new XMLHttpRequest();
        
        request.open("GET", "/account/TimeCheck/?since=" + since + "&until=" + until);
        
        request.onload = function() {
            if (request.status === 200) {
                var response = JSON.parse(request.responseText);
                if (response.IsOverlap) {
                    var choice = confirm("The time you selected overlaps with your previous working experience. Do you still want to add it?");
                    resolve(choice);
                } else {
                    resolve(true); // 无重叠,允许提交
                }
            } else {
                reject(new Error("Failed to check time overlap"));
            }
        };
        
        request.onerror = function() {
            reject(new Error("Network error occurred"));
        };
        
        request.send();
    });
}

// 在表单提交时调用这个检查函数
$("form").submit(function(e) {
    e.preventDefault(); // 先阻止默认提交
    var form = this;
    
    TimeCheck().then(allowSubmit => {
        if (allowSubmit) {
            form.submit(); // 用户确认后再提交表单
        }
    }).catch(err => {
        alert(err.message);
    });
});

额外优化建议

  1. 日期解析可以用DateTime.TryParse替代DateTime.Parse,避免前端传入非法日期格式导致服务器报错:
if (!DateTime.TryParse(sinceStr, out DateTime since))
{
    return Json(new { IsOverlap = false, Error = "Invalid since date format" }, JsonRequestBehavior.AllowGet);
}
frame.Since = since;
  1. 重叠判断逻辑可以简化,更易读:
isOverlap = currentHistory.Any(w => !(w.Until <= frame.Since || w.Since >= frame.Until));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:11:47