【问题标题】:MVC 5 Dynamic Data Form - List of Model Not Posting to ControllerMVC 5 动态数据表单 - 未发布到控制器的模型列表
【发布时间】:2014-03-07 02:10:30
【问题描述】:

好吧,这让我发疯了。有时我发现使用 MVC 我有点迷失在树林里,开始寻找错误的道路,一切都下地狱了。所以我伸出手来看看是否有一双新的眼睛会指引我正确的方向。

基本上,该结构允许管理员创建自己的问题,这本身非常简单,但在这种情况下,它不仅仅是一个“单一”的答案框。示例:

您的营业地点的名称和地址是什么?

姓名:_______ 地址:____ 城市:___ 州:__ 邮编:_强>

因此,如果客户只有一个位置,则答案将包含 5 个文本框(姓名、地址、城市、州、邮编)...但由于问题是动态创建的,它可能是 3 个文本框,1, 2等

所以我遇到的问题是当模型被发布回控制器时,视图模型的问题部分很好,但它的答案/选择部分总是返回 null。请看一下是否有我明显忽略的巨大开关。

这是模型和视图模型:

public class Questions
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }
    public int FormID { get; set; }

    [Display(Name = "Question Order")]
    [Range(0, Int32.MaxValue, ErrorMessage = "Must Use an Integer")]
    public int QuestionOrder { get; set; }

    [Required]
    [DataType(DataType.MultilineText)]
    public string Question { get; set; }

    [Display(Name = "Help Text")]
    public string HelpText { get; set; }
    public bool IsActive { get; set; }

    [Display(Name = "Question May Have More Than One Entry")]
    public bool CanHaveMoreThanOne { get; set; }

    public int QuestionTypeID { get; set; }

}

public class Choices
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }
    public int QuestionID { get; set; }
    public string FieldName { get; set; }
    public string QuestionLabel { get; set; }
    public bool IsRequired { get; set; }
    public string RegEx { get; set; }
    public string TextIfSelected { get; set; }
    public string QuestionToSkipToIfSelected { get; set; }
    public bool IsActive { get; set; }

    [NotMapped]
    public string AnswerText { get; set; }
    [NotMapped]
    public bool AnswerBool { get; set; }
    [NotMapped]
    public int AnswerNumeric { get; set; }
    [NotMapped]
    public DateTime AnswerDate { get; set; }

}

public class ViewQuestion
{

    public Questions Question { get; set; }
    public IEnumerable<Choices> Answers { get; set; }

}

这是视图:

@using InterviewMaster.Models
@model ViewQuestion

@using (Html.BeginForm("AnswerQuestion","Interview", FormMethod.Post))
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
    @Html.HiddenFor(m => m.Question.CanHaveMoreThanOne)
    @Html.HiddenFor(m => m.Question.FormID)
    @Html.HiddenFor(m => m.Question.HelpText)
    @Html.HiddenFor(m => m.Question.ID)
    @Html.HiddenFor(m => m.Question.Question)
    @Html.HiddenFor(m => m.Question.QuestionOrder)
    @Html.HiddenFor(m => m.Question.QuestionTypeID)

    <h3>@Model.Question.Question</h3>
    <hr />

    @if (Model.Question.QuestionTypeID == 1) 
    {

        foreach(var o in Model.Answers) 
        {

            Html.RenderPartial("Partial1", o);   

        }
    }

    else if (Model.Question.QuestionTypeID == 2) 
    {
         //TO-DO: Make other types of answers such as radio buttons, checkboxes, etc.
    }

    <input type="submit" value="Create" class="btn btn-default" />
</div>
}

这是我正在使用的部分

@model InterviewMaster.Models.Choices


@using(Html.BeginCollectionItem("Choices"))
{
    @Html.HiddenFor(model => model.ID)
    @Html.HiddenFor(model => model.QuestionID)
    @Html.HiddenFor(model => model.FieldName)
    @Html.HiddenFor(model => model.QuestionLabel)
    @Html.HiddenFor(model => model.IsRequired)
    @Html.HiddenFor(model => model.RegEx)
    @Html.HiddenFor(model => model.TextIfSelected)
    @Html.HiddenFor(model => model.QuestionToSkipToIfSelected)
    @Html.HiddenFor(model => model.IsActive)

    @Html.HiddenFor(model => model.AnswerBool)
    @Html.HiddenFor(model => model.AnswerDate)
    @Html.HiddenFor(model => model.AnswerNumeric)

    <div class="form-group">
    <label>@Html.ValueFor(model => model.QuestionLabel)</label>
    @Html.TextBoxFor(model => model.AnswerText)
    </div>

}

最后但并非最不重要的是,收到此帖子的控制器:

    // POST: /Interview/AnswerQuestion
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult AnswerQuestion(ViewQuestion dto)
    {
        foreach(var answer in dto.Answers)
        {
            Console.Write("Answer:" + answer.AnswerText);
        }

        return RedirectToAction("ContinueInterview", new { OrderID = 1, OrderDetailID = 1, FormID = 1, QuestionID = 1 });
    }

【问题讨论】:

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


    【解决方案1】:

    好吧,对于那些有一天可能需要这个的人来说,这就是问题所在。

    这...

     @using(Html.BeginCollectionItem("Choices"))
    

    应该是这样的……

     @using(Html.BeginCollectionItem("dto.Answers"))
    

    在 Steven Sandersons 网站 (http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/) 上的示例中,它并没有真正涉及到像我这样的复杂示例(不是他的错……我的)

    我认为这是您正在编辑/查看的模型。相反,它是您发送回控制器的内容。对我来说太棒了。

    希望这对将来的某人有所帮助。这花了我大约 8 个小时让自己发疯......arrrrggggghhh!

    【讨论】:

      猜你喜欢
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-10
      • 1970-01-01
      • 2017-02-05
      • 1970-01-01
      相关资源
      最近更新 更多