Asp.net mvc 当视图根据条件需要不同的ViewModel时,如何为ViewModel建模?

Asp.net mvc 当视图根据条件需要不同的ViewModel时,如何为ViewModel建模?,asp.net-mvc,asp.net-mvc-3,Asp.net Mvc,Asp.net Mvc 3,我正在建立一个问题库。它一次显示两个问题。这些问题可以是不同类型的。例如,多项选择题和“矩阵”题,其中有许多行和列需要回答 我目前不使用ViewModels,只使用实体模型(我知道我不应该这样做) 用于检索问题列表的代码: public ActionResult QuestionList(int categoryId, int page) { var questions = new PagedData<Question>();

我正在建立一个问题库。它一次显示两个问题。这些问题可以是不同类型的。例如,多项选择题和“矩阵”题,其中有许多行和列需要回答

我目前不使用ViewModels,只使用实体模型(我知道我不应该这样做)

用于检索问题列表的代码:

        public ActionResult QuestionList(int categoryId, int page)
    {
        var questions = new PagedData<Question>();

        questions.Data = db.Question.Where(c => c.category_id == categoryId).OrderBy(p => p.question_number).Skip(PageSize * (page - 1)).Take(PageSize).ToList();
        questions.NumberOfPages = Convert.ToInt32(Math.Ceiling((double)db.Question.Where(cc => cc.category_id == categoryId).Count() / PageSize));
        questions.CurrentPage = page;
        questions.CategoryID = categoryId;

        return PartialView("QuestionList", questions);
    }
public ActionResult问题列表(int-categoryId,int-page)
{
var questions=new PagedData();
questions.Data=db.Question.Where(c=>c.category_id==categoryId).OrderBy(p=>p.Question_number).Skip(PageSize*(page-1)).Take(PageSize).ToList();
questions.NumberOfPages=Convert.ToInt32(Math.Ceiling((double)db.Question.Where(cc=>cc.category_id==categoryId.Count()/PageSize));
questions.CurrentPage=第页;
questions.CategoryID=CategoryID;
返回PartialView(“问题列表”,问题);
}
视图如下所示:

    @model MvcApplication3.Helpers.Paging.PagedData<MvcApplication3.Models.Question>


@if (Model.Data.Count() == 0)
{
<h2>Denne kategori har ingen spørgsmål</h2>
}
else
{
    <h2>@Model.Data.First().Category.category_name</h2>

    <br />

    <div>

    Tryk for at komme videre til side: 

    @for (int i = 1; i <= Model.NumberOfPages; i++)
    {
        if (i == Model.CurrentPage)
        {
            @i
        }
        else
        {
            <a class="page-number" href="javascript:void();">@i</a>
        }
    }
    </div>
    <br />

    foreach (var item in Model.Data)
    {
        if (item.visible == true)
        {
            String isAnswered = null;
            if (item.Tabelform_Answers.Count() >= 1)
            {
                isAnswered = "answered";
            }
            else if(item.MCQ_Answers.Count() >= 1) 
            {
                isAnswered = "answered";
            }
            else
            {
                isAnswered = "unanswered";
            }

            <div id=@isAnswered>

            @if (User.IsInRole("Administrator"))
            {
                @Html.ActionLink("[Rediger]", "Edit", "AdminQuestion", new { id = item.question_id }, null)    
            }

            @Html.LabelFor(y => item.question_wording, item.question_wording, new { @class = "tooltip", title = @item.help_text })

            @if (item.Question_Type.type_description == "Multiple Choice")
            {
                <br />
                @Html.Partial("MCQDisplay", item)
            }
            else if (item.Question_Type.type_description == "Tabelform")
            {
                <br /><br />
                @Html.Partial("GridDisplay", item)
            }

            </div>
            <br />   
        }
    }

}

@Html.HiddenFor(m => m.NumberOfPages)
@Html.HiddenFor(m => m.CategoryID)
@Html.HiddenFor(m => m.CurrentPage)
List<MultipleChoiceViewModel> mcqlist;
List<GridQuestionViewModel> gridlist;
@model mvcapapplication3.Helpers.Paging.PagedData
@if(Model.Data.Count()==0)
{
Denne kategori har ingen spørgsmål
}
其他的
{
@Model.Data.First().Category.Category\u name

在komme videre进行试验,直到侧: @对于(int i=1;i=1) { isAnswered=“已回答”; } else if(item.MCQ_Answers.Count()>=1) { isAnswered=“已回答”; } 其他的 { isAnswered=“未回答”; } @if(User.IsInRole(“管理员”)) { @ActionLink(“[Rediger]”、“Edit”、“AdminQuestion”、新的{id=item.question\u id},null) } @LabelFor(y=>item.question_措辞,item.question_措辞,新的{@class=“tooltip”,title=@item.help_text}) @if(item.Question\u Type.Type\u description==“多项选择”) {
@Html.Partial(“MCQDisplay”,项目) } else if(item.Question\u Type.Type\u description==“Tabelform”) {

@Html.Partial(“GridDisplay”,项目) }
} } } @Html.HiddenFor(m=>m.NumberOfPages) @Html.HiddenFor(m=>m.CategoryID) @Html.HiddenFor(m=>m.CurrentPage)
我不想将整个问题实体发送到部分视图MCQDisplay和GridDisplay,而是只发送必要的数据

这个ViewModel应该是什么样子

我的想法是在主视图模型中列出每种类型的问题,如下所示:

    @model MvcApplication3.Helpers.Paging.PagedData<MvcApplication3.Models.Question>


@if (Model.Data.Count() == 0)
{
<h2>Denne kategori har ingen spørgsmål</h2>
}
else
{
    <h2>@Model.Data.First().Category.category_name</h2>

    <br />

    <div>

    Tryk for at komme videre til side: 

    @for (int i = 1; i <= Model.NumberOfPages; i++)
    {
        if (i == Model.CurrentPage)
        {
            @i
        }
        else
        {
            <a class="page-number" href="javascript:void();">@i</a>
        }
    }
    </div>
    <br />

    foreach (var item in Model.Data)
    {
        if (item.visible == true)
        {
            String isAnswered = null;
            if (item.Tabelform_Answers.Count() >= 1)
            {
                isAnswered = "answered";
            }
            else if(item.MCQ_Answers.Count() >= 1) 
            {
                isAnswered = "answered";
            }
            else
            {
                isAnswered = "unanswered";
            }

            <div id=@isAnswered>

            @if (User.IsInRole("Administrator"))
            {
                @Html.ActionLink("[Rediger]", "Edit", "AdminQuestion", new { id = item.question_id }, null)    
            }

            @Html.LabelFor(y => item.question_wording, item.question_wording, new { @class = "tooltip", title = @item.help_text })

            @if (item.Question_Type.type_description == "Multiple Choice")
            {
                <br />
                @Html.Partial("MCQDisplay", item)
            }
            else if (item.Question_Type.type_description == "Tabelform")
            {
                <br /><br />
                @Html.Partial("GridDisplay", item)
            }

            </div>
            <br />   
        }
    }

}

@Html.HiddenFor(m => m.NumberOfPages)
@Html.HiddenFor(m => m.CategoryID)
@Html.HiddenFor(m => m.CurrentPage)
List<MultipleChoiceViewModel> mcqlist;
List<GridQuestionViewModel> gridlist;
列出mcqlist;
列表网格列表;

如果类别中没有多项选择类型的问题,则列表将为空且不使用。这个练习好吗?

你可以试试这个。我不是100%肯定它会工作,因为我不知道MVC框架是只寻找模型类型,还是真正的类型

将基类作为模型类型传递,然后从基类类型派生不同的viewmodels。然后为每个问题类型定义编辑器模板,只需对该类型使用DisplayFor或EditorFor,并让它自己呈现

正如我所说的,这将取决于MVC是使用它的最终类型,还是只使用基本类型

编辑:

您创建了名为
QuestionViewModel
的基类,它不需要任何属性或方法,但如果有公共方法或属性,您可以将它们放在这里

然后从
QuestionViewModel
导出
multiplechiceviewmodel
GridQuestionViewModel

在你看来:

@model IEnumerable<QuestionViewModel>

@Html.EditorForModel()
@model IEnumerable
@Html.EditorForModel()
然后在视图/任意文件夹、视图/共享文件夹中为每种类型创建一个名为EditorTemplates的文件夹,然后为每种类型定义html


MVC应该自动知道一个问题是一个GridQuestionViewModel,并在您传递它们的列表时使用它的编辑器模板。

所以我不应该使用ViewModels?是的,您应该这样做。这就是为什么我说“然后导出不同的视图模型”。不知道你怎么能推断出“不使用viewmodels”的意思,你能提供一个简单的例子吗?+1,正是我所做的。是的,MVC将选择正确的子类型的编辑器模板。MultipleChiceViewModel和GridQuestionViewModel中的属性需要填充一些数据。这些数据来自哪里?谢谢你的帮助(顺便说一句!)