.NET MVC Post表单只接收foreach循环的第一次迭代

时间:2018-04-02 03:44:56

标签: asp.net asp.net-mvc

我正在开发我的第一个.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);
            }
        }

1 个答案:

答案 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]" ...