MVC2 html dropdownlist is invisible - asp.net-mvc

I am just trying to populate a html.dropdown list using mvc2 in VS2008.
But the control is not displayed at all.
Here is my code
public ActionResult Index()
{
ViewData["Time"] = DateTime.Now.ToString();
var mdl = new List<SelectListItem>();
mdl.Add(new SelectListItem
{
Value = "1",
Text = "Module One"
});
mdl.Add(new SelectListItem
{
Value = "2",
Text = "Module Two"
});
ViewData["moduleList"] = new SelectList(mdl,"Value", "Text");
return View("MainMenu");
}
and here is the markup
<div>
<%Html.DropDownList("moduleList", (IEnumerable<SelectListItem>)ViewData["moduleList"]); %>
</div>
Where did i go wrong ?

You are best putting that stuff in your model so for example
in the controller
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
ViewData["Time"] = DateTime.Now.ToString(CultureInfo.InvariantCulture);
var mdl = new List<SelectListItem>
{
new SelectListItem
{
Value = "1",
Text = "Module One"
},
new SelectListItem
{
Value = "2",
Text = "Module Two"
}
};
ViewData["moduleList"] = new SelectList(mdl, "Value", "Text");
var model = new HomeModel
{
SelectedItem = 1,
items = mdl
};
return View(model);
}
}
Now create the model
namespace MvcApplication1.Models
{
public class HomeModel
{
public int SelectedItem { get; set; }
public IEnumerable<SelectListItem> items { get; set; }
}
}
your page will look like this on a test site
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Models.HomeModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2><%: ViewData["Message"] %></h2>
<p>
To learn more about ASP.NET MVC visit http://asp.net/mvc.
</p>
<div>
<%=Html.DropDownList("SelectedItem", Model.items)%>
</div>
</asp:Content>
Now an explanation, you have created a model for the view and this model is returned to the page by the controller the page is inheriting from a ViewPage which takes the generic argument of the model that was supplied to it by the controller
The markup is saying "give me a html drop down and mark the selected item as the first selected, the items come from the model (which is what your controller supplied it).
In the real world the data would come from your data layer and not directly in the controller (I like as little code in the controller as possible)
edit:
You have a typo for your example try this
<%= Html.DropDownList("moduleList") %>

Related

Why is the DropDown values Null in the POST action?

Below is the View:
<%# Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Models.Index>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Contact
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm())
{%>
<%=Html.DropDownListFor(x => x.SelectedFavColor, Model.DropDownItems)%>
<%= Html.ValidationMessageFor(x=> x.SelectedFavColor) %>
<input type="submit" value="submit" />
<%} %>
</asp:Content>
Below mentioned is the Model:
namespace MvcApplication1.Models
{
public class Index
{
[Range(0, 1000, ErrorMessage = "hello")]
public int SelectedFavColor { get; set; }
public IEnumerable<SelectListItem> DropDownItems { get; set; }
}
public class Colors
{
public int ColorID { get; set; }
public string ColorName { get; set; }
}
}
I am passing some Dropdown values in the View.
Below is the Controller action:
public ActionResult Contact()
{
List<MvcApplication1.Models.Colors> l = new List<Models.Colors>();
l.Add(new Models.Colors { ColorName = "-1", ColorID = -1 });
l.Add(new Models.Colors { ColorName = "a", ColorID = 0 });
l.Add(new Models.Colors { ColorName = "b", ColorID = 2 });
l.Add(new Models.Colors { ColorName = "c", ColorID = 3 });
l.Add(new Models.Colors { ColorName = "d", ColorID = 4 });
l.Add(new Models.Colors { ColorName = "e", ColorID = 4 });
l.Add(new Models.Colors { ColorName = "f", ColorID = 4 });
var model = new MvcApplication1.Models.Index
{
DropDownItems = l.Select(i => new SelectListItem
{
Text = i.ColorName,
Value = i.ColorID.ToString()
})
};
ViewData["records"] = model.DropDownItems;
return View(model);
}
[HttpPost]
public ActionResult Contact(Index posted, FormCollection collection)
{
posted.SelectedFavColor = Convert.ToInt16(collection["SelectedFavColor"]);
return View(posted);
}
Why is the DropDown values Null in the POST action?
The DropDownItems is null because it is not being POSTed in your form. You are only creating a drop down menu with this: Html.DropDownListFor(x => x.SelectedFavColor, Model.DropDownItems), which is not enough to post the collection.
Posting a collection, however, is rather tricky; but you can look into this.
One last thing: you already have the collection (since you are passing it to the View), so technically, you don't even need to POST it back to the server.
The simple reason why the values of DropDown are null is because they are not sent (POSTed) with the form (You can easily check it with Firebug Firefox extension). You will need to collect (repopulate) the values of dropdown list again to see those values in view.
Suggestion:
Do not return the view immediately after the POST. Typical pattern in ASP-MVC apps is Post-Redirect-Get. It will help you to avoid unnecesary re-POSTs of the form (e.g. on browser refresh button) - Why should I use PRG.

ASP.NET mvc : HOWTO: Update database after editing multiselectlist (listbox)

I'm really stuck at this: I have two listboxes populated from a database. I want to copy items from one list to the other. Then the changes must be saved in the database.
This is what I've got:
Custom ViewModel:
public class StudentModel
{
public IEnumerable<SelectListItem> NormalStudentsList { get; set; }
public IEnumerable<SelectListItem> StudentsNoClassList { get; set; }
public string[] NormalSelected { get; set; }
public string[] NoClassSelected { get; set; }
public string Save { get; set; }
}
Controller:
public ActionResult IndexStudents(Docent docent, int id, int klasgroepid)
{
var studentModel = new StudentModel
{
NormalStudentsList = docent.GeefStudentenNormaalList(id, klasgroepid),
StudentsNoClassList = docent.GeefStudentenNoClassList(id, klasgroepid)
};
return View(studentModel);
}
[HttpPost, Authorize]
public ActionResult IndexStudentsResult(StudentModel model, string add, string remove)
{
ModelState.Clear();
(if! string.IsNullOrEmpty(add))
//update database
SaveState(model);
return View(model);
}
But how can I update the database?? Using UpdateModel()?
or should I work with FormCollection? But I need a formCollection to work with UpdateModel()...
The Students table has a field named "ClassID", and when copying the rows from 1 list to the other, the ID has to change from the current ClassID to "0".
How can I do that? I'm really stuck at this... hope you can help.
This is my View
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ProjectenII.Models.Domain.StudentModel>"%>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
IndexStudents
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>IndexStudents</h2>
<%using (Html.BeginForm()) { %>
<%=Html.ListBoxFor(model => model.NormalSelected, new MultiSelectList(Model.NormalStudentsList, "StudentNummer", "Naam", Model.NormalSelected), new { size = "6" }); %>
<input type="submit" name="add"
id="add" value=">>" /><br />
<%=Html.ListBoxFor(model => model.NoClassSelected, new MultiSelectList(Model.StudentsNoClassList, "StudentNummer", "Naam", Model.NoClassSelected)); %>
<% } %>
<%=Html.HiddenFor(model => model.Save) %>
<input type="submit" name="apply" id="apply" value="Save!" />
</asp:Content>
Your problem is related to returning a List from the view... check this post by Phil Haack:
Model Binding To A List
Here you can see I ran into a similar problem. In my case a used checkboxes to select items in a list. The solution proposed guided me in the right direction but it wasn't the one I used, I used Phil's post.
My Post
Hope this helps.
We may also achieve using Editor helper, but making all of the multiselectlist elements selected before submit will work:
$("#NormalSelected option").prop("selected", true);
This will pass multiselectlist items to controller.

I am new to MVC getting exception when i try to render the textbox dynamically with the following code. Please help

"Object reference not set to an instance of an object" Exception occurs with the following code
VIEW Code
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Hello_World_MVC.Models.ModelProperty>" %>
<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">.
<%using (Html.BeginForm())
{ %>
<%foreach (var cbName in Model.Obj)//Exception throws here NullreferenceException
{%>
<input id="cbID" type="checkbox" name="SelectedObject" value="<%=cbName.OptionID%>"/>
<%} %>
<%} %>
</asp:Content>
Control page
public ActionResult About()
{
AboutModels ObjAM = new AboutModels();//model class name
ModelProperty ObjMP = new ModelProperty();
ObjMP.Obj = ObjAM.dbValue();
return View();
}
Model Page
#region ModelsDTO
public class ModelProperty
{
private List<double> cbvalues = new List<double>();
public List<double> cbValues { get; set; }
private List<Option> obj = new List<Option>();
public List<Option> Obj { get; set; }
}
#endregion
public class AboutModels
{
DataClasses1DataContext dbObj = new DataClasses1DataContext();
public List<PollOption> dbValue()
{
List<Option> opValue = new List<Option>();
opValue = (from Value in dbObj.Options
select Value).ToList<Option>();
return opValue;
}
}
Please help..Thanks in advance
Change return View(); in AboutAction with return View(ObjMP);. Your mistake is that you forget to pass generated model to view, and it is null.
you should enter the model/object as paramter for returning the view
so in your case it is
return View(ObjMP);
hth
You need to pass the model to the view. Try this..
public ActionResult About()
{
AboutModels ObjAM = new AboutModels();//model class name
ModelProperty ObjMP = new ModelProperty();
ObjMP.Obj = ObjAM.dbValue();
return View(ObjAM);
}

Partial view displaying error

I created a drop down list in a partial view and I am trying to render that on my aspx page. I am getting an error:
{"Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'."}
This is my aspx page where I am using the ascx control:
<td>
<% Html.RenderAction("getFilterdData");%>
</td>
My ascx control looks like this:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewPage<IEnumerable<assist>>" %>
<%=Html.DropDownList("Assists", (SelectList)ViewData["Assists"], "--Select One--")%>
and my controller code is like this:
public ActionResult getFilterdData()
{
scorerep sc = new scorerep();
ViewData["Assists"] = new SelectList(sc.FilterData(), "assist_a","");
return View();
}
Why am I getting this error and how can I fix it?
It is difficult to help without seeing the entire exception stacktrace. Here are a few tips:
Make sure that your partial Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<assist>>" and not Inherits="System.Web.Mvc.ViewPage<IEnumerable<assist>>". You are using an ASCX partial and inheriting from System.Web.Mvc.ViewPage which is wrong.
Make sure that your partial view is called exactly the same as the controller action: getFilterdData.ascx (I see a typo here)
Make sure that the Assist class contains a property called assist_a as that's what you are using when rendering the dropdown
Make sure there is no exception being thrown inside the getFilterdData controller action while you are fetching the data.
Here's a working example:
Model:
public class Assist
{
public string Id { get; set; }
public string Value { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult GetFilteredData()
{
// TODO: replace with your repository logic
ViewData["Assists"] = new SelectList(new[] {
new Assist { Id = "1", Value = "Assist 1" },
new Assist { Id = "2", Value = "Assist 2" },
new Assist { Id = "3", Value = "Assist 3" },
}, "Id", "Value");
return View();
}
}
View (~/Views/Home/Index.aspx):
<% Html.RenderAction("GetFilteredData"); %>
Partial: (~/Views/Home/GetFilteredData.ascx):
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Assist>>" %>
<%= Html.DropDownList("Assists", (SelectList)ViewData["Assists"], "--Select One--") %>

using a usercontrol on aspx page in MVC using partial view

I have Dropdown and on click of a button, I want to display data in the usercontrol
the below code is not working as expected.
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%
using (Html.BeginForm())
{%>
<%=Html.DropDownList("CarMake", (SelectList)ViewData["CarMake"])%>
<input type="submit" value="Get all car model" />
<%
Html.RenderPartial("CarModel");
} %>
</asp:Content>
// in controller
public ActionResult Test1()
{
ViewData["CarMake"] = new SelectList(_carDataContext.Makes.Select(m => new { ID = m.Id, Name = m.Name }), "ID", "Name");
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Test1(int carMake)
{
ViewData["CarMake"] = new SelectList(_carDataContext.Makes.Select(m => new { ID = m.Id, Name = m.Name }), "ID", "Name");
var carModel = _carDataContext.Models.Where(m => m.MakeId == carMake).ToList();
return PartialView("CarModel", carModel);
}
Since you're doing a full post of the form, you don't want to return a partial view. You want to set the ViewData["CarModel"] to the correct model, then re-render the same view. The RenderPartial in the view will use this to "include" the correct partial view in the code.
Note this would be different if you were posting via AJAX. At that point, you'd have it set up to replace a particular element of the page and you would want to only render the partial that goes into that element.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Test1(int carMake)
{
ViewData["CarMake"] = new SelectList(_carDataContext.Makes.Select(m => new { ID = m.Id, Name = m.Name }), "ID", "Name");
ViewData["CarModel"] = _carDataContext.Models.Where(m => m.MakeId == carMake).ToList();
return View();
}

Resources