DB ViewModel数据未在MVC视图中显示

时间:2014-01-01 17:28:10

标签: c# linq asp.net-mvc-4

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项目。

非常感谢,如果你能告诉我我做错了什么。

3 个答案:

答案 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#代码。首选强类型对象而不是序列化字符串。