mvc3: html.beginform search returning empty querystring - asp.net-mvc-3

In an MVC3 app, i have the following View:
#using (Html.BeginForm("Index", "Search", new {query = #Request.QueryString["query"]}, FormMethod.Post))
{
<input type="search" name="query" id="query" value="" />
}
When i type in the url "/Search?query=test", Request.Querystring in my Index action reads out the search-value perfectly well (i have my routes set to ignore the Action in the url). When i type it in the seachbox, it hits the right action and controller (so the routing seems fine) but the querystring remains empty. What am i doing wrong?

The Problem is that you are look in the Request.QueryString collection. But you are doing a POST so the query value is in the Request.Form Collection. But i think you want your TextBox filled with the data so can do it like in my sample.
Sample
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<input type="search" name="query" id="query" value="#Request.Form["query"]" />
}
But this is not the real MVC approach. You should create a ViewModel for that.
Model
namespace MyNameSpace.Models
{
public class SearchViewModel
{
public string Query { get; set; }
}
}
View
#model MyNameSpace.Models.SearchViewModel
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.TextBoxFor(x => x.Query)
<input type="submit" />
}
Controller
public ActionResult Index()
{
return View(new SearchViewModel());
}
[HttpPost]
public ActionResult Index(SearchViewModel model)
{
// do your search
return View(model);
}

Related

How to use hidden field values from view to controller in asp.net mvc 3

I have to pass hidden filed values to controller action. So I have tried in the following way, but I am getting null values.
I have tried both methods i.e formcollection and viewmodel concept
Controller
public ActionResult MapIcon()
{
Hidden hd = new Hidden();
return View(hd);
}
[HttpPost]
public ActionResult MapIcon(Hidden hidden)
{
var value=hidden.hiddevalue;//null
FormCollection col = new FormCollection();
var value = col["hidden1"];
// string value = mycontroler.ControlName;
return View(hidden);
}
View
#model SVGImageUpload.Models.Hidden
Razor view:#using (Html.BeginForm(new { id = "postform" }))
{
<input type="hidden" id="" value="7" name="hidden1" />
<input type="hidden" id="" value="7" name="hidden2"/>
<input type="submit" value="Match"/>
}
Viewmodel
public class Hidden
{
public string hiddevalue { get; set; }
}
Try this, In Razor view:
#using (Html.BeginForm(new { id = "postform" }))
{
#Html.HiddenFor(m=>m.hiddevalue)
<input type="submit" value="Match"/>
}
It seems to me like you are trying to get multiple values into the POST controller. In that case, and by your exam, the value from the hidden input is enough. In that case, you can setup your controller as so:
public ActionResult Index()
{
Hidden hd = new Hidden();
return View(hd);
}
[HttpPost]
public ActionResult Index(IEnumerable<string> hiddens)
{
foreach (var item in hiddens)
{
//do whatter with item
}
return View(new Hidden());
}
and as for your view, simple change it in order to bind to the same name "hiddens" as so:
#using (Html.BeginForm(new { id = "postform" }))
{
<input type="hidden" value="7" name="hiddens" />
<input type="hidden" value="2" name="hiddens" />
<input type="submit" value="Match" />
}
Hope this serves what you are looking forward to.
if your hidden value is static.Than try this
View
#using (Html.BeginForm(new { id = "postform" }))
{
#Html.HiddenFor(m=>m.hiddevalue)
<input type="hidden" id="" value="7" name="hidden1" />
<input type="hidden" id="" value="7" name="hidden2"/>
<input type="submit" value="Match"/>
}
Controller
[HttpPost]
public ActionResult MapIcon(Hidden hidden, string hidden1, string hidden2)
{
var hiddenvalue = hidden.hiddevalue;
var hiddenvalue1 = hidden1;
var hiddenvalue2 = hidden2;
var value=hidden.hiddevalue;//null
FormCollection col = new FormCollection();
var value = col["hidden1"];
// string value = mycontroler.ControlName;
return View(hidden);
}
Script
$(document).ready(function () {
$('#hiddevalue').val("Jaimin");
});

Submitting a form view to controller

I have a form in my form view defined as
using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
This form contins a number of input of type button and button
<input type="submit" value="val1" name="action">
<input type="submit" value="val2" name="action">
<input type="submit" value="val3" name="action" />
<button class="button" type="submit" name="action" value="val4">Val4</button>
I have 2 controllers for this view
Public ActionResult form{
}
and
[HttpPost]
public ActionResult form(String button)
{
switch (actionType)
{
case "val1":
return RedirectToAction("AnotherView");
case "val2":
return RedirectToAction("AnotherView2");
default:
return RedirectToAction("AnotherView3");
}
}
But whichever button I click, I am being redirected to the Home defined in the form
using (Html.BeginForm("Index", "Home",
My question is how can I fix this and how can I be certain that this post method is bound to my view as i just typed it in?
using (Html.BeginForm("action_name", "controllername", FormMethod.GET, new { enctype = "multipart/form-data" }))
use input type select:
<select name="action">
<option value="val1" >val1</option>
<option value="val2" >val2</option>
<option value="val3" >val3</option></select>
and method at controller
public ActionResult action_name(String action){
switch (action)
{
case "val1":
return RedirectToAction("AnotherView");
case "val2":
return RedirectToAction("AnotherView2");
default:
return RedirectToAction("AnotherView3");
}
}
If you specify a form field named action MVC will interpret this as the action on the controller to route to. Thus clicking val1 will ultimately execute the method:
public ActionResult val1()
{
}
If this method does not exist, your error handling will take over.
Solution: Don't use action as a name of a form field.

What are the parameters need to be put inside a Html.BeginForm()

I have the following view:
<h2>enter the student name to search</h2>
#using (Html.BeginForm())
{
<label>Search:</label>
<input type="text" name="searchString" />
<input type="submit" name="submit" />
}
and the view corresponds to following controller
namespace Searching.Controllers
{
public class SearchController : Controller
//somecode
[HttpPost]
public ActionResult SearchIndex(FormCollection formCollection)
{
string searchString=formCollection["searchString"];
var search = from m in db.Searches select m;
if (!String.IsNullOrEmpty(searchString))
{
search = search.Where(s => s.Name.Contains(searchString));
}
return View(search);
}
}
}
the controller name is SearchController.cs and the name of the method to pass form is SearchIndex.
What should be the parameter inside the Html.BeginForm().I am a begginer.
Html.BeginForm("SearchIndex", "Search", .....)
You should read this: http://msdn.microsoft.com/en-us/library/dd410596.aspx

Can't add file upload capability to generated MVC3 page

I'm new to MCV and I'm learning MVC3. I created a model and a controller and view was generated for me. The generated code makes perfect sense to me. I wanted to modify the generated view and controller so that I could upload a file when I "create" a new record. There is a lot of good information out there about how to do this. Specifically I tried this: http://haacked.com/archive/2010/07/16/uploading-files-with-aspnetmvc.aspx
The problem is that even when I select a file (not large) and submit, there are no files in the request. That is, Request.Files.Count is 0.
If I create the controller and and view from scratch, in the same project (no model), the example works just fine. I just can't add that functionality to the generated page. Basically, I'm trying get the Create action to also send the file. For example, create a new product entry and send the picture with it.
Example Create view:
#model Product.Models.Find
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm("Create", "Find", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Find</legend>
<input type="file" id="file" />
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Example Controller:
[HttpPost]
public ActionResult Create(Product product)
{
if (ModelState.IsValid)
{
if (Request.Files.Count > 0 && Request.Files[0] != null)
{
//Not getting here
}
db.Products.Add(product);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(find);
}
This will create the record just fine but there are not files associated with the Request.
I've also tried a controller action like this:
[HttpPost]
public ActionResult Create(HttpPostedFileBase file)
{
if (file.ContentLength > 0)
{
//Not getting here
}
return RedirectToAction("Index");
}
I'm wondering if maybe you can't post a file at the same time as posting form fields? If that is the case, what are some patterns for creating a new record and associating a picture (or other file) with it?
Thanks
Create a ViewModel which has properties to handle your image and Product deatils
public class ProductViewModel
{
public string ImageURL { set;get;}
public string Title { set;get;}
public string Description { set;get;}
}
And in your HTTPGET Action method, return this ViewModel object to your strongly typed view
public ActionResult Create()
{
ProductViewModel objVM = new ProductViewModel();
return View(objVM);
}
And in your View
#model ProductViewModel
<h2>Add Product</h2>
#using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.TextBoxFor(m => m.Title) <br/>
#Html.TextBoxFor(m => m.Description ) <br/>
<input type="file" name="file" />
<input type="submit" value="Upload" />
#Html.HiddenFor(m => m.ImageURL )
}
Now in your HttpPost action method, accept this ViewModel and File
[HttpPost]
public ActionResult Create(HttpPostedFileBase file, ProductViewModel objVM)
{
if(file==null)
{
return View("Create",objVM);
}
else
{
//You can check ModeState.IsValid if you have to check any model validations and do further processing with the data here.
//Now you have everything here in your parameters, you can access those and save
}
}
You will have to create a ViewModel for Product (maybe ProductViewModel) and add a HttpPostedFileBase field with the same name as the field of the form and use that instead of the Product in the action of the controller.
A ViewModel is nothing but a model used for specific views. Most of the times, with extra data to generate the view or to decompose and form the model on the controller action.
public ProductViewModel
{
public string Cod { get; set; }
// All needed fields goes here
public HttpPostedFileBase File{ get; set; }
/// Empty constructor and so on ...
}

Correct way to load a partial view into a view

I am wanting to create a view that allows me to add phone numbers for a person.
public class PersonModel
{
public string Name { get; set; }
}
public class PhoneModel
{
public string PhoneNumber { get; set; }
}
public class PersonDetailViewModel
{
public PersonModel PersonDetails { get; set; }
public IList<PhoneModel> PhoneNumbers { get; set; }
}
I am binding my main view to the viewmodel like
#model DynamicPhoneNumber.Models.PersonDetailViewModel
#{
ViewBag.Title = "Add";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Details</legend>Name #Html.TextBoxFor(a => a.PersonDetails.Name)
<input type="button" id="btnAdd" value="Press Me" />
<div id="mydiv">
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
My Partial view looks like
#model DynamicPhoneNumber.Models.PhoneModel
<p>
#Html.TextBoxFor(t => t.PhoneNumber)
</p>
Im using jquery to dynamically add the partial view.
On HttpPost I place a breakpoint and I can see the value from the PersonDetails.Name however none of the values from my loaded partialview are been bound to the PhoneModel.
What do I need to do to be able to return the data from the partial views into my viewmodel?
here is a good blog post that may help to resolve your problem
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

Resources