I am working on a method that will apply to 2 different views "/DogProfile" and "/DogProfile/Profile" I want to call this method and then have it return to the current page, as it does now for "DogProfile". However, I am having trouble identifying how to create a variable that would store the url of the page I am operating from. i.e. now if I were on the Profile view and run the page I am redirected to the "/DogProfile" page instead of back to the "DogProfile/Profile" page.
Dog Profile Controller:
public IActionResult CheckOut(string activity, int dogID)
{
var status = context.Dogs.Find(dogID);
status.CheckedOut = true;
status.Activity = activity;
status.TimeCheckOut = DateTime.Now;
context.SaveChanges();
return Redirect("/dogprofile");
}
Profile view:
#model WebApplication2.Models.Dog;
<h1>#Model.DogName</h1>
<img src="#Model.ImageSource" class="dogProfile"><img />
<br />
<br />
#if (Model.Description != null)
{
<h2>Dog Special Requirements:</h2>
<p>#Model.Description</p>
}
<form asp-controller="DogProfile" asp-action="CheckOut" method="post">
<select name="activity" id="activity">
<option value="walk">Walk</option>
<option value="furlough">Furlough</option>
<option value="bathe">Bathe</option>
</select>
<br />
<input type="submit" value="Check Out" />
<input type="hidden" name="dogID" value="#Model.Id" />
</form>
If you want to submit via the Profile page and return to the current "DogProfile/Profile" page instead of the "/DogProfile" page, you can try the following code.
[HttpPost]
public IActionResult CheckOut(string activity, int dogID)
{
var status = _context.Dogs.Find(dogID);
status.CheckedOut = true;
status.Activity = activity;
status.TimeCheckOut = DateTime.Now;
_context.SaveChanges();
return Redirect("/dogprofile/profile" + "/" + dogID);
}
Related
I'm creating an edit user page which will modify a user's existing role name within the web app. However, upon POST request, the Edit's view model becomes null after containing the values from the form (checked this using breakpoints).
I then get a prompt message in Visual Studio saying:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Microsoft.AspNetCore.Mvc.Razor.RazorPage\<TModel\>.Model.get returned null.
UserController.cs
[HttpPost]
public async Task<IActionResult> Edit(IFormCollection formCollection)
{
try
{
await _userControllerService.EditAzureUser(formCollection);
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
UserControllerService.cs
public async Task EditAzureUser(IFormCollection formCollection)
{
string id = formCollection["User.PrincipalId"];
string appRoleId = formCollection["User.AppRoleId"];
//Edit logic here
}
Edit.cshtml
#model CreateUserViewModel
#{
ViewData\["Title"\] = "Edit User";
}
<label asp-for="User.PrincipalDisplayName" class="col-form-label">Name: </label>
<input asp-for="User.PrincipalDisplayName" value="#Model.User.PrincipalDisplayName" readonly class="form-control"/>
<label class="col-form-label">Role: </label>
<select asp-for="User.AppRoleName" title="Select Role" required class="form-control" style="margin-bottom: 1rem"/>
#{
foreach(var role in AppRole.Roles)
{
if(Model.User.AppRoleName == role)
{
<option value="#role" selected>#role</option>
} else
{
<option value="#role">#role</option>
}
}
}
<input type="hidden" asp-for="User.AppRoleId"/>
<input type="button" value="Cancel" class="btn btn-secondary btn-sm" onclick="goBack()" />
<input type="submit" class="btn btn-info btn-sm" />
Your POST method doesn't return a model to the view, but the view expects a non-null CreateUserViewModel, which it uses in the markup. My guess is that's why you're getting the NRE.
However, if the POST was successful, why are you going back to the edit page anyway? Either send them to another page (often a user list if this is an admin facility, or a "thank you page if it's for the users themselves), or modify the Razor in this view to show a message saying the edit was successful. Either way, you don't need the model.
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" class="btn btn-primary btn-lg"/>
<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>
}
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" class="btn btn-primary btn-lg"/>
<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.
I have an asp.net mvc4 application in which i'd to use the .post ajax's function to post a variable in my view. i had this problem and i posted it here : question, so i'm now trying to solve it by the use of Ajax
View : index.cshtml
<td>
Donner votre avis.
</td>
and
<form method="Post" action="/User/Validate_Expert_Decision" target="_parent">
<span>
<b style="color:red" >
Votre justification *
<b />
<br />
<br />
<textarea rows="10" cols="75" name="justification"></textarea>
</span>
<input type="hidden" name="element" value="#Request.Params["element"]" />
<p>
<input type="submit" name="submit">
<input type="button" name="cancel" value="Annuler" onClick="closebox()">
</p>
</form>
the javascript function
function openbox2(formtitle, fadin) {
var self = $(this);
var arr = self.data('arr');
$.post("/index.cshtml", { element: arr });
var box = document.getElementById('box');
document.getElementById('shadowing').style.display = 'block';
var btitle = document.getElementById('boxtitle');
btitle.innerHTML = formtitle;
if (fadin) {
gradient("box", 0);
fadein("box");
}
else {
box.style.display = 'block';
}
}
controller : Validate_Expert_Decision
public ActionResult Validate_Expert_Decision()
{
string id_element = Request.Params["element"];
return RedirectToAction("Display_Task_List", new { id_project = id_project});
}
the problem is that i always get an empty value of id_element in string id_element = Request.Params["element"];.
What are the reasons of this error? How can i fix it?
If you want to post an ajax request you must use urls in this pattern:
/Area/Controller/Action
in your ajax request you specify your view name, but url for ajax request must be:
$.post("#Url.Action("ActionName, ControllerName, new { Area = "AreaName" }")", { element: arr });
and if you don't have area, just remove last argumant.
Instead of Request.Params["element"] you can easily get your variables by argumant in your action method:
public ActionResult Validate_Expert_Decision(string element)
** If you want to learn ASP.Net MVC i suggest you to read this book:
Pro ASP.Net MVC 4
This is one of best books that i have read until now
I have a asp.net mvc application with razor engine.
In a view Home i have this snippet:
<section id="form_admin">
<form action="/Super/Manipuler" method="post">
<fieldset>
<legend>Formulaire d'ajout d'un administrateur</legend>
#Html.Label("Login")
#Html.Label("Mail")
#Html.Label("Password")
#Html.Label("Name")
<br />
<br />
#if(Model != null){
foreach (Upload.Models.AdminModels admin in Model)
{
if (i == 0){
<input type="radio" checked class="radio" name="radio" value="#admin.Login" >
}
else{
<input type="radio" class="radio" name="radio" value="#admin.Login" style="margin-left:0.3px;">
}
<label id="log">#admin.Login</label>
<label id="logm">#admin.Mail</label>
<label id="logp">#admin.Password</label>
<label id="logn">#admin.Name</label>
<br />
i++;
}
}
<br />
<input type="submit" value="Editer" name="submit_button"/>
<input type="submit" value="Supprimer" name="submit_button" />
Créer un nouveau compte
</fieldset>
</form>
</section>
In the controller : the action Manipuler is the below:
public ActionResult Manipuler()
{
string buttonName = Request.Form["submit_button"];
string _login = Request.Params["radio"];
Upload.Models.AdminModels admin = new AdminModels();
Upload.Models.CompteModels.Modifiying_login = _login;
if (buttonName == "Editer") { return RedirectToAction("Edit", "Admin"); }
else { admin.Delete_admin(_login); return RedirectToAction("Home", "Super"); }
}
It's works fine but i'd like to change the radiobox to checkbox.
My question is how to know all checked box in the collection of checkbox in the action Manipuler ?
Take a look at Phil Haack's article on model binding a checkbox list. Basically, you just need to set up the HTML in a specific way (name your checkboxes the same which will then convert the various POSTed values into a list).
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
I need to link to the database (finance rates) when someone enters a number in the text box and clicks calculate that it will pull the rates from the database and display the calculation below in a 'form message'. What should I put in the homecontroller/index to link the code to the database?
Index.aspx:
<td>You wish to convert:
<input type="text" name="amount" size="30" onblur="test_ifinteger(Index.amount,'amounts')"/>
<input type="submit" name="submitter" value="calculate" />
<tr><td colspan="2">That will produce:<%=ViewData["formmessage"] %></td></tr>
Home Controller:
public ActionResult Index()
{
financeInit();
if (Request.Params["submitter"] == "calculate")
calculatepressed();
return View();
public void calculatepressed()
{
.............
}
I would wrap your fields in a form like this:
<form action="Home" method="get">
<div>
You wish to convert:
<input type="text" name="amount" size="30" id="userValue" onblur=""test_ifinteger(Index.amount,'amounts')"/>
<input type="submit" name="userSubmit" />
<br />
That will produce:<%=ViewData["formmessage"] %>
</div>
</form>
Then have your controller something like this:
public ActionResult Index()
{
int value;
if (int.TryParse(Request.Params["amount"], out value))
{
ViewData["formmessage"] = calculatepressed(value);
}
return View();
}
private string calculatepressed(int value)
{
// Do your magic here and return the value you calculate
return value.ToString();
}
If this ever expands from a simple page you might want to consider changing the form action to a post and having two different methods handling the initial view of the home page and the a view for the results of the calculation.