我正在开发我的第一个.NET MVC项目,我希望我的表单可以在锻炼中循环练习循环(可以是任意数量的练习)。我有一个foreach循环,一切似乎都运行正常,但是当我检查数据库时,它只采用了第一个练习的条目,并将其应用于所有条目。我不确定我搞砸了什么,或者误解了我的问题。任何关于正确方向的建议都将受到高度赞赏。
查看:
@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>
视图模型:
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() { }
}
}
控制器:
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);
}
}
答案 0 :(得分:1)
问题是隐藏输入的名称都是一样的。当控制器收到它时,它将被视为您只有一个字段要提交。
如果您想从表单提交多个收集字段。
您可以将@Html.HiddenFor
与 For Loop
@model WorkoutGenerator.ViewModels.AddRecordViewModel
<h1>Add Exercise Record</h1>
<form asp-controller="Record" asp-action="Add" method="post">
@for (int i = 0; i < Model.Exercises.Count(); i++)
{
<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>o.exercise.ExerciseID
@Html.HiddenFor(o=>Model.Exercises[i].ExerciseID)
@Html.HiddenFor(o=>Model.Exercises[i].WorkoutID)
@Html.HiddenFor(o=>Model.Exercises[i].OwnerId)
}
<input type="submit" value="Add Exercise Record" />
</form>
或者您可以像这样使用
@model WorkoutGenerator.ViewModels.AddRecordViewModel
@{
int i = 0;
}
<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[@i]" value="@exercise.ExerciseID" />
<input type="hidden" name="WorkoutID[@i]" value="@exercise.WorkoutID" />
<input type="hidden" name="OwnerID[@i]" value="@exercise.OwnerId" />
@i++;
}
<input type="submit" value="Add Exercise Record" />
</form>
然后输入的名称将显示为name="ExerciseID[0]"
,name="ExerciseID[1]"
...