id doesnt get passed (MVC dropdownlist + viewdata selectlist) - c#

my view:
#using (Html.BeginForm("Index", "Person"))
{
#Html.DropDownList("Departments",ViewData["Departments"] as SelectList)
<button type="submit">Select</button>
}
my DepartmentController:
public ActionResult Index()
{
ViewData["Departments"] = new SelectList(db.Departments, "ID", "Name");
return View();
}
my PersonController
public ActionResult Index(string id = null)
{
if (id != null)
{
//Return list of persons with department id
}
return View();
}
My problem:
When I select a department from the DropDown and press the button, it redirects fine, but the id is not passed.
What am I missing? I'm guessing it has to do with how i fill the DropDownList?
Anyway, as always, thanks in advance

The name attribute of your dropdown is not "id" so the MVC model binder can not bind it.
Add html attribute new {#Name ='id'} to your DropDown definition and it should work.
I also would suggest that your view receive a model - in this case model binding will be much easier, and you could use DropDownFor helper.
Using model also allows you to avoid using ViewData and ViewBag containers that are not recommended because they are not strongly typed so if by mistake you write ViewData["Departnents"] in your View you won't get a compilation error because of the typo, but clearly it won't work.
As an opposite you can define a model
public class Person
{
public SelectList Departments {get; set;}
public int SelectedDepatrmentId {get; set;}
//Other person properties come here
}
In your View the only thing you should do to make it work is:
#model path to your Person class
#Html.DropDownListFor(model => model.SelectedDepatrmentId, Model.Departments)

The problem in your case that mvc model binding is done with name attribute and #Html.DropDownList("Departments"... will render html with dropdown having name 'Departments' so either try my first answer or change #Html.DropDownList("Departments"... as shown in my second answer.
Try This :
public ActionResult Index(string Departments) // <------ Use 'Departments' here instead of 'id'
{
.....
return View();
}
OR change dropdownlist as :
#Html.DropDownList("id",ViewData["Departments"] as SelectList)

Related

There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key "Auteur_du_Livre"

(First topic for me -> Amazing !)
I'm actually learning how to Handle ASP.NET MVC and i'm having some problem with he Html Helper DropDownListFor.
So the class concerned looks like that :
public class Auteur {
[required]
public int Id {get; set;}
public string Nom {get; set;}
}
My controller looks like that :
[HttpGet]
public ActionResult Ajout_livre()
{
Donnee_a_persister data = new Donnee_a_persister();
List<Auteur> auteur_possible = new List<Auteur>();
foreach (Auteur temp in data.afficher_auteurs())
auteur_possible.Add(temp);
ViewBag.auteur_possible = new SelectList(auteur_possible,"Id","Nom");
return View();
}
And I use it in my view like that :
<div>
#Html.LabelFor(model => model.Auteur_du_livre)
#Html.DropDownListFor(model => model.Auteur_du_livre, (SelectList)ViewBag.auteur_possible)
#Html.ValidationMessageFor(model => model.Auteur_du_livre)
</div>
Here is my post-method (as you can see i tried to populate the select list here too)
[HttpPost]
public ActionResult Ajout_livre(Livre detaillivreaajouter)
{
Donnee_a_persister data = new Donnee_a_persister();
List<Auteur> auteur_possible = new List<Auteur>();
foreach (Auteur temp in data.afficher_auteurs())
auteur_possible.Add(temp);
ViewBag.auteur_possible = new SelectList(auteur_possible, "Id", "Nom");
if (ModelState.IsValid == false)
{
return View(detaillivreaajouter);
}
//Work out
return View("Livre_eligible", detaillivreaajouter);
}
Auteur_du_livre reffers to a variable of type Auteur as this view is strongly typed.
So I get the view and my dropdown list is populated with the content of the ViewBag but when I submit the form I get the following error
There is no ViewData item of type 'IEnumerable' that has the key "Auteur_du_Livre"
I've seen that this problem is frequent so i've tried a lot of thing but i can't figure out what is really happening
Is it possible to get the whole object directly from the form(due to the binding) or do I have to get the property Id and find the corresponding Object in my post method ?
I finally get what's wrong in my Model : i thought that the binding made with the SelectList could directly get the object of type Auteur when the user submit the form but it's wrong. The binding can only get a primitive variable (here it would get the property Id of type int) that was assert on the value fo the form via the selectlist.
Thanks for all.
So i've just changed the helper in my view in the following way :
#Html.DropDownListFor(model => model.Auteur_du_livre.Id, (SelectList)ViewBag.auteur_possible)

Let textboxfor display the value it updates

I got this textbox in my view inside a beginform:
#Html.TextBoxFor(m => m.Page.logoUrl)
When i submit, the value i put in the textbox updates the db..
I would like the textbox to display the value from the db when the
page loads.
I often use a viewmodel class for this type of thing:
public class IndexViewModel
{
public string LogoUrl { get; set; }
}
I use that viewmodel in the controller's action method like so.
public ActionResult Index()
{
var viewModel = new IndexViewModel();
viewModel.LogoUrl = // Get this from DB.
return View(viewModel);
}
Finally, I can use the LogoUrl in the view:
#using IndexViewModel
#Html.TextBoxFor(m => m.LogoUrl)
This way, you can display the LogoUrl when the page loads (note, you will likely have different action method named to Index, I was just making an assumption).

MVC4 model binding - Passing Custom View Models & values from view to controller

I have a strongly typed view with the following model.
public class ProductViewModel
{
public Product Product { get; set; }
public List<ProductOptionWithValues> ProductOptionsWithValues { get; set; }
}
public class ProductOptionWithValues
{
public ProductOption ProductOption;
public List<AllowedOptionValue> AllowedOptionValues;
}
I'm using this Model To populate a form where a user can select the options they want for a product.
This is the view.
#model AsoRock.Entities.ViewModels.ProductViewModel
#{
ViewBag.Title = "Details";
}
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<h3>
#Html.DisplayFor(model => model.Product.ProductName)
----> #Html.DisplayFor(model => model.Product.Price)
</h3>
<br/>
foreach (var item in Model.ProductOptionsWithValues)
{
<b>#Html.DisplayFor(modelItem => item.ProductOption.Option.OptionName)</b>
<br/>
#Html.DropDownListFor(m => m.ProductOptionsWithValues,
new SelectList(item.AllowedOptionValues,
"Id", "DisplayString",
item.AllowedOptionValues.First().Id))
<br/>
}
<input type="submit" value="Add to cart" />
}
In my controller I am trying to pass the model back. When I set a break point in the controller it hits it but the Product view model is empty, any ideas how I can get the values that are selected in the view back in to my controller?
[HttpPost]
public ActionResult Details(ProductViewModel ProductViewModel)
{
return View();
//return View();
}
As mentioned in the comments, you need to change the name of the viewmodel parameter from ProductViewModel to something else e.g.
[HttpPost]
public ActionResult Details(ProductViewModel viewModel)
{
}
Now it's very odd that the viewModel param is not set to an instance of the class. The MVC model binder will still create an instance of ProductViewModel even if none of it's properties are set to anything. You're not using a custom model binder by any chance?
Also I would very strongly suggest that your viewmodel class does not have a Product property. Instead, create properties in the viewmodel specifically for the Product properties you intend to use e.g.
public class ProductViewModel
{
public string ProductName { get; set; }
public decimal ProductPrice { get; set; }
public List<ProductOptionWithValues> ProductOptionsWithValues { get; set; }
}
Using Product in the viewmodel sort of defeats the point of having a viewmodel. The viewmodel should contain only the bare minimum that the view needs. Including Product means the viewmodel is now bloated with extra data it does not use/need.
EDIT:
In your shoes, I would strip down the view itself, using only little bits of the viewmodel, and POST to the controller to see what happens. If the viewmodel calss is not NULL, go back to the view and add another bit back. Keep doing this until the viewmodel is NULL again. Doing this bit by bit should help.

using DropdownlistFor helper for a list of names

I know it was silly to ask this question but I'm not able to figure it out and I need your help guys.
First of all I am new to MVC. In my Project I am using a dropdownlistFor helper for displaying a list of names available for a particular Id. I did that and it is displaying names for an id.
Now while posting the form I am getting a Null Reference Exception for property used in the dropdownlist.
Here is my property in model which is a list of names.
In my controller in the [HttpGet] I did this which calls a function and returns a list of names for that Id.
Now the list of names is being displyed while form loading. And my view is as
When I am submitting the form I am getting a Null Reference Exception because in new SelectList(Model.InterviewerName) the Model is NULL.
Is there anyway to get me out of this issue.
I think you should update your viewmodel like this:
public class InterviewViewModel
{
public List<SelectListItem> Interviewers { set;get;}
public int SelectedInterviewerID { set;get;}
//Other properties relevant to the view as needed
}
And in your GET action set the Interviewers collection property:
public ActionResult Interview()
{
var vm=new InterviewViewModel();
vm.Interviewers =GetInterViewrsFromSomewhere();
return View(vm);
}
public List<SelectListItem> GetInterViewrsFromSomewhere()
{
var list=new List<SelectListItem>();
//Items hard coded for demo. you can read from your db and fill here
list.Add(new SelectListItem { Value="1", Text="AA"});
list.Add(new SelectListItem { Value="2", Text="BB"});
return list;
}
And in your view which is strongly typed to InterviewViewModel
#model InterviewViewModel
#using(Html.Beginform())
{
<p>Select interviewer :
#Html.DropdownlistFor(x=>x.SelectedInterviewerID,Model.Interviewers,"Select")
<input type="submit" />
}
So when the form is posted, The selected interviewers id will be available in the SelectedInterviewerID property:
[HttpPost]
public ActionResult Interview(InterviewViewModel model)
{
if(ModelState.IsValid)
{
//check for model.SelectedIntervieweID value
//to do :Save and redirect
}
//Reload the dropdown data again before returning to view
vm.Interviewers=GetInterViewrsFromSomewhere();
return View(vm);
}
In the HttpPost action method, if you are returning the viewmodel back to the view, you need to refill the dropdown content because HTTP is stateless and it won't keep the dropdown content between the requests (Webforms does this using Viewstate and here in MVC we don't have that).
I think i spotted the problem, you need to do the following two things to resolve,
1) change the model property public IList<string> InterviewerName to public string InterviewerName
2) use ViewBag to take the selectlist values to the View.
Let me know if it helps.

how to Bind dropdownList using Entity Framework in MVC 3

i want to show a dropdownList on a page using Entity Framework in my MVC app, but i am just stuck here to do this using using HTML Helper. so if anyone having knowledge of entity framework, help me...
my dataContext partial class is Entities, in which an entity named MemberInfo have some fields including MemberID & MemberName, so my dropdownList should show the field MemberName & behind this the value should be MemberID,
the code i tried yet--->
#Html.DropDownListFor(Model => Model.MemberID, MemberInfo)
in controller i am returning the Model--->
var MemberNameList = FinanceDBContext.MemberInfoes.Select(x => new { x.MemberID, x.Name });
return View(MemberNameList);
but its not working (errors).
You need to pass in all of your objects as the "model". Best practice is to use a ViewModel which will contain the list of data and a property to store the selected item.
ViewModel
public class MyViewModel
{
// The drop-down list and variable to get selection
public List<Member> Members { get; set; }
public int SelectedMemberId { get; set; }
}
Controller
[HttpGet]
public ActionResult Index()
{
var viewModel = new MyViewModel();
viewModel.Members = FinanceDBContext.MemberInfoes.ToList();
return View(viewModel);
}
[HttpPost]
public ActionResult Index(MyViewModel viewModel)
{
string debug = string.Format("You selected member: {0}", viewModel.SelectedMemberId);
return View(viewModel);
}
Finally, in your view (these lines need to be inside a BeginForm { ... } and ensure your View is strongly typed to MyViewModel
#Html.DropDownList("SelectedMemberId", new SelectList(Model.Members, "MemberID", "Name"))
<input type="submit" value="Save etc..." />
In this example you could put a break-point on the HttpPost action and check the debug string to check the correct Member is returned and proceed as required.

Categories