【问题标题】:Asp.net Core 3.1 HttpContext.Session.GetString("Index")Asp.net Core 3.1 HttpContext.Session.GetString("Index")
【发布时间】:2020-10-13 11:46:58
【问题描述】:

我刚开始使用 asp.net Core 3.1 并遇到了使用 Session 变量存储用户登录数据的问题,基本上它在页面之间切换或执行 ajax 发布时随机返回“null”。我花了几个小时在谷歌上搜索并尝试了我所看到的一切,但无济于事。我最终创建了一个新的 Razor 页面 Web 应用程序,但我仍然遇到会话变量返回 null 的问题。要重新生成此内容,请单击“保存更改”按钮,它将执行 HTTP Post,并且会话变量“索引”为空。

我希望有人可以在这里提供帮助。

<HTML>

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}


    <script type="text/javascript">
        $("body").on("click", ".Save", function (e) {

            if (confirm("Do you want to Save all your changes?")) {

                var bd = ["test:", "mike"];
                

                $.ajax({
                    type: "POST",
                    url: "/Index?handler=Fred",
                    cache: false,
                    beforeSend: function (xhr) {
                        xhr.setRequestHeader("XSRF-TOKEN",
                            $('input:hidden[name="__RequestVerificationToken"]').val());
                    },
                    data: JSON.stringify(bd),
                    contentType: "application/json; charset=utf-8",
                    success: function (r) {
                        $("body").html(r);
                        alert("Update Completed");
                    },
                    error: function (result) { alert("error " + result.statusText) }
                });
            }
        });
     </script>

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>first time to this page [ @ViewData["firsttime"].]</p>
    <p>times to the page [ @ViewData["count"].]</p>
    <p>session ID [ @HttpContext.Session.Id]</p>
    <br />
    <p>times posted [ @ViewData["post"].]</p>
    <a class="Save btn btn-outline-danger btn-sm" href="javascript:;">Save Changes</a>
</div>

<HTML>
```     
        Startup.cs
        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
                services.AddDistributedMemoryCache();
                services.AddSession(o =>
                {
                    o.IdleTimeout = TimeSpan.FromMinutes(60);
                    o.Cookie.HttpOnly = true;
                    o.Cookie.IsEssential = true;
                });
                services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
                services.AddRazorPages();
        }

                public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseSession();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }
    }
```

```Index.chtml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using System.Data;

namespace Grid.Pages
{
    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;

        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
            if (HttpContext.Session.GetString("Index") == null)
            {
                ViewData["firsttime"] = "yes";
                ViewData["count"] = 1;
                HttpContext.Session.SetInt32("Index", 1);
                HttpContext.Session.SetInt32("Count", 1);
                HttpContext.Session.SetInt32("Post", 0);
                ViewData["post"] = 0;
            }
            else
            {
                ViewData["firsttime"] = "no";
                int? i = HttpContext.Session.GetInt32("Count");
                ViewData["count"] = i++;
                ViewData["post"] = 0;
                HttpContext.Session.SetInt32("Count", (int)i);
            }
        }
        public void OnPostFred([FromBody] object bd)
        {
            if (HttpContext.Session.GetString("Index") == null)
            {
                int? i = HttpContext.Session.GetInt32("Post");
                ViewData["post"] = i++;
                HttpContext.Session.SetInt32("Post", (int)i);
            }
            else
            {
                ViewData["firsttime"] = "session gone";
            }
        }
    }
}
```

【问题讨论】:

    标签: asp.net asp.net-core


    【解决方案1】:

    在 .Net Core 中,您可以通过IHttpContextAccessor 访问会话。 要启用它,您需要在 Startup.cs 的 ConfigureServices 方法中的服务集合中添加 HttpContextAccessor

    public void ConfigureServices(IServiceCollection services)
            {
                services.AddHttpContextAccessor();
    
                services.AddDistributedMemoryCache();
                services.AddSession(o =>
                {
                    o.IdleTimeout = TimeSpan.FromMinutes(60);
                    o.Cookie.HttpOnly = true;
                    o.Cookie.IsEssential = true;
                });
                services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
                services.AddRazorPages();
            }
    

    现在在您的IndexModel 页面构造函数中,您可以注入依赖项

    private readonly IHttpContextAccessor httpContextAccessor;
            public IndexModel(ILogger<IndexModel> logger,IHttpContextAccessor httpContextAccessor)
            {
                _logger = logger;
                this.httpContextAccessor = httpContextAccessor;
            }
    

    您可以像这样在任何页面上设置/获取会话

    public void OnGet()
            {
                if (httpContextAccessor.HttpContext.Session.GetString("Index") == null)
                {
                    ViewData["firsttime"] = "yes";
                    ViewData["count"] = 1;
                    httpContextAccessor.HttpContext.Session.SetInt32("Index", 1);
                    httpContextAccessor.HttpContext.Session.SetInt32("Count", 1);
                    httpContextAccessor.HttpContext.Session.SetInt32("Post", 0);
                    ViewData["post"] = 0;
                }
                else
                {
                    ViewData["firsttime"] = "no";
                    int? i = httpContextAccessor.HttpContext.Session.GetInt32("Count");
                    ViewData["count"] = i++;
                    ViewData["post"] = 0;
                    httpContextAccessor.HttpContext.Session.SetInt32("Count", (int)i);
                }
            }
    

    【讨论】:

      【解决方案2】:

      我完全按照你说的做了。所以我在调试模式下在 Visual Studio 中启动项目。在索引页面上,我单击隐私页面,然后返回索引页面。会话保持不变。查看从 F12 获取的 HTML

      ````
      <HTML>
      
          <html lang="en"><head>
              <meta charset="utf-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>Home page - Grid</title>
              <link href="/lib/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
              <link href="/css/site.css" rel="stylesheet">
              <script src="https://code.jquery.com/jquery-3.5.1.min.js" crossorigin="anonymous" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="></script>
          
          </head>
          <body>
              <header>
                  <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
                      <div class="container">
                          <a class="navbar-brand" href="/">Grid</a>
                          <button class="navbar-toggler" aria-expanded="false" aria-controls="navbarSupportedContent" aria-label="Toggle navigation" type="button" data-target=".navbar-collapse" data-toggle="collapse">
                              <span class="navbar-toggler-icon"></span>
                          </button>
                          <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                              <ul class="navbar-nav flex-grow-1">
                                  <li class="nav-item">
                                      <a class="nav-link text-dark" href="/">Home</a>
                                  </li>
                                  <li class="nav-item">
                                      <a class="nav-link text-dark" href="/Privacy">Privacy</a>
                                  </li>
                              </ul>
                          </div>
                      </div>
                  </nav>
              </header>
              <div class="container">
                  <main class="pb-3" role="main">
          
                      
          
              <script type="text/javascript">
                  $("body").on("click", ".Save", function (e) {
          
                      if (confirm("Do you want to Save all your changes?")) {
          
                          var bd = ["test:", "mike"];
                          var i = 0;
          
                          $.ajax({
                              type: "POST",
                              url: "/Index?handler=Fred",
                              cache: false,
                              beforeSend: function (xhr) {
                                  xhr.setRequestHeader("XSRF-TOKEN",
                                      $('input:hidden[name="__RequestVerificationToken"]').val());
                              },
                              data: JSON.stringify(bd),
                              contentType: "application/json; charset=utf-8",
                              success: function (r) {
                                  $("body").html(r);
                                  alert("Update Completed");
                              },
                              error: function (result) { alert("error " + result.statusText) }
                          });
                      }
                  });
               </script>
          
          <div class="text-center">
             
              <h1 class="display-4">Welcome</h1>
              <p>first time to this page [ no.]</p>
              <p>times to the page [ 3.]</p>
              <p>session ID [ 33b3e934-206d-0aa8-3db4-0cee6d41a5cf]</p>
              <br>
              <p>times posted [ 0.]</p>
              <a class="Save btn btn-outline-danger btn-sm" href="javascript:;">Save Changes</a>
          </div>
          
                  </main>
              </div>
          
              <footer class="border-top footer text-muted">
                  <div class="container">
                      © 2020 - Grid - <a href="/Privacy">Privacy</a>
                  </div>
              </footer>
          
              <script src="/lib/jquery/dist/jquery.min.js"></script>
              <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
              <script src="/js/site.js?v=dLGP40S79Xnx6GqUthRF6NWvjvhQ1nOvdVSwaNcgG18"></script>
              <input name="__RequestVerificationToken" type="hidden" value="CfDJ8GWv3jmnhshAiL19koM-TGi70Yrjt9_nk_EMCmtKd31IWu5kaP9L9bTKTJSNa0M0YxwaUcmaK2pyZBJ9HDIEebyG7OtRRXZAPkWZ-Jxkj3lcmiAFTl1E3R5TOo1taZRzKJbYP-HwcNasWbPwRdv5Uds">
              
          
          
          </body></html>
      
      <HTML>
      
      ````
      

      然后我单击执行 ajax 发布的“保存更改”,并且会话(“索引”)为空。所以这就是问题所在。查看 ajax 帖子后的 HTML

      ````
      <html lang="en"><head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Home page - Grid</title>
          <link href="/lib/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
          <link href="/css/site.css" rel="stylesheet">
          <script src="https://code.jquery.com/jquery-3.5.1.min.js" crossorigin="anonymous" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="></script>
      
      </head>
      <body>
      
      
      
          
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Home page - Grid</title>
          <link href="/lib/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
          <link href="/css/site.css" rel="stylesheet">
          <script src="https://code.jquery.com/jquery-3.5.1.min.js" crossorigin="anonymous" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="></script>
      
      
      
          <header>
              <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
                  <div class="container">
                      <a class="navbar-brand" href="/">Grid</a>
                      <button class="navbar-toggler" aria-expanded="false" aria-controls="navbarSupportedContent" aria-label="Toggle navigation" type="button" data-target=".navbar-collapse" data-toggle="collapse">
                          <span class="navbar-toggler-icon"></span>
                      </button>
                      <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                          <ul class="navbar-nav flex-grow-1">
                              <li class="nav-item">
                                  <a class="nav-link text-dark" href="/">Home</a>
                              </li>
                              <li class="nav-item">
                                  <a class="nav-link text-dark" href="/Privacy">Privacy</a>
                              </li>
                          </ul>
                      </div>
                  </div>
              </nav>
          </header>
          <div class="container">
              <main class="pb-3" role="main">
      
                  
      
          <script type="text/javascript">
              $("body").on("click", ".Save", function (e) {
      
                  if (confirm("Do you want to Save all your changes?")) {
      
                      var bd = ["test:", "mike"];
                      var i = 0;
      
                      $.ajax({
                          type: "POST",
                          url: "/Index?handler=Fred",
                          cache: false,
                          beforeSend: function (xhr) {
                              xhr.setRequestHeader("XSRF-TOKEN",
                                  $('input:hidden[name="__RequestVerificationToken"]').val());
                          },
                          data: JSON.stringify(bd),
                          contentType: "application/json; charset=utf-8",
                          success: function (r) {
                              $("body").html(r);
                              alert("Update Completed");
                          },
                          error: function (result) { alert("error " + result.statusText) }
                      });
                  }
              });
           </script>
      
      <div class="text-center">
         
          <h1 class="display-4">Welcome</h1>
          <p>first time to this page [ session gone.]</p>
          <p>times to the page [ .]</p>
          <p>session ID [ 33b3e934-206d-0aa8-3db4-0cee6d41a5cf]</p>
          <br>
          <p>times posted [ .]</p>
          <a class="Save btn btn-outline-danger btn-sm" href="javascript:;">Save Changes</a>
      </div>
      
              </main>
          </div>
      
          <footer class="border-top footer text-muted">
              <div class="container">
                  © 2020 - Grid - <a href="/Privacy">Privacy</a>
              </div>
          </footer>
      
          <script src="/lib/jquery/dist/jquery.min.js"></script>
          <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
          <script src="/js/site.js?v=dLGP40S79Xnx6GqUthRF6NWvjvhQ1nOvdVSwaNcgG18"></script>
          <input name="__RequestVerificationToken" type="hidden" value="CfDJ8GWv3jmnhshAiL19koM-TGilawv_ADn2Bqy2OpVOX7UV3GoyvfC_Nk8KhmRUSvic3XHPq3ID73pBHt5s_UchzAooDOM9IvyyMX2fHn-sV8_n_26OLNgvNmJrukJyQPDJg4ICpAbMdqBoRDsIsk6lXI4">
          
      
      
      </body></html>
      
      ````
      

      【讨论】:

      • 您是否在OnPostFred 方法中设置了任何断点?那么您就可以了解您是如何获得session gone. 消息的。您可以更新您的问题或对您正在回复的答案添加评论,而不是发布答案
      • 是的,我已经做到了。我发现它是间歇性的。它随机失败,所以我看不出它如何可靠地使用。我从来没有遇到过asp.net的这个问题。还有什么其他方法可以存储会话数据?
      • HttpSessionState.Timeout 看看这个,docs.microsoft.com/en-us/dotnet/api/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2021-12-25
      • 1970-01-01
      • 2020-07-19
      • 2020-06-21
      • 1970-01-01
      • 2020-06-18
      相关资源
      最近更新 更多