mvc3 passing button name to post - asp.net-mvc-3

The button name is not being passed to my action method.
Here is my view (simplified):
#using (Html.BeginForm("HandleSubmit", "Home", FormMethod.Post))
{
<input id="btnAddLineItem" type="submit" name="AddLineItem" value="AddLineItem" />
}
Here's the controller method:
[HttpPost, ActionName("HandleSubmit")]
public ActionResult HandleSubmit(int? id, string btnSubmit)
{
switch (btnSubmit)
{
case "AddLineItem":
break;
case "AddNewOrder":
break;
}
return View("OrderDetails");
}
The btnSubmit value is always null. What do I need to do differently?

The name is what gets bound to your method signature, not the id.
Use the following:
public ActionResult HandleSubmit(string AddLineItem, string AddNewOrder)
{
/* ... code ... */
if(!string.IsNullOrEmpty(AddLineItem)) {
}
else if(!string.IsNullOrEmpty(AddNewOrder)) {
}
/* ... code ... */
}
Remember the form post will send a multipart/form-data collection of name/value pairs to the server.

You are not sending the button ID in any name or value in way whatsoever.
I suggest you make a model that has the following two properties:
In the get method make an instance of the model:
public ActionResult HandleSubmit()
{
MyModel model = new MyModel();
return View(model);
}
In the post method use the property of the model to get your values.
[HttpPost, ActionName("HandleSubmit")]
public ActionResult HandleSubmit(MyModel model)
{
switch (model.Order)
{
case "AddLineItem":
break;
case "AddNewOrder":
break;
}
return View("OrderDetails");
}
Your view can be something like the following:
#model MvcApplication3.Controllers.MyModel
#using (Html.BeginForm("HandleSubmit", "Home", FormMethod.Post))
{
#Html.EditorFor(x => Model.Order)
<input id="btnAddLineItem" type="submit" name="AddLineItem" value="AddLineItem" />
}

Related

How to send data from view to controller in MVC3

Hello everyone I would like to ask how to send data from view to controller ? I would like to describe my question with my controller and view as you can see below
Here is the login action controller
[HttpPost]
public ActionResult Login(Panel model, string Username, string Password, string CaptchaValue, string InvisibleCaptchaValue)
{
bool cv = CaptchaController.IsValidCaptchaValue(CaptchaValue.ToUpper());
bool icv = InvisibleCaptchaValue == "";
if (!cv || !icv)
{
ModelState.AddModelError(string.Empty, "The Captcha Code you entered is invalid.");
}
if (ModelState.IsValid)
{
if (model.Username == Username && model.Password == Password)
{
FormsAuthentication.SetAuthCookie(model.Username, false);
return RedirectToAction("index", "Home");
}
else
{
ModelState.AddModelError("", "Check your name or password");
}
}
return View();
}
So when user login, redirect to Home/index view. At this point everything is okey.
Here is my index view:
[Authorize]
public ActionResult index()
{
return View();
}
My question is how can I hold user's password parameter and send from index view to different controller to use this parameter in controller method but how ? For example I would like to use password parameter at my index_test controller method in where clause but first of all I need to send this data from index.
public ActionResult index_test()
{
return View(db.contents.Where(x => x.test_parameter== password).ToList());
}
You have to add a parameter to your action method:
public ActionResult index_test(string password) { ...
In Your view you can either send data to the action via a standard link:
#Html.ActionLink("Click me", "index_test", "Controller",
new { password = "StringOrVariable")
Or by doing a form post:
#using(Html.BeginForm("index_test")) {
<input type="hidden" name="password" value="mypassword" />
add some fields
<input type="submit" value="Send" />
}
In your view post the form back to the controller, for example
<form action = "yourcontroller/youraction" method = "POST" enctype = "multiparrt/form-data">

Why is {System.Web.Mvc.SelectList} DropDownList SelectedValue

I have created a DropDownList, as described in my last question here
I have been trying to figure out how to get the selected value of the list. I used the answer that was provided but the only thing it returned was {System.Web.Mvc.SelectList}
I debugged it and sure enough the string that was in the "Value" column was {System.Web.Mvc.SelectList}
What am I doing wrong here? I have been miserably failing at MVC and am new at it.
Thank you for the help
Your Action in your controller should look like this:
[HttpPost]
public ActionResult Index(int DropOrgId)
{
System.Diagnostics.Debugger.Break();
return null;
}
The important thing to note is that "DropOrgId" is the same as the string name you passed into #Html.DropDownList("DropOrgID") in your view. This name will store the value of the input from the HTML input control, in this case the
The source will be:
<select id="DropOrgID" name="DropOrgID">...</select>
The id of the input control is how the MVC framework will match up the value of that control to the parameter of the action you are looking for.
Here is a sample app that shows it:
Class
public class Organization
{
public int OrganizationID { get; set; }
public string Name { get; set; }
}
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
var orgs = new List<Organization>();
foreach (var count in Enumerable.Range(1, 10))
{
var newOrg = new Organization();
newOrg.OrganizationID = count;
newOrg.Name = "Organization " + count.ToString();
orgs.Add(newOrg);
}
ViewBag.DropOrgID = new SelectList(orgs, "OrganizationID", "Name", 3);
return View();
}
[HttpPost]
public ActionResult Index(int DropOrgID)
{
//You can check that this DropOrgID contains the newly selected value.
System.Diagnostics.Debugger.Break();
return null;
}
}
Index View
<h2>Index</h2>
#using (Html.BeginForm())
{
#Html.DropDownList("DropOrgID")
<br />
<br />
<input type="submit" value="Save" />
}

ASP.NET MVC 3 (Razor) form submit not working

Using Fiddler I can see that the request is not even being made but I can't see why.
Here's the form:
#using (Html.BeginForm("Index", "FileSystemChannelIndex", FormMethod.Post, new {
channelId = #Model.ChannelId }))
{
#Html.HiddenFor(model => model.Id)
#Html.HiddenFor(model => model.ChannelId)
<div class="editor-label">
Select File Source
</div>
<div class="editor-field">
#Html.DropDownListFor(
model => model.SelectedFileSourceValue,
new SelectList(Model.AvailableFilesSources, "Id", "Name"),
new { id = "selectFileSource" })
</div>
<p>
<input class="t-button" type="submit" value="Save" />
</p>
}
The View originally came from:
public ViewResult Create(int channelId)
{
var channel = this.fullUOW.GetFileSystemChannelRepository().All.Where(c => c.Id == channelId);
var vm = new FileSystemChannelIndexViewModel(channelId, new FileSystemChannelIndex());
return View("Edit", vm);
}
I've tried adding the "name" attribute to the but that didn't make any difference.
Any ideas?
EDIT: More info for Jim et al...
Domain:
public class FileSystemChannel
{
public int Id {get; set; }
public ICollection<FileSystemChannelIndex> ChannelIndexes { get; set; }
}
public class FileSystemChannelIndex
{
public int Id { get; set; }
public FileSystemChannel ParentChannel { get; set; }
}
Due to a 0...* association, in the UI we have to create a FileSystemChannel first then add a FileSystemChannelIndex to it. So that's why I pass in the channelId to the FileSystemChannelIndex Create View. When submitting the new FileSystemChannelIndex the following action should be called:
[HttpPost]
public ActionResult Index(int channelId, FileSystemChannelIndexViewModel vm)
{
//TODO: get the Channel, add the Index, save to db
return View("Index");
}
So thanks to Mark's comment it's due to a Select failing client side validation. Using IE dev tools to inspect the element:
<select name="SelectedFileSourceValue" class="input-validation-error" id="selectFileSource" data-val-required="The SelectedFileSourceValue field is required." data-val-number="The field SelectedFileSourceValue must be a number." data-val="true">
empo,
further to my comment above:
empo - can you post both public ActionResult Create(////) methods (i.e. HttpPost and HttpGet) into the question as this could highlight if the issue is related to ambiguous method signatures, which i suspect could well be the case as you are posting back the same signature as the HttpGet actionresult
try adding the appropriate HttpPost actionresult along the lines of:
[HttpPost]
public ActionResult Create(FileSystemChannelIndex domainModel)
{
if (!ModelState.IsValid)
{
return View(PopulateEditViewModel(domainModel));
}
_serviceTasks.Insert(domainModel);
_serviceTasks.SaveChanges();
return this.RedirectToAction("Edit", new {id = domainModel.ChannelId});
}
your original HttpGet (which feels 'wierd' to me):
[HttpGet]
public ViewResult Create(int channelId) {
var channel = this.fullUOW.GetFileSystemChannelRepository().All
.Where(c => c.Id == channelId);
var vm = new FileSystemChannelIndexViewModel(channelId,
new FileSystemChannelIndex());
return View("Edit", vm);
}
and inside your Edit actionresult, you'd grab the entity based on the passed in id. might work, might not. not sure without a fuller picture of your domain and logic.
obviously, your own plumbing will vary, but this should give an idea of what should be expected.
How can you have Model.Id when you are creating something? Maybe Model.Id is null and because you cannot post

Sending data from hardcoded dropdwonlist to controller

Migrating from textboxe to dropdownlist – Need to send value from a hard-coded dropdownlist to controller
The code below is used in the controller
var list = new SelectList(new[]
{
new{ID="1",Name="20012"},
new{ID="2",Name="20011"},
new{ID="3",Name="20010"},
new {ID="4",Name="2009"},
new{ID="5",Name="2008"},
new{ID="6",Name="2007"},
new{ID="7",Name="2006"},
new{ID="8",Name="2005"},
new{ID="9",Name="2004"},
new{ID="3",Name="2003"},
new{ID="3",Name="2002"},
new{ID="3",Name="2001"},
new{ID="3",Name="2000"},
},
"ID", "Name", 1);
ViewData["list"] = listYear;
The code below is used in the view
#using (Html.BeginForm()){
<p>
Title: #Html.TextBox("SearchString")
#Html.DropDownList("list",ViewData["list"] as SelectList)
Genre: #Html.DropDownList("Towns", "All")
<input type="submit" value="Filter" /></p>
}
Below is the code which was used for the textbox
if (!String.IsNullOrEmpty(year))
{
car = Cars.Where(s => s.Year.Contains(year));
}
Looks like you are trying to select a value from a selectlist and send that value to the controller. First off, I'd suggest you use a ViewModel instead of magic strings. You should modify your View to accept the new ViewModel and then post the model to your action. It's easy, cleaner and more maintainable.
Here is what your model would look like
public class VehicleYearsViewModel {
public SelectList VehicleYears { get; set; }
public int SelectedYear { get; set; }
public VehicleYearsViewModel() {
VehicleYears = new SelectList(new[]
{
new{ID="1",Name="2012"},
new{ID="2",Name="2011"},
new{ID="3",Name="2010"},
new{ID="4",Name="2009"},
new{ID="5",Name="2008"},
new{ID="6",Name="2007"},
new{ID="7",Name="2006"},
new{ID="8",Name="2005"},
new{ID="9",Name="2004"},
new{ID="3",Name="2003"},
new{ID="3",Name="2002"},
new{ID="3",Name="2001"},
new{ID="3",Name="2000"}
}
}
}
Your View then would look like so:
#YourAppName.Models.VehicleYearsViewModel
#using (Html.BeginForm()){
#Html.ValidationSummary(true)
#Html.DropDownListFor(model => model.SelectedYear, Model.VehicleYears, "ID", "Name", 1))
<input type="submit" value="OK" />
}
Your controller action would accept the model and can make use of the selected value as an int datatype.
I'm just guessing since your controller action isn't posted but this is pretty much what it would look like:
public class HomeController : Controller {
public ActionResult Index() {
var model = new VehicleYearsViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(VehicleYearsViewModel model) {
if(ModelState.IsValid) {
// you can get selected year like so
int selectedYear = model.SelectedYear;
// ... your code here to do whatever with selectedYear
}
return View(model);
}
}
Hope this helps

Strange Model Binder behavior with fractional number

I am confused by strange model binder behavior:
- when I use RedirectToAction with parameters which includes fractional number (because in Russian, we use "," instead of ".", e.x. 1,5; 2,5) in View it Binds that with dots, "4,5 => 4.5", and after post form I have ModelState error and values equal to 0. When inputting integer numbers however, all works as expected.
How i can fix it?
Models:
public class TestA
{
public double FirstNumberA { get; set; }
public double SecondNumberA { get; set; }
}
public class TestB
{
public double FirstNumberB { get; set; }
public double SecondNumberB { get; set; }
}
controller:
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(TestA model)
{
return RedirectToAction("About", new { firstNumberB = model.FirstNumberA, secondNumberB = model.SecondNumberA });
}
public ActionResult About(double firstNumberB, double secondNumberB)
{
return View(new TestB() { FirstNumberB = firstNumberB, SecondNumberB = secondNumberB });
}
[HttpPost]
public ActionResult About(TestB model)
{
return View();
}
views:
/* index */
#model TestA
#using (Html.BeginForm())
{
#Html.TextBoxFor(x => x.FirstNumberA)
#Html.TextBoxFor(x => x.SecondNumberA)
<input type="submit" name="submit" value="submit" />
}
/* about */
#model TestB
#using (Html.BeginForm())
{
#Html.TextBoxFor(x => x.FirstNumberB)
#Html.TextBoxFor(x => x.SecondNumberB)
<input type="submit" name="submit" value="submit" />
}
Upd
When remove TextBoxFor(x => x.SecondNumberB) in About.cshtml and post form - FirstNumberB will cause an ModelState error, when SecondNumberB binds as should.
Upd2
I think, that here is another problem, that describe Phil Haack in his post - asp.mvc first look for values at the query string and get it. And in my case in query string I have ?firstNumber=1.5 and it binds to TextBox "as-is", without culture rules. And after post we get FormatException error. How can I fix it - bind decimal values to textboxes with correct culture decimal-separators? I can't use any JavaScript. I think about workaround with TempData before ReturnToRedirect, but in this case user can't reload the page.
Could be a culture problem. Make sure you set the correct culture in your web.config <globalization> element.

Resources