#html razor radio buttons mvc5 - asp.net-mvc

here's my viewmodel
public class UserResponseModel
{
public string QuestionId { get; set;}
public string QuestionText { get; set; }
public bool IsChecked { get; set; }
}
so, for checkboxes this works beautifully
for (var i = 0; i < Model.UserResponses.Count; i++)
{
<div class="row">
<div class="col-md-4">
<div class="form-group">
#Html.HiddenFor(x => x.UserResponses[i].QuestionId)
#Html.CheckBoxFor(x => x.UserResponses[i].IsChecked)
but for radio buttons this does not
for (var i = 0; i < Model.UserResponses.Count; i++)
{
<div class="row">
<div class="col-md-4">
<div class="form-group">
#Html.HiddenFor(x => x.UserResponses[i].QuestionId)
#Html.RadioButtonFor(x => x.UserResponses[i].IsChecked, new { Name = "grp1" })
#Html.DisplayTextFor(x => x.UserResponses[i].QuestionText)
when i submit the form then IsChecked is always false - why - what am i missing - as I mentioned for checkboxes it works just fine. I did look at this question here but i'm not sure why radiobuttons require extra properties in the view model to hold the correct answer when checkboxes work transparently.
Edit: my question model is now as so
public class QuestionModel
{
public string WhichQuestion { get; set; }
public int PointsObtained { get; set; }
public bool CorrectAnswer { get; set; }
private List<UserResponseModel> _userResponse;
public List<UserResponseModel> UserResponses
{
get { return _userResponse ?? (_userResponse = new List<UserResponseModel>()); }
set { _userResponse = value; }
}
}
notice i have just added public bool CorrectAnswer { get; set; }
and in my view here's the code
for (var i = 0; i < Model.UserResponses.Count; i++)
{
<div class="row">
<div class="col-md-4">
<div class="form-group">
#Html.HiddenFor(x => x.UserResponses[i].QuestionId)
#Html.HiddenFor(x => x.CorrectAnswer)
#Html.HiddenFor(x => x.UserResponses[i].IsChecked)
#Html.RadioButtonFor(x => x.UserResponses[i].IsChecked, Model.CorrectAnswer, new { Name = "grp1" })
EDIT 2:
#Html.HiddenFor(x => x.UserResponses[i].QuestionId)
#Html.HiddenFor(x => x.SelectedAnswerId)
#Html.HiddenFor(x => x.UserResponses[i].IsChecked)
#Html.RadioButtonFor(x => x.UserResponses[i].IsChecked, Model.SelectedAnswerId, new { Name = "grp1" })
EDIT3:
public class QuestionModel
{
public string WhichQuestion { get; set; }
public int PointsObtained { get; set; }
private List<UserResponseModel> _userResponse;
public List<UserResponseModel> UserResponses
{
get { return _userResponse ?? (_userResponse = new List<UserResponseModel>()); }
set { _userResponse = value; }
}
}
public class UserResponseModel
{
public string QuestionId { get; set;}
public string QuestionText { get; set; }
public string SelectedQuestionId { get; set; }
}
finally, my view
for (var i = 0; i < Model.UserResponses.Count; i++)
{
<div class="row">
<div class="col-md-4">
<div class="form-group">
#Html.HiddenFor(x => x.UserResponses[i].QuestionId)
#Html.RadioButtonFor(x => x.UserResponses[i].SelectedQuestionId, Model.UserResponses[i].QuestionId, new { Name = "grp1" })
#*#Html.CheckBoxFor(x => x.UserResponses[i].IsChecked)*#
#Html.DisplayTextFor(x => x.UserResponses[i].QuestionText)
EDIT4:so finally I'm getting some where
this works!!!
#Html.RadioButtonFor(x => x.UserResponses[i].SelectedQuestionId, Model.UserResponses[i].QuestionId)
I can now see the selectedquestionid populated in my httppost method but if I do this
#Html.RadioButtonFor(x => x.UserResponses[i].SelectedQuestionId, Model.UserResponses[i].QuestionId, new {Name="grp"})
then though i am able to select only one radiobutton the selectedquestionid is null on httppost - wierd

Radio buttons are not checkboxes. Radio buttons are grouped. This means that you should have a single property on your view model to hold the selected radio button value (as shown in the answer you linked to). With check boxes you could have multiple checkboxes selected, that's thy you are binding them to a collection of boolean values in your view model. Radio buttons on the other hand have only one possible selected value because they are mutually exclusive. That's why they should all be bound to a single property on your view model that will hold the selected radio button value.
So in your example of questions and answers, you have a question view model that will contain the question id and text as well as a list of possible answers. Each answer will be represented by an id and text. Your question view model will also have an answer property that will hold the selected answer radio button from the user. It is this property that you are going to bind all your radio button to. But with a different value.

Related

Binding complex object .net core

I have a model view that has a list of objects in it, so it has a list of other class in it:
public class CpdTestFeedbackFormModel
{
public Guid WebsiteKey { get; set; }
//
//some other simple fileds
public List<SelectListItem> StarItems;
public List<CpdFeedbackQuestionAnswerModel> Questions;
public CpdTestFeedbackFormModel()
{
//some initialization
}
}
and the other class definition:
public class CpdFeedbackQuestionAnswerModel
{
public Guid Questionkey { get; set; }
public string Question { get; set; }
public string QuestionType { get; set; }
public int RatingAnswer { get; set; }
public string TextAnswer { get; set; }
}
I render my data like this in the view:
using (Html.BeginForm("SubmitFeedbackAnswers", "Form", FormMethod.Post, new
{
enctype = "multipart/form-data"
}))
{
#Html.HiddenFor(x => Model.WebsiteKey)
#Html.HiddenFor(x => Model.Testkey)
<div>
<div>
<h1>Feedback Questions</h1>
#for (int i = 0; i < #Model.Questions.Count(); i++)
{
<p>Q.<span>#Model.Questions[i].Question</span></p>
<p>
#if (#Model.Questions[i].QuestionType == "Star Rating")
{
#foreach (var starItem in Model.StarItems)
{
#Html.RadioButtonFor(model => Model.Questions[i].RatingAnswer, starItem.Value)
#Html.Label(starItem.Text)
}
}
else
{
#Html.HiddenFor(m => Model.Questions[i].Questionkey)
#Html.HiddenFor(m => Model.Questions[i].Question)
#Html.HiddenFor(m => Model.Questions[i].QuestionType)
#Html.HiddenFor(m => Model.Questions[i].RatingAnswer)
#Html.TextBoxFor(m => Model.Questions[i].TextAnswer)
}
</p>
}
</div>
</div>
<div>
<button type="submit" data-type="submit" class="bg-btn-primary">
Save Answer
</button>
</div>
</div>
}
when I inspect the view binding seems perfect:
but in my controller, the questions field is empty all other data are coming ok except that list.
[HttpPost]
public async Task<StatusCodeResult> SubmitFeedbackAnswers(CpdTestFeedbackFormModel model)
did I miss something?
After having another look I noticed a mistake in my CpdTestFeedbackFormModel class, my Questions don't have a get; set; method!! and that's it, it's working fine now.
public List<CpdFeedbackQuestionAnswerModel> Questions { get; set; }
Only missed part.

How can i take many textboxes' value on Post in MVC

i have a problem about MVC, but first I am sorry for my english :D .
Now i am trying to make a form for users and i have a critical issue when i want connect to values with database.
My Form is like this : https://i.hizliresim.com/vJ6r2p.png
Models :
[Table("Testers")]
public class Testers
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[StringLength(50),Required]
public string testerName { get; set; }
public ICollection<Scores> Scores { get; set; }
}
[Table("Technologies")]
public class Technologies
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[StringLength(50)]
public string technologyName { get; set; }
[StringLength(50)]
public string type { get; set; }
}
[Table("Scores")]
public class Scores
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[DefaultValue(0)]
public int score { get; set; }
public virtual Testers tester { get; set; }
public virtual Technologies technology { get; set; }
}
ViewModels:
public class TechnologiesView
{
public List<Technologies> Technologies { get; set; }
public Scores Scores { get; set; }
}
Controller :
public ActionResult Page2()
{
TechnologiesView allTechs = new TechnologiesView();
allTechs.Technologies = db.Technologies.ToList();
return View(allTechs);
}
View:
#model TechnologiesView
#{
ViewBag.Title = "Page2";
}
<style>
#lang {
font-size: 15px;
color: gray;
}
#tech {
font-size: 13px;
color: gray;
}
</style>
<div class="container">
<div class="row col-xs-12 bilgi" style="color:black">
#HelperMethods.Title("Kendini Skorla!")
<br />
<i>Bilgi Düzeyini 0 ile 5 puan arasında notlar mısın? (0=Hiç 5= İleri Seviye)</i>
</div>
</div>
<hr />
#using (Html.BeginForm())
{
<div class="container-fluid" style="padding-left:50px; margin:0px">
<div class="row" id="lang">
#foreach (Technologies techs in Model.Technologies)
{
if (techs.type == "lang")
{
<div class="col-md-1 col-sm-2 col-xs-6">
#(techs.technologyName)
</div>
<div class="col-md-1 col-sm-2 col-xs-6">
(#(Html.TextBoxFor(x => x.Scores.score, new
{
id = techs.ID,
name = "techID",
style = "display:inline; width:20px; height:20px; font-size:smaller; padding:0px; text-align:center",
#class = "form-control"
})))
</div>
}
}
</div>
<hr style="color:black" />
<div class="row" id="tech">
#foreach (Technologies techs in Model.Technologies)
{
if (techs.type == "tech")
{
<div class="col-md-1 col-sm-2 col-xs-6" id="tech">
#(techs.technologyName)
</div>
<div class="col-md-1 col-sm-2 col-xs-6">
#Html.HiddenFor(x=>techs.ID)
(#(Html.TextBoxFor(x => x.Scores.score, new
{
id = techs.ID,
name = "techID",
style = "display:inline; width:20px; height:20px; font-size:smaller; padding:0px; text-align:center",
#class = "form-control"
})))
</div>
}
}
</div>
<hr />
<div class="row col-xs-12" id="lang">
<span>Kullandığınız IDE’ler (yazınız)</span>
<br />
<div style="margin-bottom:10px; text-align:center">
#HelperMethods.TextArea("Ide", 3)
</div>
</div>
<div style="text-align:right; margin-bottom:10px">
#HelperMethods.Button("btnPage2")
</div>
</div>
}
Now user has to give a score to him/herself for every technologies or languages and after this i want to when user click to button "Follow the next page(it's turkish)" i will select the last saved user from maxID value in Testers and i have to connect scores with technologies and testers but i don't know how can i get textboxes' values and which technology's value is this value on post :D
You generating form controls which have no relationship at all to your model (which is also wrong anyway). Never attempt to change the name attribute when using the HtmlHelper methods (and there is no reason to change the id attribute either)
Next, you cannot use a foreach loop to generate form controls for a collection. You need a for loop or EditorTemplate to generate the correct name attributes with indexers. Refer this answer for a detailed explanation.
Then you cannot use a if block inside the loop (unless you include a hidden input for the collection indexer), because by default the DefaultModelBinder required collection indexers to start at zero and be consecutive.
First start by creating view models to represent what your want to display/edit in the view.
public class ScoreVM
{
public int ID { get; set; }
public string Name { get; set; }
public int Score { get; set; }
}
public class TechnologiesVM
{
public List<ScoreVM> Languages { get; set; }
public List<ScoreVM> Technologies { get; set; }
public string Notes { get; set; } // for your textarea control
}
Note you will probably want to add validation attributes such as a [Range] attribute for the Score property
In the GET method, initialize and populate your view model and pass it to the view
public ActionResult Page2()
{
IEnumerable<Technologies> technologies = db.Technologies;
TechnologiesVM model = new TechnologiesVM
{
Languages = technologies.Where(x => x.type == "lang")
.Select(x => new ScoreVM{ ID = x.ID, Name = x.technologyName }).ToList(),
Technologies = technologies.Where(x => x.type == "tech")
.Select(x => new ScoreVM{ ID = x.ID, Name = x.technologyName }).ToList(),
};
return View(model);
}
and in the view
#model TechnologiesVM
....
#using (Html.BeginForm())
{
....
#for (int i = 0; i < Model.Languages.Count; i++)
{
#Html.HiddenFor(m => m.Languages[i].ID)
#Html.HiddenFor(m => m.Languages[i].Name)
#Html.LabelFor(m => m.Languages[i].Score, Model.Languages[i].Name)
#Html.TextBoxFor(m => m.Languages[i].Score)
#Html.ValidationMessageFor(m => m.Languages[i].Score)
}
#for (int i = 0; i < Model.Languages.Count; i++)
{
.... // repeat above
}
#Html.LabelFor(m => m.Notes)
#Html.TextAreaFor(m => m.Notes)
#Html.ValidationMessageFor(m => m.Notes)
<input type="submit" />
}
and the POST method will be
public ActionResult Page2(TechnologiesVM model)
{
if (!ModelState.IsValid)
{
return View(model);
}
... // save the data and redirect
}

MVC Razor - Hierarchy / Nested IList of Checkboxes Posting with Count = 0

I am trying to post back the changes to the nested list of checkboxes for Groups and their Users but keep getting my list Count = 0 when it posts. Right now, there are no groups within groups, but I would still like to make this recursive if we move towards that in the future.
I have a hierarchical IList of GroupsUsers attached to my Activity Model as such:
Activity:
public class Activity
{
public int ActivityId { get; set; }
public string Name { get; set; }
public string Path { get; set; }
public string Description { get; set; }
public Nullable<int> ParentId { get; set; }
public IList<GroupsUsers> Hierarchy { get; set; }
}
GroupsUsers:
public class GroupsUsers
{
public Guid? Guid { get; set; }
public string Name { get; set; }
public bool IsAllowed { get; set; } = false;
public IList<GroupsUsers> Children { get; set; } = new List<GroupsUsers>();
}
I have tried EditorFor, Partial View, and Helper but am having no luck with any of them posting back the Hierarchy. My Model.Hierarchy is posting back with Count = 0.
Here's my current attempt:
Main View (watered down):
#model MyProject.Models.Activity
#using (Html.BeginForm())
{
<!-- Activity stuff -->
<ul style="list-style:none;">
#for (var i = 0; i < Model.Hierarchy.Count(); i++)
{
#Html.EditorFor(model => model.Hierarchy[i])
}
</ul>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
}
Current Attempt. GroupsUsers.cshtml:
#model MyProject.Models.GroupsUsers
<li>
#Html.HiddenFor(model => model.Guid)
#Html.HiddenFor(model => model.Name)
#Html.CheckBoxFor(model => model.IsAllowed, new { #class = "groupsusers-checkbox", #style = "margin-right:5px; cursor:pointer;", #value = Model.Guid.ToString() }) #Html.LabelFor(model => model.IsAllowed, Model.Name, new { #class = "build-checkbox-label", #style = "font-weight:normal; margin-top:-2px;" })
#if (Model.Children.Any())
{
<ul style="list-style:none;">
#for (var i = 0; i < Model.Children.Count(); i++)
{
#Html.EditorFor(model => model.Children[i])
}
</ul>
}
</li>
I'm looking for my list of checkboxes to display as a list hierarchy recursively and post Model.Hierarchy back properly.
Any help would be appreciated... I only included Attempt #2 and #3 in case I was close to having it correct.

allow to select only one radiobutton

I have a survey with 6 questions. Each question will be rated between (1-5). I want to capture the value selected for each question. Only one value can be selected on each question
The following is allowing me to select more than one option for each question, I should restrict to select only one for each question. All the radio buttons should be grouped as one, and only one button can be selected. I should be able to capture the selected value for each when submitted.
public class SurveyViewModel
{
public GroupViewModel GroupA { get; set; }
public GroupViewModel GroupB { get; set; }
public GroupViewModel GroupC { get; set; }
public SurveyViewModel()
{
GroupA = new GroupViewModel();
GroupA.GroupName = "A";
GroupB = new GroupViewModel();
GroupB.GroupName = "B";
GroupC = new GroupViewModel();
GroupC.GroupName = "C";
}
}
public class GroupViewModel
{
public string GroupName { get; set; }
public bool radio1 { get; set; }
public bool radio2 { get; set; }
public bool radio3 { get; set; }
public bool radio4 { get; set; }
public bool radio5 { get; set; }
}
Editor Template:
<div>
<h4>GroupViewModel</h4>
<hr />
<dl class="dl-horizontal">
<dt>#Html.RadioButtonFor(model => model.radio1, true, new { id = Model.GroupName + "1" })</dt>
<dd>#Html.DisplayNameFor(model => model.radio1)</dd>
<dt>#Html.RadioButtonFor(model => model.radio2, true, new { id = Model.GroupName + "2" })</dt>
<dd>#Html.DisplayNameFor(model => model.radio2)</dd>
<dt>#Html.RadioButtonFor(model => model.radio3, true, new { id = Model.GroupName + "3" })</dt>
<dd>#Html.DisplayNameFor(model => model.radio3)</dd>
<dt>#Html.RadioButtonFor(model => model.radio4, true, new { id = Model.GroupName + "4" })</dt>
<dd>#Html.DisplayNameFor(model => model.radio4)</dd>
<dt>#Html.RadioButtonFor(model => model.radio5, true, new { id = Model.GroupName + "5" })</dt>
<dd>#Html.DisplayNameFor(model => model.radio5)</dd>
</dl>
</div>
and the survey View as follows:
#using (Html.BeginForm())
{
#Html.EditorFor(m => m.GroupA)
#Html.EditorFor(m => m.GroupB)
#Html.EditorFor(m => m.GroupC)
<input type="submit" value="Continue" />
}
I have added a group name as posted below, but I could not able to capture the selected value in the http post
#Html.RadioButtonFor(model => model.radio1, true, new { id = Model.GroupName + "1", #Name = Model.GroupName })
You have to override the name attribute:
#Html.RadioButtonFor(model => model.radio1, true, new { id = Model.GroupName + "1", #Name = "Group" })
You have to do this for every radiobutton that you want to have only one selection.
When you use Html.RadioButtonFor it expected that you use the same property to bind all radio buttons like:
#Html.RadioButtonFor(model => model.radio, "answer1")
#Html.RadioButtonFor(model => model.radio, "answer2")
#Html.RadioButtonFor(model => model.radio, "answer3")
Or using an Enumeration in place of "answer1", "answer2" and "answer3"
Each radio button you generating if for a different property and has a different name (they are not grouped) so all radio buttons within a 'Question' can be selected, and worse, none of then can be unselected once selected.
In addition your properties within SurveyViewModel are all the same type, so you should be using a collection property, not generating individual properties for each item.
Start by creating a view model which represents what you want to display/edit in the view.
public class QuestionVM
{
public string Name { get; set; }
[Required(ErrorMesage = "Please select a rating")]
public int? Rating { get; set; }
}
and in the controller GET method
List<QuestionVM> model = new List<QuestionVM>()
{
new QuestionVM() { Name = "A" },
new QuestionVM() { Name = "B" },
new QuestionVM() { Name = "C", Rating = 3 } // use this if you want to pre-select a radio button
};
return View(model);
Next, create an EditorTemplate for QuestionVM. The templates needs to be named /Views/Shared/EditorTemplates/QuestionVM.cshtml
#model QuestionVM
<div class="question">
#Html.HiddenFor(m => m.Name) // so this value posts back
<h2>#Model.Name</h2>
#for(int i = 1; i < 6; i++)
{
<label>
#Html.RadioButtonFor(m => m.Rating, i, new { id = "" })// remove id attribute to prevent invalid html
<span>#i</span>
</label>
}
#Html.ValidationMessageFor(m => m.Rating)
</div>
and finally in the main view
#model IEnumerable<QuestionVM>
#using (Html.BeginForm())
{
#Html.EditorFor(m => m)
<input type="submit" value="Save" />
}
which will post back to
public ActionResult Edit(IEnumerable<QuestionVM model) // adjust method name to suit

On posting to server all collections of complex types are null in mvc

I'm fairly new to MVC but am progressing.
I have come across an issue that I can't seem to solve and would be greatful of any assistance.
When I post to the server my edits (in RoutineViewModel) are mostly lost, primitive data types are persisted (in class Routine) but collections of complex types (ICollection<RoutineExercise>) are lost.
I found this MVC Form not able to post List of objects and followed the advice to seperate the view into an EditorTemplate but this has not worked. Using the '#foreach' loop still produces all the page controls with the same id and name when you viewsource. I tried using a for (int i = 1; i <= 5; i++) type loop as many other posts suggest but get errors about not being able to apply index to my object.
Also the fact this #Html.DropDownListFor(model => Model.ExerciseId, Model.Exercises, "", new { #class = "input-sm col-md-12" }) does not select the correct list item (Model.ExerciseId has the correct value) concerns me.
Any help/advice would be great as I'm stuck and have been for 3 days now.
* POCO *
public partial class Routine
{
public Routine()
{
this.RoutineExercises = new List<RoutineExercise>();
}
public int Id { get; set; }
public string RoutineName { get; set; }
public string Description { get; set; }
...Other fields removed for clarity...
public virtual ICollection<RoutineExercise> RoutineExercises { get; set; }
}
public partial class RoutineExercise
{
public int Id { get; set; }
public int RoutineId { get; set; }
public int Exerciseid { get; set; }
public int SetsToDo { get; set; }
public int RepsToDo { get; set; }
...Other fields removed for clarity...
public virtual Exercise Exercise { get; set; }
public virtual Routine Routine { get; set; }
}
* VIEWMODEL *
public class RoutineViewModel
{
//Routine information
public int Id { get; set; }
[Display(Name = "Name")]
public string RoutineName { get; set; }
public string Description { get; set; }
//Exercise information
[Display(Name = "Exercise")]
public ICollection<RoutineExercise> RoutineExercises { get; set; }
public IEnumerable<SelectListItem> Exercises { get; set; }
public int ExerciseId { get; set; }
}
* FORM *
<div class="panel-body">
#using (Html.BeginForm("Edit", "Workout"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.Id)
#Html.EditorForModel()
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
</div>
* EDITOR TEMPLATE *
<div class="form-group">
#Html.LabelFor(model => model.RoutineName, new { #class = "control-label col-md-1" })
<div class="col-md-2">
#Html.EditorFor(model => model.RoutineName)
#Html.ValidationMessageFor(model => model.RoutineName)
</div>
#Html.LabelFor(model => model.Description, new { #class = "control-label col-md-1" })
<div class="col-md-2">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
</div>
#foreach (var e in Model.RoutineExercises)
{
#Html.LabelFor(model => model.RoutineExercises, new { #class = "control-label col-md-1" })
<div class="col-md-3">
#*TO FIX This does NOT bind the selected value*#
#Html.DropDownListFor(model => Model.ExerciseId, Model.Exercises, "", new { #class = "input-sm col-md-12" })
</div>
<div class="col-md-12">
#Html.LabelFor(model => e.SetsToDo, new { #class = "control-label col-md-2" })
#Html.EditorFor(m => e.SetsToDo, new { #class = "control-label col-md-10" })
</div>
}
* CONTROLLER *
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(RoutineViewModel rvm) /*rvm always null for collections only*/
{
if (ModelState.IsValid)
{
//Save Routine
var r = new Routine
{
Id = rvm.Id,
RoutineName = rvm.RoutineName,
Description = rvm.Description,
RoutineFrequencyId = rvm.RoutineFrequencyId,
RoutineLengthId = rvm.RoutineLengthId
};
_repo.Update(r);
return RedirectToAction("Index");
}
return View(getRoutineViewModel(rvm.Id));
}
First, avoid the term "complex type" unless you're actually talking about a complex type in Entity Framework. It just creates confusion, and honestly, nothing you have here is really "complex" anyways.
You will indeed need to employ a for loop with an index instead of foreach to get the proper field names for the modelbinder to work with. However, the reason you're getting an error is that ICollection is not subscriptable ([N]). You can use ElementAt(N) to pull out the item at an index, but unfortunately, Razor will still not create the right field names with that. As a result, you need to use something like List for your collection properties to edit them inline. Since you're already using a view model this is trivial. Just change the property type from ICollection<RoutineExcercise> to List<RoutineExcercise> on your view model.

Resources