Reputation: 574
I have been trying to call a POST action from my view. I see POST method parameter is always null. What I am doing wrong ?
My model class :
public class Survey
{
public int Id { get; set; }
public int QuestionId { get; set; }
public string QuestionText { get; set; }
public int ResponseId { get; set; }
public string ResponseText { get; set; }
public string Comments { get; set; }
}
My controller method:
[HttpPost]
public ActionResult Publish(List<Survey> surveyToSave)
{
if (ModelState.IsValid)
{
return View("Index");
}
//Save logc
return View("Index");
}
View code:
@model List<Survey>
@using (Html.BeginForm("Publish","Home",FormMethod.Post))
{
<div class="center-div">
@foreach (var item in Model)
{
<div [email protected] class="Question">
<table>
<tr>
<td>@item.QuestionText</td>
</tr>
<tr>
<td>
<div>
<label>
@Html.RadioButtonFor(m => m.Find(i => i.QuestionId == item.QuestionId).ResponseText, "Not sure")
Not sure
</label>
</div>
<div>
<label>
@Html.RadioButtonFor(m => m.Find(i => i.QuestionId == item.QuestionId).ResponseText, "Agree")
Agree
</label>
</div>
</td>
</tr>
</table>
</div>
}
}
</div>
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Publish" class="btn btn-default" />
</div>
}
Most properties in model is supposed to be populated from view. Idea was to make the model in UI and submit that in post to save.
Upvotes: 0
Views: 748
Reputation: 218702
Your current view code is generating the input element like this, for all the items in the collection.
<input id="ResponseText" name="ResponseText" type="radio" value="Not sure" />
Model binding will work when the property structure/names matches with the form data posted to your method matches. The default model binder will look into the name attribute value of each item in the posted form data and tries to find a matching property in the class object you used as the method parameter and map the values. Since your HttpPost action methods parameter is List<Survey>
, for model binding to work, your input element names should be some thing like this
<input name="[n].ResponseText" type="radio" value="Not sure" />
Where n
is the index, starting from 0
to Model.Count-1
You can convert your view code to use a for
loop and create input element with above name
attribute value
@model List<Survey>
@using (Html.BeginForm("Publish", "Home", FormMethod.Post))
{
<div class="center-div">
@for (var i = 0; i < Model.Count; i++)
{
<div>
<label>@Model[i].QuestionText</label>
<label>@Html.RadioButtonFor(m => Model[i].ResponseText, "Not sure")No</label>
<label>@Html.RadioButtonFor(m => Model[i].ResponseText, "Agree")Agree </label>
</div>
@Html.HiddenFor(a => Model[i].QuestionId)
}
</div>
<input type="submit" value="Publish" class="btn btn-default" />
}
Upvotes: 2