【问题标题】:How to retrieve browser session data in ASP.Net MVC Controller?如何在 ASP.Net MVC 控制器中检索浏览器会话数据?
【发布时间】:2017-11-29 18:55:15
【问题描述】:

这个问题我很难过。我做了很多研究,但没有发现任何有效的方法!

我想做的事: 我想用javascript捕捉用户的时区和utc时区偏移量,将这两条数据存储在浏览器会话中,然后在控制器中检索。

什么是有效的: 我的 javascript 正在提取用户的时区和时区偏移量,并将这两个变量保存到会话中。以下是我的工作 JS:

<script type="text/javascript">
 window.onload = function () {
     var UserTime = new Date();
     var stringtz = UserTime.toString();
     var tzstart = stringtz.indexOf("(") + 1;
     var tzend = stringtz.indexOf(")");
     var userTZ = stringtz.slice(tzstart, tzend);
     sessionStorage.setItem("userTZOffset", UserTime.getTimezoneOffset().toString());
     sessionStorage.setItem("userTZ", userTZ);
 };
</script>

什么不起作用: 当用户登录时,我想获取会话中保存的两个变量(userTZ 和 userTZOffset)并为它们创建声明。但是,当我尝试将它们拉入我的控制器时,我得到 null 作为值。经过进一步检查,我可以看到会话超时、id 等,但键和值是空白的。

这是我在控制器中登录操作的代码片段:

        var claims = UserManager.GetClaims(user.Id);

        var timezoneclaim = claims.First(c => c.Type == "UserTZ");
        UserManager.RemoveClaim(user.Id, timezoneclaim);

        var timezoneoffsetclaim = claims.First(c => c.Type == "UserTZOffset");
        UserManager.RemoveClaim(user.Id, timezoneoffsetclaim);

        var test = HttpContext.Session["userTZ"];
        var test2 = HttpContext.Session["userTZOffset"];

        UserManager.AddClaim(user.Id, new Claim("UserTZ", test.ToString()));
        UserManager.AddClaim(user.Id, new Claim("UserTZOffset", test2.ToString()));

我在此设置断点并遍历代码,但每次 test 和 test2 都是空的。当我在断点上查看会话本身时,我看到了 SessionId、Timeout 等,但计数为 0,Key 计数为 0。

我试过了:

  1. 添加 remove name="Session" 并将 name="Session" type="System.Web.SessionState.SessionStateModule" 添加到我的 webconfig 基于我发现的类似问题 here
  2. 我尝试添加 Microsoft.Aspnet.Session nuget 包并遵循 this 教程,但我的项目的 startup.cs 没有 ConfigureServices 部分,并且添加我自己的也不起作用。
  3. 我根据找到的here 在 webconfig 中将会话状态设置为 InProc,但同样没有任何变化。

想法?

【问题讨论】:

  • 您是否尝试过在 Application_Start 事件内的 Global.asax 文件中初始化 Session 变量,或者在正常的 asp.net 中,相同的文件会有一个 Session_Start 事件。查看此链接以获取一些指针/提示stackoverflow.com/questions/560084/…
  • 你不能。 HttpContext.Session 是服务器端的,不知道或无法访问客户端 (DOM) localStorage 或 sessionStorage。这些仅适用于浏览器。您必须明确地将数据从 Javascript 发送到服务器,例如通过 AJAX 调用、表单 POST 或其他一些机制。
  • 您是否也尝试过以下情况 - HttpContext.Current.Session["userTZ"]
  • @MethodMan HttpContext.Current.Session["userTZ"] 给我一个构建错误,因为 HttpContext 由于某种原因在我的解决方案中没有“当前”。我必须添加一个特殊的 using 语句吗? VS 告诉我改用 CurrentHandler 或 CurrentNotification。使用这些中的任何一个都有意义吗?
  • 是的,有一条 using 声明,但请阅读我发布的链接,它在 MVC 中与普通的 asp.net Web 应用程序不同

标签: c# asp.net asp.net-mvc session


【解决方案1】:

您不能使用HttpContext.Session["userTZ"],因为从客户端传递的数据未存储在服务器端Session State 中。相反,您需要使用HiddenValue 将这些值传递回服务器。

登录视图模型

public class LoginViewModel
{
    ...        
    public string UserTZ { get; set; }        
    public string UserTZOffset { get; set; }
}

查看

@using (Html.BeginForm(...))
{
     ...

    @Html.HiddenFor(m => m.UserTZ)
    @Html.HiddenFor(m => m.UserTZOffset)
}

<script type="text/javascript">
    $(function() {
        var UserTime = new Date();
        var stringtz = UserTime.toString();
        var tzstart = stringtz.indexOf("(") + 1;
        var tzend = stringtz.indexOf(")");
        var userTZ = stringtz.slice(tzstart, tzend);
        $("#@Html.IdFor(m => m.UserTZOffset)").val(UserTime.getTimezoneOffset().toString());
        $("#@Html.IdFor(m => m.UserTZ)").val(userTZ);
    });
</script>

控制器

[HttpPost]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    string userTZ = model.UserTZ,
           userTZOffset = model.UserTZOffset;
    ...
}

【讨论】:

    【解决方案2】:

    会话在服务器端维护。因此,如果您想存储用户时区和偏移量,您应该根据来自客户端的某些事件(例如登录按钮单击)将它们从客户端传递到 mvc 控制器。然后在服务器上,您可以将它们存储在会话变量中,对于同一会话中的后续请求,您可以在服务器上检索这些值。对于后续请求,您也可以将这些会话值从控制器传递到其他视图(使用 ViewBag / Viewdata)。如果您需要此代码 sn-p,请告诉我。

    【讨论】:

      猜你喜欢
      • 2016-02-07
      • 1970-01-01
      • 1970-01-01
      • 2019-12-03
      • 1970-01-01
      • 2013-07-06
      • 1970-01-01
      • 1970-01-01
      • 2011-10-11
      相关资源
      最近更新 更多