Getting name of button on postback - button

I have built a 'buy products' page dynamically by building it up for each product. Each product has an 'Add to Basket' button, which are differentiated for each product by having the pID as the buttons name attribute. I now want to get the value of the name attribute within my controller on postback. Not sure how to do this:
View:
#foreach (Ecommerce.Models.HomeModels.Product product in Model)
{
using (Html.BeginForm())
{
#Html.Label(product.Name);
<br />
#Html.Label(product.Description);
<br />
#Html.Label(product.UnitPrice.ToString());
<p></p>
<input name="#product.ID" type="submit" value="Add to Basket" />
}
}
Controller:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult BuyProducts(string button)
{
}

If you don't have multiple submit buttons inside a form then there is no need to know on the server side what was the name of the clicked submit button. There are other ways to send back your Id to the server:
Why don't you just generate a hidden field inside your form to hold and post the data?
#foreach (Ecommerce.Models.HomeModels.Product product in Model)
{
using (Html.BeginForm())
{
<input type="hidden" name="productId" value="#product.ID" />
<input type="submit" value="Add to Basket" />
}
}
Then you can get the value of the hidden field in your controller:
public ActionResult BuyProducts(string productId)
{
//..
}

Related

Razor Pages action from input button

I'm trying to understand how Razor pages work, as well as .Net Core, by creating a small web application and I'm stuck on how to handle the button action within a form. I'm used to the MVC type of process (from when I first tried web apps 5 years ago) where the button would have a onClick action that could be accessed from the code behind but it seems like that's not the same with a Razor page (unless I'm just not seeing it). I have a basic form like this
<form method="post">
<fieldset>
<input type="text" value="" placeholder="user name"/>
<input type="password" value="" placeholder="password"/>
<input type="button" value="Submit" id="submitButton"/>
</fieldset>
So what I'm trying to achieve is when the button is pressed an action in the .cs file is called that will perform a couple different operations (like calling an API, getting a result and then depending on result route to a different page) but even if I add an "onClick" to the button I can't figure out how to hook it up to the code behind. I've seen various answers, most using models and a database but since that's not the same as what I'm doing those examples haven't helped.
I will try to make a simple example for you. Create a razor page and use the name "Test". The Test.cshtml file should have the following contents:
#page
#model WebApplication1.Pages.TestModel
<form method="post">
<fieldset>
<input asp-for="username" placeholder="user name" />
<span asp-validation-for="username" class="text-danger"></span>
<br />
<input asp-for="password" type="password" placeholder="password" />
<span asp-validation-for="password" class="text-danger"></span>
<br />
<input type="submit" value="Submit" id="submitButton" />
</fieldset>
</form>
The Test.cshtml.cs should have the following contents
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace WebApplication1.Pages
{
public class TestModel : PageModel
{
[BindProperty]
public string username { get; set; }
[BindProperty]
public string password { get; set; }
public void OnGet()
{
// you can initialize the values. for example I set the username
username = "test";
}
public IActionResult OnPost()
{
// do something with username and password
if (string.IsNullOrEmpty(password))
{
ModelState.AddModelError("password", "Password is a required field.");
return Page();
}
// or you can redirect to another page
return RedirectToPage("./Index");
}
}
}
Tell me if you need extra explanation for this example. I hope it helps.

How to get checkbox values from another form with asp .net MVC4?

Here is a simplified example. My first form :
#using (Html.BeginForm("Action1", "MyController", FormMethod.Post))
{
<input id="cb" type="checkbox" value="true" name="MyCheckBox" />
<label for="cb">Check this out</label>
}
And late in the same view, another form :
#using (Html.BeginForm("Action2", "MyController", FormMethod.Post))
{
<input type="submit" value="Submit" id="submit" />
}
How to efficiently get the value (checked or not) of this checkbox, in the action Action2 in MyController ?
Browser don't send values from another form in requests.
The only way to do it is to handle onsubmit event with js/jquery, add value to form and submit it with js.

Controller doesn't redirect after form submit

I'm new to ASP.net MVC and I am struggling to make this work at the moment. I have a controller method called Add, it looks like this:
public ActionResult Add()
{
// check user is authenticated
if (Request.IsAuthenticated)
{
return View();
}
return RedirectToAction("Index", "Home");
}
//
// POST: /Home/Add
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Add(string title, string description, string priority, string color, FormCollection collection)
{
if (ModelState.IsValid)
{
// create instance of todo object
todo obj = new todo();
try
{
// gather fields
obj.priority = Convert.ToInt32(priority);
obj.color = Convert.ToInt32(color);
obj.title = title;
obj.description = description;
todosDataContext objLinq = new todosDataContext();
// get the users id, convert to string and store it
var userid = Membership.GetUser().ProviderUserKey;
obj.userid = userid.ToString();
// save
objLinq.todos.InsertOnSubmit(obj);
objLinq.SubmitChanges();
return RedirectToAction("Index", "Home");
}
catch
{
return View(obj);
}
}
return RedirectToAction("Index", "Home");
}
If data is sent via POST to the method, it should add the data to the database. That is working fine and everything is added correctly. However, the RedirectToAction is not firing, and the application gets stuck at /Home/Add, when it should redirect to /Home/Index. The view loads however, so it shows /Home/Index but the URL says /Home/Add.
Here is a copy of the partial view that contains the form:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<todo_moble_oauth.Models.todo>" %>
<% using (Html.BeginForm()) { %>
<%: Html.AntiForgeryToken() %>
<%: Html.ValidationSummary(true) %>
<fieldset>
<h3>Title:</h3>
<div class="editor-field">
<input type="text" name="title" />
</div>
<h3>Description:</h3>
<div class="editor-field">
<input type="text" name="description" />
</div>
<h3>Priority:</h3>
<div class="editor-field">
<select name="priority">
<option value="1">Low</option>
<option value="2">Medium</option>
<option value="3">High</option>
</select>
</div>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<h3>Color:</h3>
<input type="radio" name="color" id="radio-choice-1" value="0" checked="checked" />
<label for="radio-choice-1">None</label>
<input type="radio" name="color" id="radio-choice-2" value="1" />
<label for="radio-choice-2">Red</label>
<input type="radio" name="color" id="radio-choice-3" value="2" />
<label for="radio-choice-3">Blue</label>
<input type="radio" name="color" id="radio-choice-4" value="3" />
<label for="radio-choice-4">Yellow</label>
</fieldset>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
So data is being sent to the database and stored, however the redirect is broken.
Turns out it is an issue with jQuery mobile, this threads solution resolved the issue for me:
jQuery Mobile/MVC: Getting the browser URL to change with RedirectToAction

Submitting a form to MVC

My form code is not generating correct HTML. Here's my code.
Here's the form code:
#using (Html.BeginForm("SendEmail", "PropertyDetails", FormMethod.Post))
{
<fieldset>
<div class="left">
<label for="Name">Your Name</label>
<input type="text" required name="Name" />
<label for="Phone">Your Phone Number</label>
<input type="text" required name="Phone" />
<label for="Email">Your Email</label>
<input type="email" class="text" required name="Email" />
</div>
<div class="right">
<label for="Message">Your Message</label>
<textarea name="Message">
</textarea>
<input type="submit" name="submit" value="send" />
<div class="clear"></div>
</div>
<div class="clear"></div>
</fieldset>
}
Here's my Controller. I have a breakpoint on the first line of the SendMail message which isn't being hit:
public class PropertyDetailsController : Controller
{
[HttpPost]
public ActionResult SendEmail(EmailData email)
{
if (ModelState.IsValid) // BREAKPOINT ON THIS LINE ISN'T BEING HIT
{
etc.
Here's the class that should get populated with the form data and passed into the method (I'm not doing this myself. I assume it's happening automatically under the covers).
public class EmailData
{
private string _name;
private string _email;
private string _phone;
private string _message;
[Required]
[StringLength(50, MinimumLength = 1)]
public string Name
{
get { return _name; }
set { _name = value == null ? string.Empty : value.Trim(); }
}
[Required]
[RegularExpression(RegEx.Email, ErrorMessage = "Invalid e-mail address.")]
public string Email
{
get { return _email; }
set { _email = value == null ? string.Empty : value.Trim(); }
}
public string Phone
{
get { return _phone; }
set { _phone = value == null ? string.Empty : HtmlHelper.StripIllegalXmlChars(value.Trim()); }
}
[StringLength(500, MinimumLength = 1)]
public string Message
{
get { return _message; }
set { _message = value == null ? string.Empty : HtmlHelper.StripIllegalXmlChars(value.Trim()); }
}
}
Here's the HTML that's being generated:
<form action="" method="post">
<fieldset>
<div class="left">
<label for="Name">Your Name</label>
<input type="text" required name="Name" />
<label for="Phone">Your Phone Number</label>
<input type="text" required name="Phone" />
<label for="Email">Your Email</label>
<input type="email" class="text" required name="Email" />
</div>
<div class="right">
<label for="Message">Your Message</label>
<textarea name="Message">
</textarea>
<input type="submit" name="submit" value="send" />
<div class="clear"></div>
</div>
<div class="clear"></div>
</fieldset>
</form>
Any ideas why the action is empty?
Change your <form> declaration to this:
<% using (Html.BeginForm("SendEmail", "[Controller]")) { %>
<!-- Form data -->
<% } %>
Where [Controller] is the name of your Controller minus "Controller". In other words, if the controller name is HomeController, you would use "Home".
Try changing the form declaration within your view to this (using Razor syntax):
#using (this.Html.BeginForm("SendEmail", "[your controller name]", FormMethod.Post))
{
[form HTML]
}
The using statement will ensure that your form is closed correctly.
Also the HtmlHelper.BeginForm extension method is flexible enough that it generates the URI for the action based on the routes defined in your application's RouteCollection, such that if your routes change the form does not need to be updated; the change in URI is handled gracefully and automatically.
You need to add an action to your form
<form action="/SendEmail/" method="post">
But really this should be done using the MVC3 BeginForm helper.
You need to have your HTML rendered by a controller. So put your HTML in a View called "SendEmail" and write a controller action with an [HttpGet] attribute.
Call the Action "SendEmail" and in it just do return View().
Like this
[HttpGet]
public ActionResult SendEmail()
{
return View();
}
That will cause the BeginForm to render the action="" properly.
Then once that's working you are going to have a problem when you do post the data back because the input fields aren't bound to you model. You need to add #model yournamespace.EmailData to the very top of your View and then you need to change your inputs to bind to the model properties.
I've no idea how good this link is but it's the first one I found that looks like it might guide you through a similar process http://geekswithblogs.net/WinAZ/archive/2010/10/30/an-mvc-3-contact-form.aspx

How to get drop-down list value?

my first question here.. :)
Let's begin with the code...
my page is
<form id="form1" runat="server">
<% using (Ajax.BeginForm(null)){%>
<%=Html.DropDownList("DdlScelta",MVC.Models.SelectLists.ConventionIdsSelectList, "Select by this list")%>
<%=Ajax.ActionLink("Show the Data", "SetData", new AjaxOptions { UpdateTargetId = "msg" })%>
<span id="msg"></span>
</form>
and this is my controller method
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SetData(FormCollection form1)
{
//form1["DdlScelta"] etc
}
I've also tried with a better way like
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SetData(string DdlScelta)
{
//not important code
}
but NOTHING to do, as soon one of the 2 actionResult is catched, I have a null value..
Thank you to any who can help me :)
You have to submit the form
<input type="submit" value="Somevalue" />
and have the form like this
Ajax.BeginForm("actionName", "controllerName", ajaxOptions)
Something like this
<% using (Ajax.BeginForm("actionName", "controllerName", ajaxOptions))
{%>
//form stuff
<input type="submit" value="Somevalue" />
<% } %>

Resources