How can I send to action of controller different values for same field? Which input parameters should I define in action? And how can I show url with different values of identical fields in querystring? I want to get such url: site.com/directory?metro=2&metro=3
Thanks!
Here's an example of how this would be done in the case of checkboxes. Note that you wouldn't see the same querystring parameter repeated in the case of a GET request. Instead you would see "?metros=1,3" if checkboxes 1 and 3 were checked.
HTML
<form action="http://site.com/directory" method="get">
<input type='checkbox' name='metros' value='1' />
<input type='checkbox' name='metros' value='2' />
<input type='checkbox' name='metros' value='3' />
</form>
Controller
public class DirectoryController : Controller {
public ActionResult Index(IEnumerable<int> metros) {
foreach (var metro in metros) {
// do something
}
return View();
}
}
Related
I have an ASP.NET MVC 3 application. I need to implement a file uploader action within it. For some reason, when I post my form, the Request.Files collection is empty. I have been able to confirm this by setting a breakpoint. So I know that I'm reaching the action. However, I can't figure out why the Request.Files collection is empty. Here are my relevant HTML, AreaRegistration, and Controller snippets.
index.html
<form action="/files/upload/uniqueID" method="post" enctype="multipart/form-data">
<div>Please choose a file to upload.</div>
<div><input id="fileUpload" type="file" /></div>
<div><input type="submit" value="upload" /></div>
</form>
MyAreaRegistration.cs
context.MapRoute(
"FileUpload",
"files/upload",
new { action = "UploadFile", controller = "Uploader" }
);
UploaderController.cs
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UploadFile(int uniqueID)
{
foreach (string file in Request.Files)
{
// I never get here :(
}
return View();
}
I have not made any changes to the default web.config file. Is there some setting I need to add? I can't figure out why the Request.Files collection would be empty. Can someone please help me?
Thank you so much!
You should use HttpPostedFileBase for you controller and do something like that
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/"), fileName);
file.SaveAs(path);
}
return RedirectToAction("Index");
}
And for the view
<form action="" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<input type="submit" />
</form>
Check Phil Haack blog here for this problem: Uploading a File (Or Files) With ASP.NET MVC
I believe the problem is with your action attribute in your <form /> tag:
action="/files/upload/uniqueID"
I think upon post it is trying to pass the string "uniqueID" to your Action method. When you hit your breakpoint, what is the value of your uniqueID parameter set to when you reach the action method UploadFile()?
Use the HtmlHelper.BeginForm() method to use Razor to construct the form.
I am currently having an issue with multiple action buttons being in the same form.
The first button would perform verification while the second button would save profile. The third would simple redirect the user out of the page, but they are still required to go through controller some tracking purposes. Last button is delete. Because they are placed together and I do need ModelBinding passed through POST, it's impossible to separate them into multiple forms.
Currently, in order to differentiate which action is being clicked, I have a hidden input in my form and onclick, javascript would update the hidden input so that it will be passed back to the controller.
The reason I did this was because for some weird reasons, FormCollection doesn't want to hold my submit values. I tried accessing buttons in controller via
formCollection["verify"]
But it turns out to be null. Both id and name of the input submit is set to verify.
I also tried a lot of other suggestions like this and this but to no avail. Is there a better approach to my problem without using javascript to alter hidden inputs?
The best approach is to have separate actions handling the different button calls as explained in this article.
If you want to have one ugly action doing all the stuff then you could give your submit buttons names:
#using (Html.BeginForm())
{
... input fields for the model
<button type="submit" name="btn" value="verify">Verify data</button>
<button type="submit" name="btn" value="save">Save data</button>
<button type="submit" name="btn" value="redirect">Redirect</button>
}
You don't need any hidden fields or javascript. And then in your controller action you would check for the value of the btn parameter (which obviously will be part of you view model):
[HttpPost]
public ActionResult Foo(MyViewsModel model)
{
if (model.Btn == "verify")
{
// the Verify button was clicked
}
else if (model.Btn == "save")
{
// the Save button was clicked
}
else if (model.Btn == "redirect")
{
// the Redirect button was clicked
}
else
{
// ??? throw
}
...
}
Of course if you follow my advice and separate your actions (as outlined in the article):
#using (Html.BeginForm("Action", "Home"))
{
... input fields for the model
<input type="submit" name="verify" value="Verify data" />
<input type="submit" name="save" value="Save data" />
<input type="submit" name="redirect" value="Redirect" />
}
and then:
[HttpParamAction]
[HttpPost]
public ActionResult Verify(MyViewModel model)
{
...
}
[HttpParamAction]
[HttpPost]
public ActionResult Save(MyViewModel model)
{
...
}
[HttpParamAction]
[HttpPost]
public ActionResult Redirect(MyViewModel model)
{
...
}
which is a far cleaner code which doesn't violate the Single Responsibility Principle.
I do something slightly different;
<input type="submit" name="submit" value="Save Draft" />
<input type="submit" name="submit" value="Publish" />
Then you can get at the values using;
FormCollection["submit"]
Thanks,
Matt
<input type="submit" name="nameONE" />
<input type="submit" name="nameTWO" />
[HttpPost, ActionName("OrginalActionName")]
[FormValueRequired("nameONE")]
public ActionResult WhateverYouWantONE(type name)
{
code...
}
[HttpPost, ActionName("OrginalActionName")]
[FormValueRequired("nameTWO")]
public ActionResult WhateverYouWantTWO(type name)
{
code...
}
I have an Index page in an MVC3 C#.Net web app. The Index View of my Proposal Model contains an input submit button:
<input type="submit" name="Create" id="Create" value="Create New Proposal" style="width: 200px" />
When the button is clicked, I want to invoke the Create View on the Proposal Model. However, I can't get any method in the Proposal Controller to fire when clicking on the "create New" input button. Can I call the Index Post method? The Proposal Create get method? Any ideas?
You need your submit button inside a form and an overloaded ActionResult in your controller which uses the HttpPost attribute.
Something like...
Controller
public ActionResult Index()
{
return View(new MyViewModel());
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
// do stuff with model
}
View
#using(Html.BeginForm())
{
<input type="submit" value="Go" />
}
That would render a form and post it to the Index action result in your controller.
Try using an HTML Helper like #Html.BeginForm. See here for clues: http://msdn.microsoft.com/en-us/library/system.web.mvc.html.formextensions.beginform.aspx
In your case try this:
#using (Html.BeginForm("Create", "Proposal")){
......
<input type="submit" value="Submit" />
}
You have to write a post method and then use this for displaying your View
#using (Html.BeginForm("YourAction", "Controller", "FormMethod.Post"))
{
//your View code display
}
How does one obtain the form data after submitting it?
<form target="_self" runat="server">
<p>
<select id="BLAHBLAH2">
<option>2010</option>
<option>2011</option>
<option>2012</option>
<option>2013</option>
</select>
<input type="submit" runat="server" value="Change Year" />
</p>
</form>
This hits the controller's Index method. But, there's nothing in Request.Form. Why?
Second, can I use
<input type="button" instead of type=submit? That is, without introducing ajax via onclick.
Finally, how do I submit to a different method in the controller, e.g. Create?
Try removing those runat server tags. They should not be used in ASP.NET MVC. Also your select doesn't have a name. If an input element doesn't have a name it won't submit anything. Also your option tags must have value attributes which indicates what value will be sent to the server if this options is selected:
<form action="/Home/Create" method="post">
<p>
<select id="BLAHBLAH2" name="BLAHBLAH2">
<option value="2010">2010</option>
<option value="2011">2011</option>
<option value="2012">2012</option>
<option value="2013">2013</option>
</select>
<input type="submit" value="Change Year" />
</p>
</form>
But the correct way to generate forms in ASP.NET MVC is to use HTML helpers. Depending on the view engine you are using the syntax might be different. Here's an example with the Razor view engine:
#model MyViewModel
#using (Html.BeginForm("Create", "Home"))
{
<p>
#Html.DropDownListFor(x => x.SelectedYear, Model.Years)
<input type="submit" value="Change Year" />
</p>
}
Here you have a strongly typed view to some given view model:
public class MyViewModel
{
public string SelectedYear { get; set; }
public IEnumerable<SelectListItem> Years
{
get
{
return Enumerable
.Range(2010, 4)
.Select(x => new SelectListItem
{
Value = x.ToString(),
Text = x.ToString()
});
}
}
}
which is populated by some controller action that will render this view:
public class HomeController: Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Create(MyViewModel model)
{
... model.SelectedYear will contain the selected year
}
}
None of your <option> tags have a value:
...
<option value="2010">2010</option>
...
As noted by David, runat="server" is most definitely a WebForms thing, so you can 86 that.
If you want to submit to a different method on your controller you just need to specify the URL for that method.
Easy way using Html.BeginForm:
#using (Html.BeginForm("AnotherAction", "ControllerName")) {
<!-- Your magic form here -->
}
Using Url.Action
<form action="#Url.Action("AnotherAction")" method="POST">
<!-- Your magic form here -->
</form>
You can also use
In Controller
int Value = Convert.ToInt32(Request["BLAHBLAH2"]); //To retrieve this int value
In .cshtml file use
<select id="IDxxx" name="BLAHBLAH2">
//Request[""] will retrieve the VALUE for the html object ,whose "name" you request.
How to validate a simple form (one input field) and show errors without providing a command object ? My simple form is:
<form id="verify" action="check.html">
<input name="code"/>
<form:errors path="code" />
<input type="submit" value="ok" />
</form>
Controller handler method below. I need to generate error message and show in place of form:errors
#RequestMapping("/check.html")
public String check(#RequestParam(value="code") String code) {
if(!isGood(code)) {
// How to bind some error messages for `code` ?
return "fail"; // fail page
}
return "ok";
}
In short words, <form:errors> doesn't work without <form:form> and other #ModelAttribute-related functionality. If you want the simpliest solution, you can export error message as a normal model attribute instead of using <form:errors>:
#RequestMapping("/check.html")
public String check(#RequestParam(value="code") String code, ModelMap model) {
if(!isGood(code)) {
model.put("codeError", "...")
return "fail"; // fail page
}
return "ok";
}
<form id="verify" action="check.html">
<input name="code"/>
<c:out value = "${codeError}" />
<input type="submit" value="ok" />
</form>