.NET Core MVC中GET表单提交时如何保留验证码变量值
解决.NET Core MVC提交表单后验证码值清空的问题
你的问题根源在于HTTP是无状态协议,每次点击提交按钮发起的都是全新请求:
- ViewData仅在当前请求周期内有效,新请求到来时之前的ViewData数据会被清空,所以
var rnumber = ViewData["captcha"];会得到null。 - 如果
randnumber是Controller的类成员变量,每次请求都会创建新的Controller实例,该变量会被重置为默认值(null)。
以下是两种可行的解决方案:
方案一:使用Session存储验证码
Session可以在多个请求间持久化数据,适合存储这类需要跨请求验证的信息。
1. 启用Session
- .NET 6+(Program.cs):
builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(5); // 设置验证码过期时间 options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; }); // 在app.UseRouting()之后添加 app.UseSession();
- .NET Core 3.x及以前(Startup.cs):
在ConfigureServices方法添加services.AddSession(...);,在Configure方法的app.UseRouting()之后添加app.UseSession();。
2. 修改后端Index方法
public IActionResult Index(string cap) { // 从Session获取上一次生成的验证码 var storedCaptcha = HttpContext.Session.GetString("captcha"); // 验证用户输入的验证码 if (!string.IsNullOrEmpty(cap) && !string.IsNullOrEmpty(storedCaptcha)) { if (cap == storedCaptcha) { Isvisble = "visible"; } } // 生成新的验证码并存入Session和ViewData var randnumber = RandomString(6); HttpContext.Session.SetString("captcha", randnumber); ViewData["captcha"] = randnumber; return View(); }
方案二:使用隐藏字段传递验证码
如果不想依赖Session,可以把验证码存入表单的隐藏字段,提交时和用户输入一起传递到后端。
1. 修改前端cshtml代码
添加一个隐藏字段存储当前验证码:
<form method="post" asp-action="Index"> <div class="container"> <h1 class="display-4">Welcome</h1> <label for="captcha"><b>Enter chaptcha - </b></label> <label id="lblCapval" for="captchasym"><b>@ViewData["captcha"]</b></label> <!-- 新增隐藏字段存储验证码 --> <input type="hidden" name="storedCaptcha" value="@ViewData["captcha"]" /> <input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required> <br /> <button class="button" type="submit">Login</button> </div> </form>
注意:这里把请求方法改为
post,避免验证码参数暴露在URL中,更安全。
2. 修改后端Index方法
拆分Get和Post方法,逻辑更清晰:
[HttpGet] public IActionResult Index() { // 首次加载生成验证码 var randnumber = RandomString(6); ViewData["captcha"] = randnumber; return View(); } [HttpPost] public IActionResult Index(string cap, string storedCaptcha) { // 验证验证码 if (!string.IsNullOrEmpty(cap) && !string.IsNullOrEmpty(storedCaptcha)) { if (cap == storedCaptcha) { Isvisble = "visible"; } } // 生成新的验证码返回给页面 var randnumber = RandomString(6); ViewData["captcha"] = randnumber; return View(); }
补充:RandomString方法的正确实现
确保你的随机字符串生成方法没有问题,示例如下:
private string RandomString(int length) { const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var random = new Random(); return new string(Enumerable.Repeat(chars, length) .Select(s => s[random.Next(s.Length)]) .ToArray()); }
内容的提问来源于stack exchange,提问作者Arvind Chourasiya
相关产品推荐
相关产品推荐

