模型在Child Partial页面MVC5上的帖子上为空

我试图在用户填写表单后获取所有数据,但是当我尝试访问模型作为操作参数时,我总是将模型作为空值。 因此,我尝试使用FormCollection,但仍然无法计算如何访问埋在QuestionModel内的PossibleAnswerModel的列表。 非常感激你的帮助

UPDATE

在阅读Chris Pratt评论后,我将所有内容都更新为以下内容但我仍然无法获得TestModel的填充。 每次问题(TestModel测试,FormCollection formCollection)做POST索引操作得到调用我甚至尝试把一个[HttpPost]公共ActionResult问题(TestModel测试,FormCollection formCollection),但没有得到填充视图数据。 请帮忙

///////////////楷模//////////////

 [Serializable]
    public class TestModel
    {
        private QuestionModel _currenQuestionModel;

        public int TestID { get; set; }
        public string TestName { get; set; }

        public string Instructions { get; set; }

        public double TestTime { get; set; }

        public QuestionModel CurrenQuestionModel
        {
            get
            {
                if (_currenQuestionModel == null &&
                    Questions != null && 
                    Questions.Count > 0)
                    _currenQuestionModel = Questions.First();

                return _currenQuestionModel;
            }
            set { _currenQuestionModel = value; }
        }

        public List<QuestionModel> Questions { get; set; }
    }

    public class QuestionModel
    {
        public int QuestionID { get; set; }
        public string Question { get; set; }
        public bool HasMultipleAnswers { get; set; }
        public IList<PossibleAnswerModel> PossibleAnswers { get; set; }   
    }

    public class PossibleAnswerModel
    {
        public bool IsSelected { get; set; }
        public string DisplayText { get; set; }
    }
}

//////////////////控制器/////////////////

 public class TestController : Controller
        {
            public ActionResult Index(int id)
            {
                var model = _testColletion.FirstOrDefault(r => r.TestID == id);
                return View(model);
            }

            [ChildActionOnly]
            [HttpGet]
            public ActionResult Questions(TestModel test)
            {
                var testModel = _testColletion.Single(r => r.TestID == test.TestID);
                return PartialView("_Start", testModel);
            }

            [HttpPost]
            public ActionResult Questions(TestModel test, FormCollection formCollection)
            {
                var q = formCollection.Count >2 ?  formCollection.GetValues(1):null;
                var testModel = _testColletion.FirstOrDefault(r => r.TestID == test.TestID);

                //if (questionID == 0)
                //{
                //    testModel.CurrenQuestionModel = testModel.Questions.First();
                //}
                if (!string.IsNullOrWhiteSpace(Request["next"]))
                {
                    var nextQuestionIndex =
                        testModel.Questions.FindIndex(r => r.QuestionID == testModel.CurrenQuestionModel.QuestionID) + 1;
                    testModel.CurrenQuestionModel = testModel.Questions[nextQuestionIndex];
                }
                else if (!string.IsNullOrWhiteSpace(Request["prev"]))
                {
                    var prevQuestionIndex =
                       testModel.Questions.FindIndex(r => r.QuestionID == testModel.CurrenQuestionModel.QuestionID) - 1;

                    testModel.CurrenQuestionModel = testModel.Questions[prevQuestionIndex];
                }

                return PartialView("_Question", testModel);
            }
            private static List<TestModel> _testColletion = new List<TestModel>()
            {
                new TestModel()
                {
                    TestID = 1,
                    TestName = "ASP.NET",
                    Instructions = "Please choose from appropriate options",
                    TestTime = 2.40,
                     Questions = new List<QuestionModel>()
                    {
                        new QuestionModel(){QuestionID = 1, Question = "Question 1"}
                    }

                },
                new TestModel()
                {
                    TestID = 2,
                    TestName = "ASP.NET MVC",
                    Instructions = "Please choose from appropriate options",
                    TestTime = 1.00,
                    Questions = new List<QuestionModel>()
                    {
                        new QuestionModel(){QuestionID = 1, HasMultipleAnswers=true, Question = "Question 1", PossibleAnswers = new List<PossibleAnswerModel>()
                        {
                            new PossibleAnswerModel(){DisplayText = "Possible Answer 1"},
                            new PossibleAnswerModel(){DisplayText = "Possible Answer 2"},                   
                            new PossibleAnswerModel(){DisplayText = "Possible Answer 3"},   
                            new PossibleAnswerModel(){DisplayText = "Possible Answer 4"},   
                        }},
                        new QuestionModel(){QuestionID = 2, HasMultipleAnswers=true, Question = "Question 2"},
                        new QuestionModel(){QuestionID = 3, HasMultipleAnswers=true, Question = "Question 3"},
                        new QuestionModel(){QuestionID = 4, HasMultipleAnswers=true, Question = "Question 4"},
                        new QuestionModel(){QuestionID = 5, HasMultipleAnswers=true, Question = "Question 5"},
                    }
                },
                new TestModel()
                {
                    TestID = 3,
                    TestName = "ASP.NET Spring",
                    Instructions = "Please choose from appropriate options",
                    TestTime = 1.00,
                     Questions = new List<QuestionModel>()
                    {
                        new QuestionModel(){QuestionID = 1, Question = "Question 1"},
                        new QuestionModel(){QuestionID = 2, Question = "Question 2"},
                        new QuestionModel(){QuestionID = 3, Question = "Question 3"},
                        new QuestionModel(){QuestionID = 4, Question = "Question 4"},
                    }
                },
                new TestModel()
                {
                    TestID = 4,
                    TestName = ".NET C#",
                    Instructions = "Please choose from appropriate options",
                    TestTime = 4.40,
                     Questions = new List<QuestionModel>()
                    {
                        new QuestionModel(){QuestionID = 1, Question = "Question 1"},
                        new QuestionModel(){QuestionID = 2, Question = "Question 2"}
                    }
                }
            };
        }

///////////里面_Question.cshtml局部视图///////////////

@model InterviewQ.MVC.Models.TestModel

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    @*@Html.HiddenFor(r => r.CurrentQuestionID)*@
    <div>
        <br />
        <h4>Question @Model.CurrenQuestionModel.QuestionID</h4>
        <hr />
        <p>@Model.CurrenQuestionModel.Question</p>
    </div>
    <p>
     @if (Model.CurrenQuestionModel.HasMultipleAnswers)
     {
         @Html.Partial("_MultipleAnswerQuestionView", Model.CurrenQuestionModel)
     }
    </p>
    <p>
        @if (Model.CurrenQuestionModel.QuestionID > 0 && Model.CurrenQuestionModel.QuestionID < Model.Questions.Count)
        {
            if (Model.CurrenQuestionModel.QuestionID > 1)
            {
                <input type="submit" class="btn btn-default" value="Previous" name="prev" />
            }

            <input type="submit" class="btn btn-default" value="Next" name="next" />
        }
        @if (Model.CurrenQuestionModel.QuestionID == Model.Questions.Count)
        {
            <input type="submit" class="btn btn-default" value="Finish" name="finish" />
        }
    </p>
}

////////////里面_MultipleAnswerQuestionView.cshtml局部视图///////////////

@model InterviewQ.MVC.Models.QuestionModel

@if (!Model.HasMultipleAnswers)
{
    throw new InvalidOperationException("This answer optioin template doesn't support this type of questions");
}

@for(var i=0; i< Model.PossibleAnswers.Count; i++)
{ 
<div class="row">
    <div class="col-lg-6">
        <div class="input-group">
            <span class="input-group-addon">
                <input type="checkbox" value="@Model.PossibleAnswers[i].IsSelected" name="possibleAnswers">
            </span>
            <p>
                @Model.PossibleAnswers[i].DisplayText
            </p>
        </div><!-- /input-group -->
    </div><!-- /.col-lg-6 -->
</div><!-- /.row -->
}

但我仍然无法获得@ Model.PossibleAnswers [i]在帖子中的价值,我错过了任何事情


问题是您的发布数据都不匹配模型上的任何内容。 举几个例子:

  • 当你取出CurrentQuestion ,它将从Model.Questions的上下文中Model.Questions ,所以生成的字段名称将以CurrentQuestion开头,而不是Questions[N] ,其中N是该问题的索引。 马上就没有办法填充这个Questions属性,并且你的模型没有CurrentQuestion属性来绑定数据。

  • 当你将CurrentQuestion传递给你的部分时,你甚至会松开这个上下文,所以现在你所有的部分字段名都没有前缀。 例如,像Html.TextBoxFor(m => m.Foo)这样的名称最终只有Foo的名称,它的名称与模型的结构不匹配。

  • 然后,在你的部分内部,你正在使用一个抛弃了更多上下文的foreach 。 在迭代Model.PossibleAnswers每个字段名称最终会像item.IsSelected一样,而不是像item.IsSelected PossibleAnswers[N].IsSelected那样实际使用的东西,其中N是PossibleAnswers项目的索引。

  • 除此之外,您的复选框甚至没有名称属性。 所以永远不会发布任何价值。 期。

  • 总而言之,您最好回传字段名称,模型绑定者无法匹配模型上的任何内容,最糟糕的是,在某些情况下,您根本没有发布任何内容。 难怪你得到一个空模型。

    在任何时候,您都必须维护属性上下文,以便Razor可以生成模型绑定器可以使用的字段名称。 因此,不应传递CurrentQuestion ,而应将Model.Questions[N]传递给partial。 当遍历将有可编辑字段的列表时,您需要使用for而不是foreach ,以便您可以传递索引属性以给Razor提供所需的上下文: Model.PossibleAnswers[N].IsSelected

    链接地址: http://www.djcxy.com/p/53971.html

    上一篇: Model is getting null on post on Child Partial page MVC5

    下一篇: How to return a list to the controller based on checkbox checked?