为什么会话每次都会丢失

时间:2015-07-07 17:56:14

标签: asp.net asp.net-mvc

更新

如果我刷新我的页面然后它确实从Session获取数据并且我通过submit或onchange进行回发然后它会丢失会话

这是我的鳕鱼onchange事件

  

onchange =“document.location.href ='/ Home / Employee?c ='+   this.options [this.selectedIndex] .value;“}

<div class="col-xs-5">
@Html.DropDownListFor(m => m.Name, new SelectList((System.Collections.IEnumerable)ViewBag.DropDownName, "Value", "Text"), new { @class = "form-control", onchange = "document.location.href = '/Home/Employee?c=' + this.options[this.selectedIndex].value;" })
</div>

我不知道为什么我的Session会丢失,每次回发页面时,似乎将会话丢失为null ......我在这里做错了什么?

public static class SessionHelper  
    {
        public static void StoreSessionHomeIndexViewModel(HomeIndexViewModel list)
        {
            HttpContext.Current.Session.Add("HomeIndexViewModel", list);
        }

        public static HomeIndexViewModel GetSessionHomeIndexViewModel()
        {
            return ((HomeIndexViewModel)HttpContext.Current.Session["HomeIndexViewModel"]);
        }
    }

控制器:

private HomeIndexViewModel LoadData()
        {
            var vModel = new HomeIndexViewModel();
            if (SessionHelper.GetSessionHomeIndexViewModel() == null)
            {
                vModel = new HomeIndexViewModel { Employee = _db.CEmployee.ToList() };            
                SessionHelper.StoreSessionHomeIndexViewModel(vModel);
            }
            else
            {
                vModel = SessionHelper.GetSessionHomeIndexViewModel();
            } 
            return vModel;
        }

1 个答案:

答案 0 :(得分:1)

您使用的是基于Uri的会话吗?

如果您是,请查看答案的底部以获得快速解决方案(或阅读完整说明。)

我唯一可以想到的是,你正在使用Uri来保存这样的会话。如果是的话,网址将如下所示:

http://www.domain.com/(S(rzibneny21box4rtmi))/Home/Employee

如果这就是您正在做的事情,那么当您提交表单或更改document.location时,您将丢失会话ID,除非您执行某些操作来保留Uri的(S(rzibneny21box4rtmi))部分。 Uri的那部分是会话ID。

上面将解释为什么简单的页面刷新会保留会话,而覆盖document.location则不会。如果您覆盖document.location,则会丢失会话ID。

示例:使用Cookie会话(不是Uri会话)

我已根据您对onchange事件的使用情况更新了我的答案。如果我使用cookie进行会话,它可以在我的机器上运行,但如果我将cookieless设置为true则不行。

在这个例子中,我试图模仿你的select列表,尽管我的列表与你的列表不同。那是因为我不确定你的视图模型的结构。对于例子而言,这可能已经足够了。

视图

在视图中,我提供了一个提交按钮和一个更改onclick的{​​{1}}事件。两者都与cookie会话一起工作(但不是与uri会话一起工作。)

使用Cookie时,新的document.location会显示在Employee列表中,并且员工数量会按预期增加。

select

模型

我不确定你的视图模型的结构,所以我为了这个例子的目的创建了一个这样的结构。

@model WebApp.Models.HomeIndexViewModel

<form action="~/Home/Employee">
    @Html.DropDownListFor(m =>
            m.FirstName,
            new SelectList(Model.Employees, "FirstName", "LastName"),
            new { onchange = "document.location.href = '/Home/Employee?c=' + this.options[this.selectedIndex].value;" })
    <label>Number of Employees @Model.Employees.Count</label>
    <button type="submit">Submit</button>
</form>

控制器

为了示例,namespace WebApp.Models { using System.Collections.Generic; public class HomeIndexViewModel { public class Employee { public string FirstName { get; set; } public string LastName { get; set; } } public List<Employee> Employees = new List<Employee>() { new Employee() { FirstName = "FirstName0", LastName = "LastName0" }, new Employee() { FirstName = "FirstName1", LastName = "LastName1" } }; public string FirstName { get; set; } } } 操作方法只是将新的Employee对象添加到集合中并返回Employee视图。

Index

辅助

这与原始问题中的助手基本相同。

namespace WebApp.Controllers
{
    using System.Web.Mvc;
    using Models;
    using Helpers;

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var model = LoadData();
            return View(model);
        }

        public ActionResult Employee(string FirstName)
        {
            var model = LoadData();
            return View("Index", model);
        }

        private HomeIndexViewModel LoadData()
        {
            var vModel = new HomeIndexViewModel();
            if (SessionHelper.GetSessionHomeIndexViewModel() == null)
            {
                vModel = new HomeIndexViewModel();
                SessionHelper.StoreSessionHomeIndexViewModel(vModel);
            }
            else
            {
                vModel = SessionHelper.GetSessionHomeIndexViewModel();
                var count = vModel.Employees.Count;
                vModel.Employees.Add(new HomeIndexViewModel.Employee()
                {
                    FirstName = string.Format("FirstName{0}", count),
                    LastName = string.Format("LastName{0}", count)
                });
            }

            return vModel;
        }
    }
}

以上仅适用于我的会话使用Cookie时。如果web.config的namespace WebApp.Helpers { using System.Web; using Models; public static class SessionHelper { public static void StoreSessionHomeIndexViewModel(HomeIndexViewModel list) { HttpContext.Current.Session.Add("HomeIndexViewModel", list); } public static HomeIndexViewModel GetSessionHomeIndexViewModel() { return ((HomeIndexViewModel)HttpContext.Current.Session["HomeIndexViewModel"]); } } } 部分有system.web,则上述示例不起作用,因为表单提交和/或cookieless="true"的更新不会保留{{1} Uri的一部分,因此不保留会话。

示例:适用于Uri Sessions!

如果您使用的是Uri会话,则必须以保留会话ID的方式设置document.location.href(S(rzibneny21box4rtmi))。例如,这是我刚刚攻击的东西。它可以在我的机器上使用无cookie会话。

form.action

现在按预期工作,因为document.location@model WebApp.Models.HomeIndexViewModel <script type="text/javascript"> window.onload = function () { // get the domain plus the session id var index = document.location.toString().lastIndexOf(")"); var sub = document.location.toString().substring(0, index + 1); // using that as the base url // set the form action & onchange event document.getElementById("myForm").action = sub + "/"; document.getElementById("mySelect").onchange = function () { document.location.href = sub + "/Home/Employee?c=" + this.options[this.selectedIndex].value; }; }; </script> <form id="myForm" action=""> @Html.DropDownListFor(m => m.FirstName, new SelectList(Model.Employees, "FirstName", "LastName"), new { id = "mySelect" }) <label>Number of Employees @Model.Employees.Count</label> <button type="submit">Submit</button> </form> 在请求Uri中包含会话ID。你在使用无Cookie会话吗?