Reputation: 203
Controller
[HttpPost]
public ActionResult SaveProduct(string id, AddProductViewModel m)
{
if (ModelState.IsValid)
{
using (ComparisonDBDataContext CMP = new ComparisonDBDataContext())
{
tblProduct prod = (from c in CMP.tblProducts
where c.ProductID == Guid.Parse(id)
select c).SingleOrDefault();
prod.Name = m.myName;
prod.CategoryID = Guid.Parse(m.myCategory);
prod.ManufacturerID=Guid.Parse(m.myManufacturer);
CMP.SubmitChanges();
}
return RedirectToAction("Products");
}
else
{
m.ProductID = Guid.Parse(id);
return View("EditProduct", m);
}
}
View
@model Comparison.Models.AddProductViewModel
@{
ViewBag.Title = "EditProduct";
Layout = "~/Views/_LayoutData.cshtml";
}
<style>
.field-validation-error {
color: Black;
}
.validation-summary-errors {
font-weight: bold;
color: Black;
}
</style>
<h2>Edit Product</h2>
@using (Html.BeginForm("SaveProduct", "Home", new { id = @Model.ProductID }, FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true)
<div class="form-group">
<label class="control-label col-md-2" id="lblName">Name</label>
<div class="col-md-5">
@Html.TextBoxFor(m => m.myName, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.myName)
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2" id="lblCategory">Category</label>
<div class="col-md-5">
@Html.DropDownListFor(m => m.myCategory, Model.Category, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.myCategory)
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2" id="lblManufucturer">Manufucturer</label>
<div class="col-md-5">
@Html.DropDownListFor(m => m.myManufacturer, Model.Manufacturer, new {@class="form-control" })
@Html.ValidationMessageFor(m => m.myManufacturer)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Products")
</div>
View Model
public Guid? myUserID;
[Required(ErrorMessage="Required")]
public string myCategory;
public List<SelectListItem> category = new List<SelectListItem>();
public List<SelectListItem> Category
{
get
{
category.Clear();
using (ComparisonDBDataContext CMP = new ComparisonDBDataContext())
{
var cat = from g in CMP.tblCategories
select new { g.Name, g.CategoryID };
foreach (var q in cat)
{
category.Add(new SelectListItem() { Text = q.Name, Value = q.CategoryID.ToString() });
}
return category;
}
}
}
public Guid? ProductID;
[Required(ErrorMessage = "Required")]
public string myManufacturer;
public List<SelectListItem> manufacturer = new List<SelectListItem>();
public List<SelectListItem> Manufacturer
{
get
{
category.Clear();
using (ComparisonDBDataContext CMP = new ComparisonDBDataContext())
{
var manu = from g in CMP.tblManufacturers
select new { g.Name, g.ManufacturerID };
foreach (var q in manu)
{
manufacturer.Add(new SelectListItem() { Text = q.Name, Value = q.ManufacturerID.ToString() });
}
return manufacturer;
}
}
}
[Required(ErrorMessage = "Required")]
[StringLength(100, ErrorMessage = "Maximum lenght can be 100")]
public string myName;
public DateTime? CreationDate;
I have tried googling it but could not find any solutions.
I know similar questions are already asked but i couldn't find my solution in them. So kindly just review my code and tell me what I am doing wrong. Why my Model is empty ON POSTBACK?
Upvotes: 0
Views: 402
Reputation:
Your view model contains properties with only getters (and in some case they are just fields without any getter or setter) so the DefaultModelBinder
cannot set their values. It needs to be
public string myName { get; set; }
Side note: A view model should not contain database access code. It shouldbe simply
public List<SelectListItem> manufacturer { get; set; }
and the controller should be responsible for assigning the collection to the property.
Upvotes: 4