无法从基于行的元素

时间:2017-04-17 14:17:22

标签: c# asp.net-mvc razor

我正在进行"调查"在MVC中的应用5.基本上它是一个支持用户填写调查的应用程序。用户也可以在以后的任何时间返回并更改他们的答案。

用户界面:我有一个表格,每行包含实际的调查问题,答案(是/否/ N-A,来自下拉列表)和基于行的评论。他们的答案(下拉列表选择)和每行的评论应该是提交给操作的POST变量。

问题:我在获取任何后置变量时遇到问题,这些变量始终为空。这是我的一些代码...

ViewModel(SurveyResultsViewModel.cs)

[NotMapped]
public class SurveyResultsViewModel
{
    // ------ hidden
    [Key]
    public int EventId { get; set; }

    [Display(Name = "Category")]
    public string SurveyCategory { get; set; }

    [Display(Name = "Question")]
    public string SurveyQuestionText { get; set; }
    public int SurveyQuestionId { get; set; }

    public SelectList SurveyAnswerOption { get; set; }
    public int SurveyResultsId { get; set; }
    [Display(Name = "Answer")]
    public string SelectedSurveyAnswer { get; set; }

    public string Comments { get; set; }
}

控制器GET ......

 public ActionResult Index(int id)
    {
        :
        :
        :
        List<SurveyResultsViewModel> vm = new List<SurveyResultsViewModel>();

        var Surveyresults = db.SurveyResults
            .Where(i => i.EventId == id)
            .Include(a => a.SurveyQuestion)
            .OrderBy(a=>a.SurveyQuestion.SurveyQuestionCategory.Id)
            .Include(a => a.Event);

        foreach (SurveyResult ar in Surveyresults)
        {
            var newVmRecord = new SurveyResultsViewModel();

            newVmRecord.EventId = id;
            newVmRecord.SurveyAnswerOption = new SelectList(db.SurveyAnswerOptions, "AnswerOptionText", "AnswerOptionText", ar.SurveyAnswer);
            newVmRecord.SurveyCategory = ar.SurveyQuestion.SurveyQuestionCategory.SurveyQuestionCategory1;
            newVmRecord.SurveyQuestionId = ar.SurveyQuestionId.Value;
            newVmRecord.SurveyQuestionText = ar.SurveyQuestion.SurveyQuestionText;
            newVmRecord.Comments = ar.Comments;
            newVmRecord.SelectedSurveyAnswer = ar.SurveyAnswer;
            newVmRecord.SurveyResultsId = ar.Id;

            vm.Add(newVmRecord);
        }

        return View(vm.ToList());
    }

这是我观点的一部分......

      @model IEnumerable<SurveyApp.ViewModels.SurveyResultsViewModel>
      :
      :
           <div class="ibox-content">
            @using (Html.BeginForm())
            {
                @Html.AntiForgeryToken()
                <table class="table table-striped">
                    <tr>
                        <th class="col-md-2">
                            @Html.DisplayNameFor(model => model.SurveyCategory)
                        </th>
                        <th class="col-md-5">
                            @Html.DisplayNameFor(model => model.SurveyQuestionText)
                        </th>
                        <th>
                            @Html.DisplayNameFor(model => model.SelectedSurveyAnswer)
                        </th>
                        <th>
                            @Html.DisplayNameFor(model => model.Comments)
                        </th>
                    </tr>
                    @{
                        int i = 0;
                    }
                    @foreach (var item in Model)
                    {
                        <tr>

                            <td>
                                @Html.DisplayFor(modelItem => item.SurveyCategory)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.SurveyQuestionText)
                            </td>
                            <td>
                                @Html.TextBoxFor(modelItem => item.SelectedSurveyAnswer)
                                @Html.DropDownListFor(modelItem => item.SelectedSurveyAnswer, item.SurveyAnswerOption, "--Select--")
                            </td>

                            <td>
                                @Html.HiddenFor(modelItem => item.SurveyResultsId)
                                @Html.TextAreaFor(modelItem => item.Comments)
                            </td>
                        </tr>
                        i++;
                    }
                </table>
                <input type="submit" value="Save" class="btn btn-primary"/>
                @Html.ActionLink("Cancel", "Index", null, new {@class = "btn btn-white"})
            }
        </div>

视图似乎正确显示。但是,当我查看源代码时,我注意到,在呈现时,没有为&#34; post&#34;相关控件提供唯一的NAME值。我认为这可能导致了这个问题?例如,这里是其中一个下拉列表的渲染....

 <select id="item_SelectedSurveyAnswer" name="item.SelectedSurveyAnswer">
     <option value="">--Select--</option>
     <option selected="selected" value="Yes">Yes</option>
     <option value="No">No</option>
     <option value="N/A">N/A</option>
 </select>

这是我的初步POST方法。 var mySurveyResult始终为NULL ...

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Index(
        //[Bind(Include = "SurveyResultsId,SelectedSurveyAnswer,Comments")]
        List<SurveyResultsViewModel> mySurveyResult)
    {
        if (ModelState.IsValid)
        {
            for (int i = 0; i < mySurveyResult.Count(); i++)
            {
                Console.WriteLine(mySurveyResult[i].SelectedSurveyAnswer);
            }

            db.Entry(mySurveyResult).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View();
    }

正如您所看到的,我还没有完全编写这种方法。但是,基本上,这个后期操作需要遍历每个发布的答案并将其保存到数据库中。我还没到那么远,因为我继续为post参数获取null。

同样,我认为问题可能是没有唯一的名称属性可能?也许这会影响POST?对于任何反馈,我们都表示感谢。另外,如果您(从我发布的代码示例中)看到我没有正确处理,请告诉我。

请让我提前谢谢你!

1 个答案:

答案 0 :(得分:1)

您需要使用for而不是foreach来迭代您的商品:

@for (var i = 0; i < Model.Count(); i++)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => Model[i].SurveyCategory)
        </td>
        <td>
            @Html.DisplayFor(modelItem => Model[i].SurveyQuestionText)
        </td>
        <td>
            @Html.TextBoxFor(modelItem => Model[i].SelectedSurveyAnswer)
            @Html.DropDownListFor(modelItem => Model[i].SelectedSurveyAnswer, Model[i].SurveyAnswerOption, "--Select--")
        </td>
        <td>
            @Html.HiddenFor(modelItem => Model[i].SurveyResultsId)
            @Html.TextAreaFor(modelItem => Model[i].Comments)
        </td>
    </tr>
}

这会为您的字段命名为[0].SelectedSurveyAnswer,而不仅仅是SelectedSurveyAnswer,从而允许模型绑定器实际上能够将发布的值绑定回列表。