模型在子部分页面MVC5上的帖子上获得空值
本文关键字:空值 MVC5 分页 模型 | 更新日期: 2023-09-27 18:16:36
我试图在用户填写表单后获得所有数据,但当我试图访问模型作为一个动作参数时,我总是得到模型为空。因此,我尝试使用FormCollection,但仍然无法弄清楚我如何才能访问可能的answermodels列表,埋藏在QuestionModel内部。非常感谢您的帮助
阅读Chris Pratt评论后,我更新了所有内容,但我仍然无法获得TestModel填充。每次问题(TestModel测试,FormCollection FormCollection)做POST索引动作被调用,我甚至试着放一个[HttpPost]公共actionresultquestions (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"}
}
}
};
}
///////////Inside _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。可能的答案[i]值在帖子我错过了任何东西
问题是您发布的数据与模型上的任何内容都不匹配。举几个例子:
-
当您拔出
CurrentQuestion
时,它将从Model.Questions
的上下文中删除,因此生成的字段名称将以CurrentQuestion
而不是Questions[N]
开头,其中N是该问题的索引。马上,没有办法填充Questions
属性,并且你的模型上没有CurrentQuestion
属性来绑定数据。 -
当您将
CurrentQuestion
传递到部分时,您甚至失去了这个上下文,所以现在部分中的所有字段名都没有前缀。例如,像Html.TextBoxFor(m => m.Foo)
这样的内容将以简单的Foo
的名称结束,这再次与您的模型结构不匹配。 -
然后,在您的部分中,您使用
foreach
,它丢弃了更多的上下文。当您遍历Model.PossibleAnswers
时,每个字段名最终会变成类似item.IsSelected
的东西,而不是模型绑定器实际可以使用的东西,比如PossibleAnswers[N].IsSelected
,这里N是PossibleAnswers
中项目的索引。 -
最重要的是,你的复选框甚至没有name属性。所以不会有价值。时期。
不管是长是短,你最好的结果是发布回字段名,模型绑定器没有办法匹配你模型上的任何东西,最坏的情况是,在某些情况下,你根本没有发布任何东西。难怪你得到一个空模型。
在任何时候,您都必须维护属性上下文,以便Razor能够生成模型绑定器可以使用的字段名。因此,您应该将Model.Questions[N]
传递给partial,而不是传递CurrentQuestion
。当迭代具有可编辑字段的列表时,你需要使用for
而不是foreach
,这样你就可以传递索引属性给Razor所需的上下文:Model.PossibleAnswers[N].IsSelected
.