Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从不同的ViewModel返回值?_C#_Asp.net Mvc_Controller_Viewmodel - Fatal编程技术网

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;
        }
    }   
}