I can't seem to find any examples anywhere that fit my situation (using MVC4 just directly getting data from the DB using Stored Procedures without using Entity Framework) to set the SELECTED value of the DropDownListFor to the currently selected value of what is listed for that specific item in the DB).
More specifically, here are extracts from my code (hopefully sufficient to isolate what this ignorant newbie is doing wrong) - that will hopefully help anyone else struggling to set the default listed value in DropDownListFor to what is already stored in the DB for what is being edited.
CONTROLLER
[HttpGet]
[Authorize]
public ActionResult Edit(string id, string ProdName, UpdateProductModel updateproductmodel)
{
int ProductID = Convert.ToInt32(id);
ViewBag.ProdName = ProdName;
SqlConnection cn = new SqlConnection(@"Data Source=D;User ID=user;Password=pswrd;Initial Catalog=cat");
SqlCommand cmd = new SqlCommand("sp_GetProduct", cn);
cn.Open();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@ProductID", ProductID));
SqlDataReader dr = cmd.ExecuteReader();
if (dr == null)
{
return HttpNotFound();
}
if (dr.Read())
{
DataSet dst = updateproductmodel.GetProducts_ByTypes();
ViewBag.UpProdTypes = dst.Tables[0];
List<SelectListItem> items = new List<SelectListItem>();
foreach (System.Data.DataRow dru in ViewBag.UpProdTypes.Rows)
{
items.Add(new SelectListItem { Selected = (Convert.ToInt32(@dru["ProdTypeID"].ToString()) == Convert.ToInt32(dr["ProdTypeID"].ToString())), Text = @dru["ProdTypeDescr"].ToString(), Value = @dru["ProdTypeID"].ToString() });
}
ViewBag.UpProdTypes = items;
if (Request.Cookies["OIDCookie"].Value == dr["OrganisationID"].ToString())
{
updateproductmodel.ProductID = Convert.ToInt32(dr["ProductID"].ToString());
updateproductmodel.ProdTypeID = Convert.ToInt32(dr["ProdTypeID"].ToString());
updateproductmodel.ProdTypeDescr = dr["ProdTypeDescr"].ToString();
updateproductmodel.ProductName = dr["ProductName"].ToString();
updateproductmodel.ProductDescription = dr["ProductDescription"].ToString();
updateproductmodel.ProductComments = dr["ProductComments"].ToString();
updateproductmodel.ProductProfileLocation = dr["ProductProfileLocation"].ToString();
updateproductmodel.ProductProfileName = dr["ProductProfileName"].ToString();
updateproductmodel.ProductMIMEType = dr["ProductMIMEType"].ToString();
updateproductmodel.ProductSerialNumber = dr["ProductSerialNumber"].ToString();
updateproductmodel.UpdateBy = Convert.ToInt32(Request.Cookies["UIDCookie"].Value);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
//dr.Close();
}
//dr.Close();
//cn.Close();
return View(updateproductmodel);
}
When I step through this there is a stage where the Convert.ToInt32(dr["ProdTypeID"].ToString()) -
(which is the value of the existing ProductTypeID captured previously in the DB for a particular Product)
is 3 (Pumps) and the value of Convert.ToInt32(@dru["ProdTypeID"].ToString() -
(which is the value of the type of product in a table listing the various product types that is iterated through to generate the list in DropDownListFor)
is also 3 (Pumps).
I assumed that would cause the related Product Type Description for the ID of 3 (i.e. "Pumps") to be set as the selected default value that would be displayed in the DropDownListFor in the EDIT view - but instead just the first type in the list is displayed, without the SELECTED taking effect - and when updated the value stored in the DB then naturally gets set to the value of the first type in the list (which happens to be DISPENSERS - and not the desired PUMPS - which could obviously then be changed to DISPENSERS if there was a data capture error initially - but obviously it should remain what it was if not wrong).
VIEW (well what I assume is all that is needed of it)
<div class="editor-label">
@Html.LabelFor(model => model.ProdTypeID)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ProdTypeDescr) <br />
@Html.DropDownListFor(model => model.SelectedProdTypeID, (IEnumerable<SelectListItem>)ViewBag.UpProdTypes, new { @class="form-control"})
@Html.ValidationMessageFor(model => model.ProdTypeID)
</div>
I've just displayed the value of the Product Type in the view before the DropDownListFor for simple comparison to check it the value displayed in each differs or not - it will obviously be removed in once I get the correct default listed in the DropDownListFor.
I've commented out the various Closes at the bottom of the Controller Action because of getting an error that an open connection was required - WHERE and WHEN is it safe to close the connections? (I obviously don't want to accumulate open connections that are never closed).
I will really appreciate any suggestions that get the default selection in the DropDownListFor set to the existing value for a particular product that was captured in the DB, when editing that particular product.
Thank you for sharing your expertise with a clueless newbie.
Alan