2

我正在做一个调查申请。调查有问题,问题有 QuestionOption。这里有一个例子 我正在尝试以带有列表(列表)的大型形式使用此技术,但是当我回发时,应该包含项目和活动列表的 Viewmodel.Order 返回列表为空。

我的 QuestionModel.cs 就是这样。

 public int Id { get; set; }       
 public string QuestionText { get; set; }     
 public System.Nullable<bool> OptionType1 { get; set; }
 public System.Nullable<bool> OptionType2 { get; set; }
 public List<QuestionOptionModel> OptionList = new List<QuestionOptionModel>();

当我发回“IEnumerable questions”时,List OptionList 为空。我怎样才能做到这一点?

 public ActionResult CallSurvey()
    {
        IEnumerable<QuestionModel> questionModelList = (IEnumerable<QuestionModel>)SessionHelper.GetSessionObject(SessionKeys.SurveyKey);
       questionModelList = questionSrv.GetQuestionModel();
        return View(questionModelList);

    }

questionModelList 包括我所有的调查问题和问题选项。当我发布它时,回发只带有空选项列表。

 [HttpPost]
    public ActionResult CallSurvey(IEnumerable<QuestionModel> questions)
    { ..... }

CallSurvey.cshtml

   <body>
    @using ((Html.BeginForm()))
    {
        @ViewBag.Test
        <section class="slides layout-regular template-kendo">
        @foreach (var item in Model)
        {<article>

                @Html.Partial("QuestionEditor", item)
               </article>
        }
   <div class="slide-area" id="prev-slide-area"></div>
        <div class="slide-area" id="next-slide-area"></div>
      </section> 
    }
</body>

QuestionEditor.cshtml

    @model LSMM.Business.Model.Survey.QuestionModel
@using LSMM.Web.Helpers
<div>
    @using (Html.BeginCollectionItem("Questions"))
    {

        <table id="table1">
            <tr>
                <td>
                    <div id="@Model.Id" class="hint">
                        @Html.HiddenFor(m => m.Id)
                        @Html.HiddenFor(m => m.QuestionText)
                        @Html.HiddenFor(m => m.OptionType1)
                        @Html.HiddenFor(m => m.OptionType2)



                        @for (int i = 0; i < Model.OptionList.Count; ++i)
                        {
                        @Html.LabelFor(m => m.OptionList[i].Id)
                        @Html.LabelFor(m => m.OptionList[i].QuestionId)
                        @Html.LabelFor(m => m.OptionList[i].Checked)
                        @Html.LabelFor(m => m.OptionList[i].Description)
                        @Html.LabelFor(m => m.OptionList[i])
                   }
                        <span id="sorular">@Model.Id. @Model.QuestionText</span>
                        <br />
                        <br />
                    </div>
                </td>
            </tr>
            <tr>
                <td>
                    <div class="hint2">
                        @Html.Partial("QuestionOptionEditor", Model)
                    </div>
                </td>
                <td>
                    <div id="@Model.Id-Img">
                        <h2 style="top: 200px; right: 0;">
                            <img src="../../Content/css/img/@Model.Id-Img.png"></h2>
                    </div>
                </td>
            </tr>
        </table>  

和 QuestionOptionEditor.cshtml

   @model LSMM.Business.Model.Survey.QuestionModel

 @using LSMM.Web.Helpers               



@foreach (var option in @Model.OptionList)
{


    <p>
        @if (@Model.OptionType1 == false)
        { 
            @Html.Partial("QuestionOptionModel", option)

        }
        else
        { 
            @Html.Partial("../Shared/DisplayTemplates/QuestionOptionModel", option)

        }
    </p>

}

这里的 QuestionOptionModel 视图是这样的;

@model LSMM.Business.Model.Survey.QuestionOptionModel

      @(Html.RadioButtonFor(m => m.Id, true, new { Id = @Model.Id, Name = @Model.QuestionId })) @Html.Label("Evet")  
      <br /> 
      <br />
      @(Html.RadioButtonFor(m => m.Id, false ,new { Id=@Model.Id, Name = @Model.QuestionId})) @Html.Label("Hayır")
4

2 回答 2

2

根据默认 ModelBinder 使用的命名规则,单选按钮上的 name 属性不是“正确的”。这就是为什么你没有看到你期望的值,ModelBinder 找不到它正在寻找的东西。

这很容易解决,您最终应该使用更少的代码。利用该框架并让它为您工作:

  1. MVC 可以为您循环 IEnumerables。让它。如今,几乎没有理由在视图中编写 foreach 循环。
  2. 摆脱那些部分。请改用 MVC 的模板功能。

那么你的观点可以很简单:

 <body>
        @using ((Html.BeginForm()))
        {
            @ViewBag.Test
            <section class="slides layout-regular template-kendo">
        <table id="table1">
            @* Table header goes here *@
            @Html.EditorFor(model => model.OptionList)
        </table>
       <div class="slide-area" id="prev-slide-area"></div>
            <div class="slide-area" id="next-slide-area"></div>
          </section> 
        }
</body>

当您使用 EditorTemplate 或 DisplayTemplate 时,MVC 将自动修复表单字段上的 name 属性。它不会用部分来做到这一点。

另一个建议,如果你不介意的话。摆脱模型上的那些 nulla-bools 并编写不同的 QuestionOptionModel 类型。DisplayTemplate/EditorTemplates 对类型系统是明智的,MVC 将选择与其呈现的类型匹配的模板。

所以你可以有另一个派生自 QuestionOptionModel 的类:

public class ExtendedQuestionOptionModel : QuestionOptionModel
{
    //Stuff goes here.
}

并且您可以List<QuestionOptionModel>悬挂您的模型,其中包含:

  • 问题选项模型
  • 扩展问题选项模型
  • 问题选项模型

当你这样做时:

@Html.EditorFor(model => model.QuestionOptions)

MVC 将遍历选项列表并呈现 QuestionOptionModel 的 Editor Template,然后是 ExtendedQuestionOptionModel 的 Editor Template,然后是 QuestionOptionModel 的 Editor Template。

你想玩的游戏是尽量减少视图中的 C# 代码,因为视图不能进行单元测试。未经单元测试的代码最终会回来并得到你。

于 2012-10-16T14:33:08.550 回答
0

你的问题有点模棱两可。坦率地说,我希望这是您正在寻找的:
IEnumerable 可以转换为列表使用

 List<foo>listFoo =iEnumerableEntityFoo.toList() 
于 2012-09-05T15:36:03.483 回答