I have dropdownlist and want to pass value in Controller. View
#using (Html.BeginForm())
{
#Html.DropDownList("dropOrg", ViewBag.dropOrg as SelectList)
<input type="submit" value="save" />
}
Controller
foreach (int tmp in org)
{
string s = tmp + " - " + orgNames[tmp];
SelectListItem item1 = new SelectListItem() { Text = s, Value = tmp.ToString() };
items.Add(item1);
}
ViewBag.dropOrg = items;
What should i do?
It will be better if you create ViewModel for your View:
public class SampleViewModel
{
public string DropDownListValue { get; set; }
}
then in your controller's get method:
public ActionResult SomeAction()
{
var org = GetOrg(); //your org
var orgNames = GetOrgNames(); //your orgNames
// . . .
ViewBag.DropDownListValue = new SelectList(org.Select(s =>
new SampleViewModel
{
DropDownListValue = $"{s} - {orgNames[s]}"
}, "DropDownListValue", "DropDownListValue");
return View(new SampleViewModel())
}
your SomeAction View:
#model YourAppNamespace.SampleViewModel
<h1>Hello Stranger</h1>
#using (Html.BeginForm())
{
#Html.DropDownList("DropDownListValue")
<input type="submit" value="Submit"/>
}
Note that:
The DropDownList helper used to create an HTML select list
requires a IEnumerable<SelectListItem>, either explicitly or
implicitly. That is, you can pass the IEnumerable<SelectListItem>
explicitly to the DropDownList helper or you can add the
IEnumerable<SelectListItem> to the ViewBag using the same name for
the SelectListItem as the model property.
We have used here implicit passing, that is we have used same name for SelectListItem and ViewBag (which is DropDownListValue).
Then when you hit Submit, you need HttpPost method for SomeAction:
[HttpPost]
public ActionResult SomeAction(SampleViewModel model)
{
var org = GetOrg(); //your org
var orgNames = GetOrgNames(); //your orgNames
//. . . Validation etc..
ViewBag.DropDownListValue = new SelectList(org.Select(s =>
new SampleViewModel
{
DropDownListValue = $"{s} - {orgNames[s]}"
}, "DropDownListValue", "DropDownListValue", model.DropDownListValue);
var doSomething = model.DropDownListValue; //Your selected value from DropDownList
return View(model)
}
References: DotNetFiddle Example,
Using the DropDownList Helper with ASP.NET MVC
Related
I have an ASP.NET MVC project with entities based on EF6 (model first). So my entities are all auto-generated for me. I have an entity, Site and I just want the user to select a Site before proceeding. I have tried a couple of ways, all of them work, but they seem very messy and unnecessary.
I was curious about the cleanest way to create a DropdownList of Sites, then get the selected site when the form is submitted (by Id or whatever other mechanism is better).
Currently I have:
The index where the user is asked to select a site:
public ActionResult Index()
{
ViewBag.Sites = new SelectList(db.Sites.ToList(), "Id", "Name");
return View();
}
The view:
#using (Html.BeginForm("SetSite", "Home"))
{
#Html.Label("sites", "Site:");
#Html.DropDownList("Sites", null, new { #class = "selectpicker" });
<div style="width:100%;height:25px"></div>
<button class="btn btn-default" style="width:100%">Go</button>
}
And the SetSite action, where the form is submitted
[HttpPost]
public ActionResult SetSite()
{
if (Request.Form["Sites"] != null)
{
Session["Site"] = db.Sites.Find(Request.Form["Sites"]);
return RedirectToAction("Home");
}
else
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
}
A few problems arise from this method. First, I really wanted to take advantage of the #model functionality in razor and point it towards my Site class, but since it's auto-generated, I don't want to go poking around and adding a whole bunch of view properties. (beggars can't be choosers?)
Second, the Request.Form['Sites'] returns a string, and converting it to and int is ugly as hell.
As I mentioned, I'd like to use the #model functionality with Html.DropDownListFor. Is that possible when working with a list of Sites from the DB?
How can I get this done cleanly?
Solution 1:-
Controller:-
private List<Country> GetCountries()
{
var list = new Entity.Result<List<Entity.Country>>();
list = _context.Countries.Select(tc => new Entity.Country
{
Id = tc.Id,
Name = tc.Name,
IsdCode = tc.Code,
}).ToList();
return list.Data.Select(x => new Country
{
id = x.Id,
Name = x.Name,
}).ToList();
}
HttpGet Method:-
public ActionResult Add(int id)
{
try
{
}
catch (Exception ex)
{
}
finally
{
ViewBag.countryList = GetCountries();
}
return View()
}
View Method:-
#Html.DropDownListFor(x => x.countryId, new SelectList(ViewBag.countryList, "id", "Name"), KahandasDhanji.Common.Localization.Application.Resources.ddlCountry,
new { #id = "ddlCountry", #rows = 1 })
In Http Post Form Submitimg u handle that model value in HTTPPOST Method.
Solution 2:-
FormCollection class we can capture the form's values within the controller.
[HttpPost]
public ActionResult Add(FormCollection form)
{
string strDDLValue = form["Sites"].ToString();
return View(MV);
}
Hope Its Work !!!
You can use a ViewModel to avoid converting the string value from Request.Form. Below is how your ViewModel class should look like
public class MyViewModel
{
public MyViewModel()
{
this.DropdownItems = new List<SelectListItem>();
}
public int SelectedSiteId { get; set; }
public List<SelectListItem> DropdownItems { get; set; }
}
Change the get action method in your controller as below
public ActionResult Index()
{
List<Site> sites = db.Sites.ToList();
MyViewModel model = new MyViewModel();
foreach(var site in sites)
{
model.DropdownItems.Add(new SelectListItem() { Text = site.Name, Value = site.ID.ToString() });
}
return View(model);
}
Add #model MyViewModel at the first line in your view code and use Html.DropDownListFor method to generate the dropdownlist
#model MyViewModel
#using (Html.BeginForm("SetSite", "Home"))
{
#Html.Label("SelectedSiteId", "Site:");
#Html.DropDownListFor(m => m.SelectedSiteId, Model.DropdownItems, new { #class = "selectpicker" })
<div style="width:100%;height:25px"></div>
<button class="btn btn-default" style="width:100%">Go</button>
}
The post action method in your controller should look like below. model.SelectedSiteId will be the selected value of the dropdownlist and the type is int so you won't have to do any conversion such as Convert.ToInt32(Request.Form['Sites']).
[HttpPost]
public ActionResult SetSite(MyViewModel model)
{
Session["Site"] = model.SelectedSiteId;
return RedirectToAction("Home");
}
I am starting in asp.net Mvc and making test, i am doing a simple chat using PubNub api and i want finish it using only razor code only and one page only.
Model Chat.cs:
namespace SimpleChat.Models
{
public class Chat
{
public string NuevoMensaje { get; set; }
public string TextArea { get; set; }
}
}
View:
#model SimpleChat.Models.Chat
#using (Html.BeginForm("Index","Chat",FormMethod.Post))
{
#Html.LabelFor(model => model.NuevoMensaje, "Nuevo Mensaje")
#Html.TextBoxFor(model => model.NuevoMensaje)
<input type="submit" class="btn-default" value="Enviar" />
#Html.TextAreaFor(model => model.TextArea)
}
Controller:
static string variante = "";
public ActionResult Index()
{
pubnub.Subscribe<string>("Chat", subCallback, connecCallBack, errorCallback);
//Chat nuevochat = new Chat();
return View();
}
[HttpPost]
public ActionResult Index(Chat chat)
{
pubnub.Publish<string>("Chat", chat.NuevoMensaje, userCallback, puberror);
chat.NuevoMensaje = "";
chat.TextArea =variante;
return View("Index",chat);
}
private void subCallback(string obj)
{
string[] retorno = obj.Split(',','"');
variante += "Richard dice:" + retorno[0] + "\n";
}
When i press submit don't get the new data, why?
If you want to render the updated value of TextArea property of your view model, You should clear the model state dictionary.
Model state dictionary has the initial values of your form inputs. So when razor (re)render the same view, It gives priority to the content in model state dictionary than the view model object you passed to the view.
You can use the ModelState.Clear() method to clear the model state dictionary values before returning to the view.
chat.TextArea = variante;
ModelState.Clear();
return View("Index",chat);
Assuming your variante variable has the updated text.
I have a strongly typed view and I'm trying to pass the input from a textbox upon a button click to an action using BeginForm. My code keeps passing a null object to the action method in the controller. How do I pass the object to the controller via the form ?
#using (#Html.BeginForm("GetQueueInfoWorkorder","Home", FormMethod.Post, new { id = Model}))
{
#Html.TextBoxFor(x=> x.ID);
<input type="Submit" value ="Search" class="ui-button-icon-secondary"/>
}
Here is the actionmethod :
[HttpPost]
public ActionResult GetQueueInfoWorkorder(UserResponse id)
{
//Check queue complete
int woNumber = Convert.ToInt32(id);
tb_QueueCompleted completed = db.tb_QueueCompleted.SingleOrDefault(x => x.WorkOrderNumber == woNumber);
if (completed != null)
{
var u = new UserResponse { ID = completed.QueueId.ToString() };
GetLogInfoCompleted(u);
return View("GetLogInfo");
}
//check queue pending
return View();
}
I think you're fairly close, but make these changes & it should work as expected:
Model:
public class UserResponse
{
public int ID { get; set; }
}
View:
#model UserResponse
#using (Html.BeginForm("GetQueueInfoWorkorder", "Home"))
{
#Html.TextBoxFor(x => x.ID);
<input type="Submit" value ="Search" class="ui-button-icon-secondary"/>
}
Action method:
public ActionResult GetQueueInfoWorkorder(UserResponse model)
{
int woNumber = model.ID;
//...
}
if the #model of your view is UserResponse , then on submission of this page the model (UserResponse) will automatically get submitted to the controller. Where have you declared the #model for the view.
I found multiple posts about this issue on Stack Overflow but none with an answer that fix the problem I have.
I have a view with a dropdownlist that display the item label of journal from table in Database : Journal : id, label
Here is the code of the view :
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { #enctype = "multipart/form-data" }))
{
<input style="margin-left:40px;cursor:pointer;" type="file" name="file" id="upload"/>
<input type="text" name="journal" value="test"/>
<input type="submit" style="margin-left:40px;cursor:pointer;" id="load" value="Upload"/>
#Html.DropDownList("IdJournal")
}
And my controller is :
[HttpPost]
public ActionResult Index(HttpPostedFileBase file, string journal, long IdJournal)
{
ScanITAPP.Service.ImageRender service = new Service.ImageRender();
service.UploadImageToDB(file, journal, IdJournal);
return View();
}
public ActionResult Form()
{
return PartialView("Form");
}
//DropdownList
public ActionResult Index()
{
var db = new Bd_scanitEntities();
IEnumerable<SelectListItem> items = db.JournalSet
.Select(c => new SelectListItem
{
Value = c.Id.ToString(),
Text = c.label
});
ViewBag.IdJournal = items;
//ViewData["IdJournal"] = items;
return View();
}
The code is for uploading and image and associate it to a "Journal" , after executing the code I get the image with the Journal_id in my Dtabse but but it throws an error : There is no ViewData item of type 'IEnumerable' that has the key 'Id'. I don't know what's the problem please help me.
I resolved the problem by editing my controller method
[HttpPost]
public ActionResult Index(HttpPostedFileBase file, string journal, long IdJournal)
{
var db = new Bd_scanitEntities();
IEnumerable<SelectListItem> items = db.JournalSet
.Select(c => new SelectListItem
{
Value = c.Id.ToString(),
Text = c.label
});
ViewBag.IdJournal = items;
ScanITAPP.Service.ImageRender service = new Service.ImageRender();
service.UploadImageToDB(file, journal, IdJournal);
return View();
}
I am trying to use Jquery Multiselect plugin from Beautiful site and MVC3 together to send values to server. As shown in example from Darin the key is to create MultiSelectModelBinder class that will, I guess, recognize values send from client, because the multiselect plugin uses the [] notation to send the selected values to the server. My aproach is a little diferent, i fill dropDownList from my controller and not the model, keeping the model clean, and also been able to fill the list from Database. I used Darins example to create MultiSelectModelBinder and register it,in the model binder in Application_Start(). My problem is that I always keep getting empty Model back to my controller, here is the code:
MODEL:
public class PersonsSearchModel
{
public string Person { get; set; }
public string Company { get; set; }
//here is my Cities collection
public IEnumerable<string> Cities { get; set; }
}
VIEW:
#model MyNamespace.Model.PersonsSearchModel
#using (Ajax.BeginForm("Search", "Persons", new AjaxOptions
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "results",
LoadingElementId = "progress"
},
new { #id = "searchFormPerson" }
))
{
<span>
#Html.TextBoxFor(x => Model.Person, new { #class = "halfWidth"})
</span>
<span>
#Html.TextBoxFor(x => Model.Company, new { #class = "halfWidth"})
</span>
<span>
#Html.ListBoxFor(x => x.Cities, Model.Items, new { #id="combobox1"})
</span>
<input name="Search" type="submit" class="searchSubmit" value="submit" />
}
CONTROLLER:
public ActionResult Index()
{
var listCities = new List<SelectListItem>();
listCities.Add(new SelectListItem() { Text = "Select one...", Value = "" });
listCities.Add(new SelectListItem() { Text = "New York", Value = "New York" });
listCities.Add(new SelectListItem() { Text = "Boston", Value = "Boston" });
listCities.Add(new SelectListItem() { Text = "Miami", Value = "Miami" });
listCities.Add(new SelectListItem() { Text = "London", Value = "London" });
ViewBag.Cities = listCities;
return View();
}
public class MultiSelectModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var model = (PersonsSearchModel)base.BindModel(controllerContext, bindingContext);
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + "[]");
if (value != null)
{
return value.RawValue;
}
return model;
}
}
Here the data from client sholud arive, butt is always null?
public PartialViewResult Search(PersonsSearchModel psm)
{
var person = psm.Person;
var company = psm.Company;
var city = psm.Cities.ElementAt(0);
return GetResultPartialView(city);
}
GLOBAL.asax.cs
protected void Application_Start()
{
//...
//model binder
ModelBinders.Binders.Add(typeof(IEnumerable<string>), new
FinessenceWeb.Controllers.PersonsController.MultiSelectModelBinder());
}
JQUERY
$("#combobox1").multiSelect();
I had the same issue, although your provided solution still works. There is another way of doing it with less effort.
Actually defaultModelbinder does bind to multiple selected values if you can change your input parameter to List<inputparameter> and change the line #Html.DropDownListFor to #Html.ListBoxFor.
The key difference between these 2 controls is, First one being a single selection box and second one being a multiple selector.
Hope this helps some one having the same issue.
Well... After looking into DOM, and Jquery plugin, turns out the plugin gives the select element, atribute name, current id, so they are the same, and the form, well.. look's at the name attr. So solution wolud be:
$("#Cities").multiSelect();
Cheers!