C# 如何从不同的ViewModel返回值?
我试着用一种观点来做这件事,也许这不是最好的方法 我有一个数据驱动的表单;所有问题都来自一个问题表,但答案填充一个回答表。这里是风景C# 如何从不同的ViewModel返回值?,c#,asp.net-mvc,controller,viewmodel,C#,Asp.net Mvc,Controller,Viewmodel,我试着用一种观点来做这件事,也许这不是最好的方法 我有一个数据驱动的表单;所有问题都来自一个问题表,但答案填充一个回答表。这里是风景 @using Microsoft.AspNet.Identity @model Template.Models.Question @{ ViewBag.Title = "View question"; var qtype = Model.QuestionTypeId; ViewBag.Number = Model.Id - 7
@using Microsoft.AspNet.Identity
@model Template.Models.Question
@{
ViewBag.Title = "View question";
var qtype = Model.QuestionTypeId;
ViewBag.Number = Model.Id - 7;
Html.BeginForm("ViewQuestion", "Question", FormMethod.Post, new { @class = "form-horizontal", role = "form" });
}
<h4>Question #@ViewBag.Number</h4>
<hr />
<h1> @Model.Question1</h1>
@Html.AntiForgeryToken()
<div>
@switch (qtype)
{
case 1:
// Textbox
@Html.TextArea("Answer", new { @class = "form-control", rows = "4", col = "5" });<br /><br />
break;
case 2:
// Dropdown
<select class="form-control" id="Answer">
@foreach (var item in Model.QuestionOptions.OrderBy(o => o.QuestionOptionRanking))
{
<option value="@item.QuestionOption1">@item.QuestionOption1</option>
}
</select><br /><br />
break;
case 3:
// Checkbox
<div class="checkbox">
@foreach (var item in Model.QuestionOptions.OrderBy(o => o.QuestionOptionRanking))
{
<input type="checkbox" name="Answer" value="@item.QuestionOption1" /> @item.QuestionOption1 <br />
}
</div><br /><br />
break;
case 4:
// Radio buttons
foreach (var item in Model.QuestionOptions.OrderBy(o => o.QuestionOptionRanking))
{
<div class="radio">
<label>
<input type="radio" name="Answer" value="@item.QuestionOption1" />
@item.QuestionOption1
</label>
</div>
}<br /><br />
break;
}
</div>
<input type="hidden" name="QuestionId" value="@Model.Id" />
<input type="hidden" name="UserId" value="@User.Identity.GetUserId()" />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Answer" />
</div>
</div>
我研究这个问题已经好几天了,现在我只是在兜圈子。非常感谢您提供的任何帮助或建议。看起来您混淆了实体模型和视图模型。在视图中,您引用了
Template.Models.Question
,它似乎是一个实体而不是ViewModel
视图应仅引用ViewModel,而不是实体。在实体和ViewModel之间应该建立一些映射机制。我注意到的另一件事是,实体和ViewModel似乎位于应用程序中的同一名称空间中。这不一定是个问题,但可能会让人困惑,因为ViewModels只属于您的视图,而实体属于您的持久性层
当前,您的代码通过以下方式获取问题对象:来自db中的q。问题
,然后将其传递到视图中(问题)。因此,视图中实际上没有可用的ViewModel,而是实体模型
将您的视图更改为:
@model Template.Models.GetQuestionViewModel
并将控制器更改为如下所示:
var questions = (from q in db.Questions
where q.PageNumber == pageId
orderby q.QuestionRanking
select q.ToViewModelExtensionMethod()).ToList();
return View(questions);
您必须编写扩展方法来执行从Template.Model.Question到Template.Model.GetQuestionViewModel的映射
希望这有帮助
更新
有关扩展方法的信息,请参见
我只是使用扩展方法,因为我喜欢语法流动的方式。下面是一个简单的例子:
namespace Template.Models.Extensions
{
public static class QuestionExtensions
{
public static GetQuestionViewModel ToViewModelExtensionMethod(this Question question)
{
var result = new GetQuestionViewModel();
result.field1 = question.field1;
// ... etc
return result;
}
}
}
另外,请注意上面的更改,我现在映射查询的项目 另一方面,让视图中显示的问题编号基于Id是不好的做法。Id应该与您的实现完全无关。应该有一个单独的字段用于存储实际问题编号。已同意。我计划在我能正常工作的时候把它换成页码。但我目前仍停留在显示用户的答案上。两个人都在折磨我!你的[路线…]有效吗?当您导航到该url时,控制器方法是否执行?此外,该方法似乎返回一个视图(Template.Models.Question),而不是一个视图(Template.Models.GetQuestionViewModel)。您是对的,Aaron,我对实体和viewmodels感到困惑。你能给我更多关于“执行映射的扩展方法”的细节或示例吗?因为这是真正让我困惑的部分?
var questions = (from q in db.Questions
where q.PageNumber == pageId
orderby q.QuestionRanking
select q.ToViewModelExtensionMethod()).ToList();
return View(questions);
namespace Template.Models.Extensions
{
public static class QuestionExtensions
{
public static GetQuestionViewModel ToViewModelExtensionMethod(this Question question)
{
var result = new GetQuestionViewModel();
result.field1 = question.field1;
// ... etc
return result;
}
}
}