Hi I am trying to make a DropDownList work in my trivial app. I am an beginner. I have already spent several days looking at various instructions in books and at the web, so proberly if you direct me to one I have already been there. My situation is really simple and trivial yet I can't get it to work. I believe the best way to help me is to have a look at my code.
I have uploaded my projects to SkyDrive, I believe it will be quite simple for you to run my projects. So far the SelectList renders in the initial AddItem view.
Here is the projects:
http://cid-5c0bc0a6f7bdc3c6.office.live.com/self.aspx/DebugB/DropDownTwo.zip
The folder contains 2 projects:
- SHAWebService
- SHAWebRole
To run the projects:
- Fire up SHAWebService.
- Fire up SHAWebRole, it consumes SHAWebService on port 8080.
- Click the "AddItem" tab and you'l see my SelectList render in the AddItem view.
My question is then how to get it to work from there through the Edit and Details views?
If you prefer to look at my code here I will paste some of it below:
SalesItemController looks like this:
public ActionResult AddItem()
{
using (var WS = new SHAServiceReference.SHAServiceClient())
{
var categories = WS.GetCategories().ToList();
IEnumerable<SelectListItem> lstCategory = categories.Select(cat => new SelectListItem
{
Value = Convert.ToString(cat.CategoryID),
Text = cat.CategoryName
});
var salesItemModel = new SalesItemModel();
// Retrieving the UserID of the user which is going to add a sales item.
salesItemModel.SellerUserID = 24; // Hardcoded only for this example //(int)Session["userId"];
salesItemModel.CategorySelectList = lstCategory;
return View(salesItemModel);
}
}
[HttpPost]
开发者_开发知识库 public ActionResult AddItem(SalesItemModel salesItemModel, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
// This variable will capture the SalesItemID of the newly created SalesItem.
var salesItemId = 0;
//Attempt to add the SalesItem
using (var WS = new SHAServiceReference.SHAServiceClient())
{
salesItemId = WS.AddSalesItem
(
salesItemModel.SellerUserID,
salesItemModel.CategoryID,
salesItemModel.Title,
salesItemModel.Description,
salesItemModel.Price,
false
);
return View(salesItemModel);
}
}
return View(salesItemModel);
}
AddItem view looks like this:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<SHAWebRole.Models.SalesItemModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Add Item
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>
Add Item To Sell</h2>
<% using (Html.BeginForm("AddItem", "SalesItem", FormMethod.Post, new { enctype = "multipart/form-data" }))
{%>
<%: Html.ValidationSummary(true)%>
<fieldset>
<legend>Fill in info about what you are selling</legend>
<div id="userDiv">
<%: Html.HiddenFor(model => model.SalesItemID)%>
<%: Html.HiddenFor(model => model.SellerUserID)%>
Sales Item Category
<div>
<%: Html.DropDownListFor(m => m.CategoryID, Model.CategorySelectList, "Select Category") %>
</div>
When I retrieve the CategoryID and CategoryName in SalesItemController from the web service with this method var categories = WS.GetCategories().ToList();
I am calling this method in the web service:
/* Returns a list with the Categories for SalesItems */
public List<CategoryDto> GetCategoriesBL()
{
var categories = (from eachCategory in context.Categories
select new CategoryDto
{
CategoryID = eachCategory.CategoryID,
CategoryName = eachCategory.CategoryName
}
).ToList();
return categories;
}
The data transfer object I use in the above method (CategoryDto) looks like this:
[DataContract]
public class CategoryDto
{
[DataMember]
public int CategoryID { get; set; }
[DataMember]
public string CategoryName { get; set; }
}
Finaly SalesItemModel looks like this:
public class SalesItemModel
{
public int SalesItemID { get; set; }
public int SellerUserID { get; set; }
public int CategoryID { get; set; }
public IEnumerable<SelectListItem> CategorySelectList { get; set; }
Currently the DropDownList renders fine in the initial AddItem view, but when I click the "Add Item" button, the following exception is thrown:
"The ViewData item that has the key 'CategoryID' is of type 'System.Int32' but must be of type 'IEnumerable'."
I don't know what to do to make it work. Can you help me? I need someone to help me correct some details to get this to work.
Ok, here goes, modify your view model to include a property for the selected value. It's also good practice to avoid the use of ViewData if possible, so we can add the SelectListItems as well...
public class SalesItemModel
{
...
public IEnumerable<SelectListItem> CategorySelectList { get; set; }
public int CategoryID { get; set; }
...
}
now, in the controller change the select list populating too...
var categories = WS.GetCategories().ToList();
IEnumerable<SelectListItem> lstCategory = categories.Select(x => new SelectListItem
{
Value = Convert.ToString(cat.CategoryID),
Text = cat.CategoryName
});
var salesItemModel = new SalesItemModel();
salesItemModel.CategorySelectList = lstCategory;
in the view it gets simpler as well now that you have strongly typed selectlistitems...
<% Html.DropDownListFor(m => m.CategoryID, Model.CategorySelectList, "Select Category") %>
and finally modify the post action to use the posted selection...
salesItemId = WS.AddSalesItem
(
salesItemModel.SellerUserID,
salesItemModel.CategoryID, //change here
salesItemModel.Title,
salesItemModel.Description,
salesItemModel.Price,
false
);
精彩评论