MVC 4绑定多个模型asp剃须刀

时间:2014-07-11 08:22:48

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

我开发了一个管理员工队伍的应用程序,我使用Razor的MVC4 Asp.net。

在我的模型中,我有两个班级(谁是我的数据库中的表格)组建和形成(培训师)。

在我的应用程序中,我可以创建一个“阵型”,我想添加一个“形成”(训练师)列表,但我不知道我必须做什么。 我认为最好的解决方案是复选框列表,我成功地用foreach显示我的复选框列表,但我不知道如何将所选复选框的结果传递给我的控制器。

我看过许多使用“CheckBoxList”的教程,我也尝试使用它,但我使用ViewBag来填充它,并且他们不解释如何将它与viewbag一起使用。

现在我测试带有拖动按钮的双列表框(添加和删除),但这不起作用。

那么,有人可以帮助我找到并解释我必须做的,好的或最好的解决方案吗?

对不起我的英语,我是一个法国女孩。

我的一个解决方案如下所示: 我的控制器:

    public ActionResult Create()
    {     
        ViewBag.formateurListe = (from unFormateur in db.salarie
                                 where unFormateur.sFormateur == true
                                 select unFormateur).AsEnumerable()
.Select(m => new SelectListItem
                                 {
                                     Text = m.sNom.ToString() + " " + m.sPrenom.ToString(),
                                     Value = m.sId.ToString()
                                 }).ToList();

        return View();
    }

    [HttpPost]
    public ActionResult Create(formation formation, IEnumerable<SelectList> formateurList)
    {

        if (ModelState.IsValid)
        {
            db.formation.Add(formation);

            foreach (var unSal in formateurList)
            {
                formateur f = new formateur();
                f.ftIdFormation = formation.fId;
                f.ftIdSalarie = (int)unSal.SelectedValue;
                db.formateur.Add(f);

            }
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(formation);
    }

在我看来:

@model MvcAppGestionRH.Models.formation
@using (Html.BeginForm("Create", "Formation", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.ValidationSummary(true)

            @Html.Label("Libelle")        
            @Html.EditorFor(model => model.fLibelle)
            @Html.ValidationMessageFor(model => model.fLibelle)

                <label id="fFormateur">Formateur</label>                                   

                @Html.ListBox("formateurListe", ViewData["formateurListe"]  as SelectListItem[], new {Multiple = "multiple"})

                <input type="button" value="+" name="add" />
                <select name="select" size="7" >
                </select>    
 <input type="submit" value="Créer" />        
}

使用脚本:

  $(function () {
            $("#Add").click(function () {
                $("select").add($('fFormateurListe').selected);
            });
        });

2 个答案:

答案 0 :(得分:1)

第一次复选框可能会很棘手 - 我也用Google搜索了很长时间。

我的解决方案是一个看起来像这样的视图模型:

它适用于问题,主持人可以通过复选框指定项目(例如,问题可能有答案&#34; GOOD&#34;以及&#34; BAD&#34;。

public class QuestionModel
{
    public int QuestionID { get; set; }

    public string QuestionText { get; set; }

    /// <summary>
    /// Gets or sets the selected items. Purely a helper List to display check boxes for the user
    /// </summary>
    /// <value>
    /// The selected items.
    /// </value>
    [Display(Name = "Items", ResourceType = typeof(Domain.Resources.Question))]
    public IEnumerable<SelectListItem> SelectedItems { get; set; }

    /// <summary>
    /// Gets or sets the selected ids. Populated by the user, when he checks / unchecks items. Later translated into QuestionItems
    /// </summary>
    /// <value>
    /// The selected ids.
    /// </value>
    public int[] SelectedIds { get; set; }
}

这在QuestionController中填充如下:

    private async Task GetSelectedItems(QuestionModel sm, Item selectedItems)
    {
        var alreadySelected = new List<Scale>();

        if (selectedScale != null)
        {
            alreadySelected.Add(selectedScale);
        }

        var itemList = (await this.uoW.ItemRepository.Get()).OrderBy(i => i.Name);

        sm.SelectedItems = itemList.Select(x => new SelectListItem
        {
            Value = x.ScaleID.ToString(),
            Text = x.NameOfScale.GetText(),
            Selected = (from a in alreadySelected where a.ItemID == x.ItemID select x).Any()
        });
    }

这是做什么的?它获取数据库中所有可用项目的列表,并使用它填充模型。此外,您可以传入已选择的项目列表 - 这样您就可以编辑现有问题并搜索所有已检查的项目。

在视图中我使用了DropDownList:

    <div class="form-group">
        @Html.LabelFor(model => model.SelectedItems, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <div class="checkbox">
                @Html.DropDownListFor(x => x.SelectedIds, Model.SelectedItems, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.SelectedItems, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>

如果你想要复选框,看起来像这样(不同的控制器,所以不要混淆)

 for (int i = 0; i < Model.SelectedItems.Count(); i++)
        {
            var currentElem = Model.SelectedItems[i];
            //if this item is selected by the user, e.g. because he is editing the item, the item will be pre-selected
            var selected = currentElem.Selected ? "checked=\"selected\"" : string.Empty;

            // column for the questions. expected layout: list of all questions
            <div class="col-md-6">
                <div class="checkbox" id="SelectedIds">
                    <label>
                        <input type="checkbox" value="@currentElem.Value" @selected name="SelectedIds">
                        @Html.Encode(currentElem.Text)
                    </label>
                </div>
            </div>
        }

最后是create()方法本身:

    [HttpPost]
            [ValidateAntiForgeryToken]
            public async Task<ActionResult> Create([Bind(Include = "QuestionText,SelectedItems, SelectedIds")] QuestionModel question)
            {
                if (ModelState.IsValid)
                {
// I need only one Item, but if you want ore more change this line
                    if (question.SelectedIds.Count() == 1)
                    {
// better use Automapper here, this is unnecessary work
                        var newQuestion = new Question { QuestionText = question.QuestionText};

                        var ItemID = question.SelectedIds.First();

                        newQuestion.QuestionScale = await this.uoW.ItemRepository.GetRaw().Where(i => i.ItemID == ItemD).FirstAsync();

                        this.uoW.QuestionRepository.Insert(newQuestion);

                        await this.uoW.Save();

                        return this.RedirectToAction("Index");
                    }
                    else
                    {
                        this.logger.Warn("User {0} tried to insert more than one Itemin question {1}", User.Identity.Name, question.QuestionID);
                        ModelState.AddModelError(string.Empty, xyz.Areas.QuestionManagement.Resources.QuestionRes.ErrorTooManyScales);
                    }
                }
                else
                {
// the SelectedItems are empty in the model - so if you have to redisplay it, repopulate it.
                    await this.GetSelectedItems(question, null);
                }

                return this.View(question);
            }

答案 1 :(得分:-1)

您是否尝试过使用viewmodel在视图中传递两个模型?

例如:

视图模型

public class CreateFormationViewModel
{
    public Formation formation{ get; set; }
    public List<Formative> trainers {get;set;}

}

然后在您的视图中使用此viewmodel

使用此视图模型的简便方法:

在您的控制器中

public ActionResult CreateFormation()
{
   //Get your data (formation and trainer)
   CreateFormationViewModel createFormationVM = new CreateFormationViewModel();
   createFormationVM.formation = YourFormationModel;
   createFormationVM.trainers = YourtrainersModelasList;

  //bind data to the view
  return View(createFormationVM);
}

在您的视图中,您有:

@model [yournamespace].CreateFormationViewModel