MVC 5动态数据表 - 未向控制器发布的模型列表

时间:2014-03-07 02:10:30

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

好的,这让我疯了。有时候我发现MVC让我在树林里迷失方向,开始向错误的道路前进,一切都变得地狱。所以我伸出手来看看是否有一双新眼睛指向正确的方向。

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

  

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

     

名称: _ __ _ __ _ 地址: _ __ _ 城市: _ __ 状态:__ Zip: _

因此,如果客户只有一个位置,它将是一个带有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 });
    }

1 个答案:

答案 0 :(得分:4)

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

此...

 @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个小时让自己疯狂...... arrrrgggghhh!