【问题标题】:Using two models for one view in MVC, one to get data, another one to send data to controller在 MVC 中为一个视图使用两种模型,一种用于获取数据,另一种用于向控制器发送数据
【发布时间】:2019-09-27 23:00:10
【问题描述】:

我知道一个视图只能有一个模型,所以我将这两个模型放在一个文件 SurveyForm.xml 中。如何获取结果、已回答的问题并将其发送给控制器?

public class SurveyForm
    {
        public List<Question> SurveyQuestions { get; set; }
        public List<Answer> SurveyResults { get; set; }
    }

public class Question
    {
        public int Id { get; set; }
        public int? ParentID { get; set; }
        public string Text { get; set; }        
        public List<Response> Responses { get; set; }
        public List<Question> SubQuestions { get; set; }
        public string RenderType { get; set; }
    }

public class Answer
    {
        public int ResponseID { get; 
        public string Value { get; set; }
    }

我通过问题循环呈现问题,有一些子问题,所以我有嵌套循环(三层循环)。我能够提出这些问题,但获得结果对我来说并不容易。如果我制作一个由问题和答案列表组成的 SurveyForm 模型,如何为列表中的每个 Result 项目设置 ResponseID 和 Value?使用 for 循环将不起作用,因为有 20 个响应,但有 7 个问题和 13 个子问题。

这是我正在渲染的视图的一部分:

@model MyApp.Models.SurveyForm
@{
    ViewBag.Title = "Survey";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@using (Html.BeginForm("SubmitForm", "Survey"))
{
    int orderNumber = 1;
    foreach (var item in Model.SurveyQuestions)
    {
        <div> @(orderNumber++)) &nbsp; @item.Text </div> //just a title of the question
        if (item.RenderType == "Radiobutton")
        {
            <div>
                @foreach (var subitem in item.Responses)
                {
                    <div>
                        @Html.RadioButton(subitem.QuestionID.ToString(), subitem.ResponseID)
                        @Html.Label(subitem.Text)
                    </div>
                }
            </div>
            <div @Html.TextArea(item.SubQuestions.FirstOrDefault().Answers.FirstOrDefault().ResponseID.ToString(), null, new { @class = "form-control" })</div>
        }

        if (item.RenderType == "Textbox")
        {
            <div>
                @Html.TextArea(item.Id.ToString(), null, new { @class = "form-control" })
            </div>
        }
    }
}

【问题讨论】:

    标签: asp.net-mvc asp.net-core


    【解决方案1】:

    我认为这里有两点:

    1. 回发到服务器时,您不必使用与设置页面时相同的模型。即,您可以将List&lt;Question&gt; 的模型传递给您的视图,您可以循环该模型以构建 HTML。然后在您的 POST 控制器方法 (SubmitForm) 中,可以有如下签名

    这可能有助于简化您的模型对象,但不是必需的。

    public async Task<IActionResult> SubmitForm(List<Answer> model) 
    {
    
    }
    

    2。 为了将 HTML 中的项目列表绑定到对象,您需要为 html 元素的 name 属性赋予一个“索引”值,该值表示列表中项目的索引,位于对象名称之后,因此它会像 "Answer[index].ResponseId",其中 Answer 是您尝试绑定的对象的名称。

    您的 HTML 可以是这样的:

    for(int i =0; i < Model.SurveyQuestions; i++)
    {
        var item = Model.SurveyQuestions[i];
    
    if (item.RenderType == "Textbox")
        {
            <div>
    
                <textarea name="SurveyResults[i].ResponseID" value="@item.Id.ToString()" class = "form-control" >
            </div>
        }
    }
    

    看看这个类似的问题我answered previously

    希望这能为您指明正确的方向。

    【讨论】:

    • 在视图中无法访问调查结果。 for (int i = 0; i m[i].) /// 这里 m 是问题对象,不是结果 }
    • @HomeMade 你已经标记了 asp.net-core,所以你在使用它吗?或者这是 MVC 5? .net 核心已将 Html 助手替换为标签助手。它们具有不同的语法,看起来更像普通的 html,并且与我的示例非常相似。我认为您不能将标准 Html 助手与绑定列表一起使用,因为开箱即用它们不会为列表的 name 属性添加索引,因此我认为无论哪种方式您都需要更改 Html 以不使用标签助手, 然后给它一个像我的例子一样的名字将允许它正确绑定
    • 既然你提到了它,它是 MVC 5,不知道这是两个不同的东西。
    • @HomeMade,好吧,在那种情况下,我认为你不能使用一种默认的 Html 辅助方法来做到这一点。如果您需要绑定到子列表,那么您必须按照我提到的那样进行命名并执行name="SurveyForm.SurveyResults[i].[k].ResonseID 之类的操作。您显然失去了 Html 的强类型化方面,但除非构建一些,否则我会认为这是相当复杂的自定义 html 助手,我不知道另一种方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2019-01-10
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多