I am working on my first .NET MVC project and I am to a point where I want my form to iterate through a loop of exercises in a workout (can be any number of exercises). I have a foreach loop, and everything seems to work out ok, but when I check the database, it took only the entries for the first exercise, and applies that to all the entries. I am not sure where I am messing up, or misunderstanding my issue. Any advice in the right direction would be greatly appreciated.
VIEW:
@model WorkoutGenerator.ViewModels.AddRecordViewModel
<h1>Add Exercise Record</h1>
<form asp-controller="Record" asp-action="Add" method="post">
@foreach (var exercise in Model.Exercises)
{
<h4>@exercise.Exercise.Name</h4>
<div class="form-group">
<label asp-for="@Model.Sets"></label>
<input class="form-control" asp-for="@Model.Sets" />
<span asp-validation-for="@Model.Sets"></span>
</div>
<div class="form-group">
<label asp-for="@Model.Reps"></label>
<input class="form-control" asp-for="@Model.Reps" />
<span asp-validation-for="@Model.Reps"></span>
</div>
<div class="form-group">
<label asp-for="@Model.Weight"></label>
<input class="form-control" asp-for="@Model.Weight" />
<span asp-validation-for="@Model.Weight"></span>
</div>
<input type="hidden" name="ExerciseID" value="@exercise.ExerciseID" />
<input type="hidden" name="WorkoutID" value="@exercise.WorkoutID" />
<input type="hidden" name="OwnerID" value="@exercise.Exercise.OwnerId" />
}
<input type="submit" value="Add Exercise Record" />
</form>
VIEWMODEL:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using WorkoutGenerator.Models;
namespace WorkoutGenerator.ViewModels
{
public class AddRecordViewModel
{
[Required(ErrorMessage = "Please enter number of sets")]
public string Sets { get; set; }
[Required(ErrorMessage = "Please enter number of reps")]
public string Reps { get; set; }
[Required(ErrorMessage = "Please enter amount of weight")]
public string Weight { get; set; }
//Date Created
public DateTime DateCreated { get; set; }
//Link to user
public string OwnerId { get; set; }
//Link to Exercise
public int ExerciseID { get; set; }
//Link to Workout
public int WorkoutID { get; set; }
public IList<ExerciseWorkout> Exercises { get; set; }
public Workout Workout { get; set; }
public AddRecordViewModel() { }
}
}
Controller:
public IActionResult Add(int id)
{//Create form for each exercise to have sets reps and weight to submit
//!!!!!!!!!!!!!!TAKEN FROM WORKOUT CONTROLLER!!!!!!!!! MAY NEED CHANGING!!!!!!!!!!!!!!!!
string user = User.Identity.Name;
ApplicationUser userLoggedIn = context.Users.Single(c => c.UserName == user);
List<ExerciseWorkout> exercises = context
.ExerciseWorkouts
.Include(item => item.Exercise)
.Where(cm => cm.WorkoutID == id && cm.Workout.OwnerId == userLoggedIn.Id)//cm.Workout.OwnerId == userLoggedIn.Id returns list of owner specific workouts
.ToList();
Workout workout = context.Workouts.Single(m => m.WorkoutID == id);
AddRecordViewModel viewModel = new AddRecordViewModel
{
Workout = workout,
Exercises = exercises
};
return View(viewModel);
}
[HttpPost]
public IActionResult Add(AddRecordViewModel addRecordViewModel, int id)
{//Create records of exercise sets reps and weights to be added to database.
if (ModelState.IsValid)
{
string user = User.Identity.Name;
ApplicationUser userLoggedIn = context.Users.Single(c => c.UserName == user);
//exercises hopefully returns list of exercises from 'int id' parameter,
//which can then be used to iterate over each exercise put into record table
List<ExerciseWorkout> exercises = context
.ExerciseWorkouts
.Include(item => item.Exercise)
.Where(cm => cm.WorkoutID == id && cm.Workout.OwnerId == userLoggedIn.Id)
.ToList();
foreach (var exercise in exercises)
{
Record newRecord = new Record
{
Sets = addRecordViewModel.Sets,
Reps = addRecordViewModel.Reps,
Weight = addRecordViewModel.Weight,
DateCreated = DateTime.Now,//TODO Make this show only day not time of day
OwnerId = userLoggedIn.Id,//TODO Not Sure if creation of newRecord is correct.
WorkoutID = addRecordViewModel.WorkoutID,
FK_ExerciseID = addRecordViewModel.ExerciseID//TODO ExerciseID not entering into table.
};
context.Records.Add(newRecord);
context.SaveChanges();
}
return Redirect("/Record/Index");
}
else
{
return View(addRecordViewModel);
}
}