Reputation: 71
As I mentioned in title after Post Back List (MySalonTreatments) property in ViewModel is null.
I am new to MVC but I think it should work. Model binder know how to handle complex types. I search a lot but I do not get on any solution. Maybe you could point me errors.
ViewModel:
public class CreateSalonViewModel
{
public string Name { get; set; }
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }
//it shouldn't be facebook adress
public string Website { get; set; }
public string MobilePhone { get; set; }
public string LandlinePhone { get; set; }
public int CityId { get; set; }
public int ProvinceId { get; set; }
public List<SalonTreatments> MySalonTreatments;
}
public class SalonTreatments
{
public List<Treatment> SpecTypeTreaments { get; set; }
public TreatmentType TreatmentType { get; set; }
}
Controller:
public class SalonController : Controller
{
private CrsDatabase db = new CrsDatabase();
//
// GET: /Salon/Create
[Authorize]
[HttpGet]
public ActionResult Create()
{
return View(GetCreateSalonViewModel());
}
[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CreateSalonViewModel createSalonViewModel)
{
return View(createSalonViewModel);
}
#region service methods
private CreateSalonViewModel GetCreateSalonViewModel()
{
CreateSalonViewModel createSalonViewModel = new CreateSalonViewModel();
createSalonViewModel.MySalonTreatments = new List<SalonTreatments>();
foreach (var treatmentType in db.TreatmentType)
{
var treatmentOfSpecType = db.Treatment.Where(t => t.TreatmentType.Id == treatmentType.Id).ToList();
if (treatmentOfSpecType.Count > 0)
{
SalonTreatments salonTreatments = new SalonTreatments();
salonTreatments.TreatmentType = treatmentType;
salonTreatments.SpecTypeTreaments = treatmentOfSpecType;
createSalonViewModel.MySalonTreatments.Add(salonTreatments);
}
}
return createSalonViewModel;
}
#endregion
}
View:
@model CRSWebsite.ViewModels.CreateSalonViewModel
@using (Html.BeginForm("Create", "Salon", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>CreateSalonViewModel</h4>
<hr />
@Html.ValidationSummary(true)
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.EmailAddress, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.EmailAddress)
@Html.ValidationMessageFor(model => model.EmailAddress)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Website, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Website)
@Html.ValidationMessageFor(model => model.Website)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.MobilePhone, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.MobilePhone)
@Html.ValidationMessageFor(model => model.MobilePhone)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LandlinePhone, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LandlinePhone)
@Html.ValidationMessageFor(model => model.LandlinePhone)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CityId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CityId)
@Html.ValidationMessageFor(model => model.CityId)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ProvinceId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ProvinceId)
@Html.ValidationMessageFor(model => model.ProvinceId)
</div>
</div>
@for (int i = 0; i < Model.MySalonTreatments.Count; i++)
{
<label>Zabiegi @Model.MySalonTreatments[i].TreatmentType.Name:</label>
<div class="form-group">
<div class="col-md-10">
@for (int j = 0; j < Model.MySalonTreatments[i].SpecTypeTreaments.Count; j++)
{
@Html.CheckBoxFor(m => m.MySalonTreatments[i].SpecTypeTreaments[j].IsSelected)
@Html.DisplayFor(m => m.MySalonTreatments[i].SpecTypeTreaments[j].Name)
}
</div>
</div>
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Regards, Peter
Upvotes: 1
Views: 3044
Reputation: 71
Finally I have resolved my issue!
It was trivial problem, in my viewmodel class CreateSalonViewModel I created treatments collection as:
public List<SalonTreatments> MySalonTreatments;
but for some unknown reason model binder can't handel this. Right way to do it is:
public List<SalonTreatments> MySalonTreatments { get; set; }
Thanks for help!
Upvotes: 5
Reputation: 38367
public ActionResult Create()
appears to be the GET method for displaying your form. You need another method to accept the POST, and make sure to add HttpGet to the first to ensure MVC can distinguish between the two. Also verify your form is using the POSt method to submit the form:
[Authorize][HttpGet]
public ActionResult Create()
{
return View(GetCreateSalonViewModel());
}
[HttpPost]
public ActionResult Create(CreateSalonViewModel model)
{ // MVC will try to bind your POSTed form to parameters
...
}
Upvotes: 1