C#和MVC的新手,所以可能是一个明显的错误: 我的Controller逻辑不会向View发送任何数据库项。我不知道我做错了什么。
我正在构建一个多选在线测试,并有两个数据库授权类
public partial class Answer
{
public int ID { get; set; }
public string CorrectAnswer { get; set; }
public string Foil1 { get; set; }
public string Foil2 { get; set; }
public string Foil3 { get; set; }
}
public partial class Question
{
public int ID { get; set; }
public string Text { get; set; }
public string Level { get; set; }
public string GrammarPoint { get; set; }
}
我想在一个视图中显示问题和答案选项,所以我有这个ViewModel
public class ExamViewModel
{
public string CorrectAnswer { get; set; }
public string Foil1 { get; set; }
public string Foil2 { get; set; }
public string Foil3 { get; set; }
public string Text { get; set; }
}
这是控制器。
public ActionResult TakeTest()
{
ActiveTestEntities db = new ActiveTestEntities();
ExamViewModel exam = new ExamViewModel();
exam.Text = db.Questions.FirstOrDefault(t => t.ID == 1).ToString();
exam.Foil1 = db.Answers.FirstOrDefault(t => t.ID == 1).ToString();
exam.Foil2 = db.Answers.FirstOrDefault(t => t.ID == 1).ToString();
exam.Foil3 = db.Answers.FirstOrDefault(t => t.ID == 1).ToString();
exam.CorrectAnswer = db.Answers.FirstOrDefault(t => t.ID == 1).ToString();
return View(exam);
}
LINQ应该将db项发送到此视图:
@model AccessEsol.Models.ExamViewModel
@{
ViewBag.Title = "TakeTest";
}
<h2>TakeTest</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<div class="display-label">
<h3>Click the correct answer:</h3>
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Text )
</div>
<input id="Checkbox1" type="checkbox" />
@Html.DisplayFor(model => model.Foil1)
<input id="Checkbox1" type="checkbox" />
@Html.DisplayFor(model => model.Foil2)
<input id="Checkbox1" type="checkbox" />
@Html.DisplayFor(model => model.CorrectAnswer )
<input id="Checkbox1" type="checkbox" />
@Html.DisplayFor(model => model.Foil3)
<p>
<input type="submit" value="Submit Answers" />
</p>
</fieldset>
}
但是在每个Checkbox旁边只显示AccessEsol.Models.Answer,尚未检索到db项目。
非常感谢,如果你能告诉我我做错了什么。
答案 0 :(得分:1)
你使用linq错误
db.Answers.FirstOrDefault(t => t.ID == 1)
此返回对象Answer
但您需要例如Answer.Foil1
所以请尝试更改您的代码
ExamViewModel exam = (from q in db.Questions
from a in db.Answers
where q.ID == 1 && a.ID==1
select new ExamViewModel{
Foil1 = a.Foil1,
Foil2 = a.Foil2,
Foil3 = a.Foil3,
CoorectAnswer = a.CorrectAnswer,
Text = q.Text
}).FirstOrDefault()
答案 1 :(得分:1)
因为你定义了一个问题和视图类,我会在你的视图模型中使用它们而不是重新定义字段
public class ExamViewModel
{
public Answer Answer{ get; set; }
public Question Question { get; set; }
}
然后在您的视图中,您将其用作
@Html.DisplayFor(x => x.Answer.Foil1)
在您的控制器上定义对象,但我看不到您在哪里调用数据库。在控制器上放置一个断点,并确保数据库对象具有您要发送到视图的数据
答案 2 :(得分:0)
在对象上调用.ToString()
时,输出是该对象的类型名称。这就是你看到的原因:
AccessEsol.Models.Answer
这是在.ToString()
类型的任何对象上调用AccessEsol.Models.Answer
的结果。
那些物品是什么?而不是尝试将它们转换为字符串,而是使用对象本身。所以你的视图模型更像是这样:
public class ExamViewModel
{
public Answer CorrectAnswer { get; set; }
public Answer Foil1 { get; set; }
public Answer Foil2 { get; set; }
public Answer Foil3 { get; set; }
public Question Text { get; set; }
}
然后你只需删除控制器中对.ToString()
的调用:
exam.Text = db.Questions.FirstOrDefault(t => t.ID == 1);
exam.Foil1 = db.Answers.FirstOrDefault(t => t.ID == 1);
exam.Foil2 = db.Answers.FirstOrDefault(t => t.ID == 1);
exam.Foil3 = db.Answers.FirstOrDefault(t => t.ID == 1);
exam.CorrectAnswer = db.Answers.FirstOrDefault(t => t.ID == 1);
然后在您的视图中,您将访问这些对象的实际属性。我不知道这些属性被称为什么,所以这是一个猜测,但它可能是这样的:
@Html.DisplayFor(model => model.Text.QuestionText)
这假设在QuestionText
对象上有一个名为Question
的属性,用于保存其文本。无论在您的代码中实际调用该属性,只需使用它。
可以通过覆盖.ToString()
和Question
个对象上的Answer
来输出所需的字符串,从而使现有代码生效。但这并不是一种常见的方法,并且会不必要地使代码复杂化。最好的方法是只使用你拥有的模型,并将它们保留为实际的模型类型,而不是试图将它们转换为字符串。
这甚至不一定是MVC问题,这只是普通的C#代码。首选强类型对象而不是序列化字符串。