I'm building an ASP.NET Core MVC Application in which when the user clicks on "Generate OTP" then a 4 digit OTP is shown to him on the screen and then he has to enter that OTP in an input field and click "Submit OTP" tp submit it. If the OTP is correct and is entered within 30 seconds then the user will be shown a success message otherwise the user will get an exception either that the OTP is timed-out or is incorrect.
I have written the controller code for generating the OTP, Sending it, and Submitting it.
The issue I'm facing is in the "Controller". I have stored the value of the generated OTP from "generateOtp" Action Method in "TempData["otp]" and now I'm trying to use it in "submitOtp" Action Method. But it's not working, what am I getting wrong here?
**Controller**
namespace OTP_Sms_Verification.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
[HttpGet]
public IActionResult GenerateOtp()
{
return View();
}
[HttpPost]
public IActionResult SendOtp(Home home)
{
var hom = new Home();
home.num="01223456789";
home.len = home.num.Length;
home.otp = String.Empty;
home.otpDigit = 4;
for (int i = 0; i < home.otpDigit; i )
{
do
{
home.getIndex = new Random().Next(0, home.len);
home.finalDigit = home.num.ToCharArray()[home.getIndex].ToString();
} while (home.otp.IndexOf(home.finalDigit) != -1);
home.otp = home.finalDigit;
}
TempData["otp"] = home.otp;
//ViewBag.otp = home.otp;
//ViewData["otp"] = home.otp;
//TempData["timestamp"] = DateTime.Now;
return RedirectToAction("GenerateOtp");
}
[HttpPost]
public IActionResult SubmitOtp([FromForm] int finalDigit)
{
int a = Convert.ToInt32(TempData["otp"]);
if (finalDigit == null) {
return NoContent();
}
else if ((DateTime.Now - Convert.ToDateTime(TempData["timestamp"])).TotalSeconds > 30)
{
return BadRequest("OTP Timedout");
}
else if (finalDigit.ToString() == Convert.ToString(a))
{
return Ok("OTP Accepted");
}
else
{
return BadRequest("Please Enter Valid OTP");
}
}
}
}
**Model**
@model OTP_Sms_Verification.Models.Home;
@{
ViewData["Title"] = "GenerateOtp";
}
<h1>GenerateOtp</h1>
<form method="post" asp-action="SendOtp" asp-controller="Home">
<br />
<input type="submit" value="GetOtp" />
<br />
<div>
@TempData["otp"]
</div>
</form>
@using (Html.BeginForm("SubmitOtp", "Home", FormMethod.Post))
{
<table cellpadding="0" cellspacing="0">
<tr>
<td>OTP: </td>
<td>
<input type="number" name="finalDigit">
</td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="SubmitOtp"/></td>
</tr>
</table>
}
CodePudding user response:
TempData only works during the current and subsequent request. So when you submit it, it is the third request and it will lose the stored value. To persist it, you can try to use TempData Keep
or Peek
function.
The Keep
function is used to preserve the data of TempData
object even after the value is read while the Peek
function is used to read the value without clearing it.
Change your view code to:
<form method="post" asp-action="SendOtp" asp-controller="Home">
<br />
<input type="submit" value="GetOtp" />
<br />
<div>
@TempData["otp"]
@{
TempData.Keep("otp"); //add this...
}
</div>
</form>
More details you could refer to this answer here.
If you use TempData
more than three requests, I suggest you using Session
.