.net核心多页表单不在会话中存储数据 控制器的动作助手类

问题描述

我有一个3页的表单,我试图将每个页面的数据存储在一个会话对象中,但是我无法弄清楚实现中缺少了什么

如果我在assumes 10000 < sal <= 20000;上放置一个断点,则该对象的数据在表单的每一页上始终为空。

为了创建会话对象,我使用了一个助手来创建复杂类型。

控制器的动作

NewUser newUser = GetNewUser();

助手类

private NewUser GetNewUser()
{
    if (HttpContext.Session.GetobjectFromJson<NewUser>("newUser") == null)
    {
        var obj = new NewUser();
        HttpContext.Session.SetobjectAsJson("newUser",obj);
    }
    return (NewUser)HttpContext.Session.GetobjectFromJson<NewUser>("newUser");
}


[HttpGet("BasicDetails")]
[HttpPost("BasicDetails")]
public IActionResult BasicDetails(BasicDetails basicDetailsModel,string prevBtn,string nextBtn)
{
    if (nextBtn != null)
    {
        if (ModelState.IsValid)
        {
            NewUser newUser = GetNewUser();
            newUser.FirstName = basicDetailsModel.FirstName;
            newUser.LastName = basicDetailsModel.LastName;
            newUser.Email = basicDetailsModel.Email;
            newUser.Password = basicDetailsModel.Password;
            newUser.Phone = basicDetailsModel.Phone;
            newUser.Country = basicDetailsModel.Country;
            newUser.City = basicDetailsModel.City;
            newUser.RecieveCommunication = basicDetailsModel.RecieveCommunication;
            return View("Views/CreateAccount/ferretDetails.cshtml");
        }
    }
    return View("Views/CreateAccount/BasicDetails.cshtml");
}

[HttpGet("ferretDetails")]
[HttpPost("ferretDetails")]
public IActionResult ferretDetails(ferretDetails ferretDetailsModel,string nextBtn)
{
    NewUser newUser = GetNewUser();
    if (prevBtn != null)
    {
        BasicDetails basicDetails = new BasicDetails();
        basicDetails.FirstName = newUser.FirstName;
        basicDetails.LastName = newUser.LastName;
        basicDetails.Email = newUser.Email;
        basicDetails.Password = newUser.Password;
        basicDetails.Phone = newUser.Phone;
        basicDetails.Country = newUser.Country;
        basicDetails.City = newUser.City;
        basicDetails.RecieveCommunication = newUser.RecieveCommunication;
        return View("Views/CreateAccount/BasicDetails.cshtml",basicDetails);
    }

    if (nextBtn != null)
    {
        if (ModelState.IsValid)
        {
            newUser.ferretModel = ferretDetailsModel.ferretModel;
            newUser.ferretSerialNumber = ferretDetailsModel.ferretSerialNumber;
            newUser.PurchasedDate = ferretDetailsModel.PurchasedDate;
            newUser.PurchasedFrom = ferretDetailsModel.PurchasedFrom;
            return View("Views/CreateAccount/AccountType.cshtml");
        }
    }
    return View();
}

[HttpPost("/AccountType")]
public IActionResult AccountType(AccountType accountTypeModel,int accountTypeCheck,string createBtn)
{
    NewUser newUser = GetNewUser();
    if (prevBtn != null)
    {
        ferretDetails ferretDetails = new ferretDetails();
        ferretDetails.ferretModel = newUser.ferretModel;
        ferretDetails.ferretSerialNumber = newUser.ferretSerialNumber;
        ferretDetails.PurchasedDate = newUser.PurchasedDate;
        ferretDetails.PurchasedFrom = newUser.PurchasedFrom;
        return View("Views/CreateAccount/ferretDetails.cshtml",ferretDetails);
    }
    if (createBtn != null)
    {
        if (ModelState.IsValid)
        {

        }
    }
    return View();
}

解决方法

如果我在NewUser上设置一个断点newUser = GetNewUser();的数据 该对象在表单的每一页上始终为null。

根据您的代码,我创建了一个示例,看来GetNewUser()方法将始终返回新用户,而不会返回null

由于您将断点放在NewUser newUser = GetNewUser();上,因此可能未执行该语句,因此当您检查值时,它将显示null,如下所示:

enter image description here

执行该语句(尝试按“ F10”或“ F11”键)后,您将获得值:

enter image description here

此外,关于会话价值损失问题,您可以查看以下提示:

  1. 参考the Session and state management in ASP.NET Core来配置会话状态(中间件的顺序很重要):

    在ConfigureServices中添加对AddSession的调用。
    在“配置”中添加对UseSession的调用。

  2. 检查浏览器设置,确保其启用了会话和cookie。

  3. 检查会话配置,确保它没有过期。

  4. 如果您使用的是asp.net core 2.1或2.2版本,请在Startup类的ConfigureServices方法中尝试设置options.CheckConsentNeeded = context => false;

     services.Configure<CookiePolicyOptions>(options =>
     {
       // This lambda determines whether user consent for non-essential cookies is needed for a given request.
       options.CheckConsentNeeded = context => false;
       options.MinimumSameSitePolicy = SameSiteMode.None;
     });
    

    参考:Session variable value is getting null in ASP.NET Core

修改

测试步骤:

  1. 创建一个新的asp.net核心MVC应用程序,

  2. 在Startup.cs类中添加会话:

     public void ConfigureServices(IServiceCollection services)
     { 
         services.AddSession(options =>
         {
             options.IdleTimeout = TimeSpan.FromMinutes(10);
             options.Cookie.HttpOnly = true;
             options.Cookie.IsEssential = true;
         });
         services.AddControllersWithViews();
         services.AddRazorPages();
     }
    
     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
     public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
     {
         ...
    
         app.UseSession();
         app.UseEndpoints(endpoints =>
         {
             endpoints.MapControllerRoute(
                 name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");
             endpoints.MapRazorPages();
         });
     }
    
  3. 添加SessionExtensions.cs:

    公共静态类SessionExtensions { 公共静态无效SetObjectAsJson(此ISession会话,字符串键,对象值) { session.SetString(key,JsonConvert.SerializeObject(value)); }

     public static T GetObjectFromJson<T>(this ISession session,string key)
     {
         var value = session.GetString(key);
    
         return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
     }
    

    }

  4. 添加一个NewUser类,其中包含两个属性:UserID和UserName。

  5. 使用以下代码测试会话:

     public IActionResult Index()
     {
         NewUser newUser = GetNewUser();
    
         var usename = newUser.UserName;
    
         if (HttpContext.Session.GetObjectFromJson<NewUser>("TestData") == null)
         {
             var obj = new NewUser() { UserID = 1001,UserName = "Tom" };
             HttpContext.Session.SetObjectAsJson("TestData",obj);
         }
         return View();
     }
     private NewUser GetNewUser()
     {
         if (HttpContext.Session.GetObjectFromJson<NewUser>("newUser") == null)
         {
             var obj = new NewUser() { UserID=1001,UserName="Jack" };
             HttpContext.Session.SetObjectAsJson("newUser",obj);
         }
    
    
         return (NewUser)HttpContext.Session.GetObjectFromJson<NewUser>("newUser");
     }
    
     public IActionResult Privacy()
     {
         NewUser newUser = GetNewUser();
         var usename = newUser.UserName;
    
         if (HttpContext.Session.GetObjectFromJson<NewUser>("TestData") != null)
         {
             var name = HttpContext.Session.GetObjectFromJson<NewUser>("TestData").UserName;
         }
         return View();
     }
    

然后,检查调试屏幕截图(我们可以从会话中获取值):

enter image description here

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...