如何在 MVC4 EF5 中传递选定的项目?

How do I pass selected items in MVC4 EF5?

我是 MVC 的新手,希望得到任何建议。我有几个 models/tables 一起工作。我遇到的麻烦是 many-to-many 关系。我想要的是有一个列表框,用户可以从中进行多选并将这些值传递以保存在联接 table 中,同时将主要条目保存到另一个 table.

我的模特:

    public class Card
    {
        public virtual int CardID { get; set; }
        public virtual string Title { get; set; }
        //A bunch of properties...
        //Drop Down Lists
        public int RarityID { get; set; }
        public virtual Rarity Rarity { get; set; }
        public int MainTypeID { get; set; }
        public virtual MainType MainType { get; set; }
        public int CardSetID { get; set; }
        public virtual CardSet CardSet { get; set; }
        public int SubTypeID { get; set; }
        public virtual SubType SubType { get; set; }
        public virtual string AdditionalType { get; set; }
        public virtual IList<CardAbility> Abilities { get; set; }
        public virtual int[] SelectedAbilities { get; set; }
    }
    public class Ability
    {
        public virtual int AbilityID { get; set; }
        public virtual string Title { get; set; }
        public virtual IList<CardAbility> Cards { get; set; }
}

public class CardAbility
    {
        public int CardAbilityID { get; set; }
        public virtual Ability Ability { get; set; }
        public int AbilityID { get; set; }
        public virtual Card Card { get; set; }
        public int CardID { get; set; }
    }

我的控制器:

public ActionResult Create()
        {
            ViewBag.RarityID = new SelectList(db.Rarities, "RarityID", "Title");
            ViewBag.MainTypeID = new SelectList(db.MainTypes, "MainTypeID", "Title");
            ViewBag.CardSetID = new SelectList(db.CardSets, "CardSetID", "Title");
            ViewBag.SubTypeID = new SelectList(db.SubTypes, "SubTypeID", "Title");
            ViewBag.Abilities = new MultiSelectList(db.Abilities, "AbilityID", "Title");
            return View();
        }
        // POST: /Card/Create

        [HttpPost]
        public ActionResult Create(Card card)
        //[ModelBinder(typeof(CardBinder1))]
        {
            if (ModelState.IsValid)
            {
                db.Cards.Add(card);
                db.SaveChanges();

                foreach (var items in card.SelectedAbilities)
                {
                    var obj = new CardAbility() { AbilityID = items, CardID = card.CardID };
                    db.CardAbilities.Add(obj);
                }

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

            ViewBag.RarityID = new SelectList(db.Rarities, "RarityID", "Title", card.RarityID);
            ViewBag.MainTypeID = new SelectList(db.MainTypes, "MainTypeID", "Title", card.MainTypeID);
            ViewBag.CardSetID = new SelectList(db.CardSets, "CardSetID", "Title", card.CardSetID);
            ViewBag.SubTypeID = new SelectList(db.SubTypes, "SubTypeID", "Title", card.SubTypeID);
            ViewBag.Abilities = new MultiSelectList(db.Abilities, "AbilityID", "Title");
            return View(card);

我的创建视图:

model MTG.Models.Card

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Card</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>
         <div class="editor-label">
            @Html.Label("Abilities")
        </div>
        <div class="editor-field">
        @Html.ListBoxFor(model => model.Abilities, (ViewBag.AbilityID as MultiSelectList))
                       @Html.ValidationMessageFor(model => model.Abilities)
        </div>
<div class="editor-label">
            @Html.LabelFor(model => model.RarityID, "Rarity")
        </div>
        <div class="editor-field">
            @Html.DropDownList("RarityID", String.Empty)
            @Html.ValidationMessageFor(model => model.RarityID)
        </div>
// A lot more fields...
 <p>
            &lt;input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

我的数据库上下文:

public DbSet&lt;Ability&gt; Abilities { get; set; }
        public DbSet&lt;Rarity&gt; Rarities { get; set; }
        public DbSet&lt;CardSet&gt; CardSets { get; set; }
        public DbSet&lt;MainType&gt; MainTypes { get; set; }
        public DbSet&lt;SubType&gt; SubTypes { get; set; }
        public DbSet&lt;Card&gt; Cards { get; set; }
        public DbSet&lt;CardAbility&gt; CardAbilities { get; set; }

        public class AbilitiesToCardsConfiguration : EntityTypeConfiguration&lt;CardAbility&gt;
        {
            internal AbilitiesToCardsConfiguration()
            {
                this.HasKey(p =&gt; new { p.AbilityID, p.CardID });
                this.HasRequired(p =&gt; p.Ability)
                    .WithMany(p =&gt; p.Cards)
                    .HasForeignKey(p =&gt; p.AbilityID);
                this.HasRequired(p =&gt; p.Card)
                    .WithMany(r =&gt; r.Abilities)
                    .HasForeignKey(p =&gt; p.CardID);
            }
        }

我已经为此工作了大约 3 天,并且根据我在网上阅读的内容进行了大量试验和错误。此时,创建视图确实显示了一个列表框,该列表框正在从能力 table 中提取标题。当我尝试保存时,出现验证错误 "The value "1" is invalid.",其中 1 是该能力的 ID。调试时看到modelstate无效,报错

{System.InvalidOperationException: The parameter conversion from type 'System.String' to type 'MTG.Models.CardAbility' failed because no type converter can convert between these types.
   at System.Web.Mvc.ValueProviderResult.ConvertSimpleType(CultureInfo culture, Object value, Type destinationType)
   at System.Web.Mvc.ValueProviderResult.UnwrapPossibleArrayType(CultureInfo culture, Object value, Type destinationType)
   at System.Web.Mvc.ValueProviderResult.ConvertTo(Type type, CultureInfo culture)
   at System.Web.Mvc.DefaultModelBinder.ConvertProviderResult(ModelStateDictionary modelState, String modelStateKey, ValueProviderResult valueProviderResult, Type destinationType)}

我知道它不喜欢这些类型并且无法转换,但如果我尝试使用 listboxfor 帮助程序进行任何其他操作,它不会引入数据并且通常在我看到创建页面之前就崩溃了.抱歉,这么长,我只是想提供我能提供的所有信息。 :) 感谢您的帮助。

SelectedAbilities 而不是 Abilities 生成列表框:

@Html.ListBoxFor(model => model.SelectedAbilities , (ViewBag.AbilityID as MultiSelectList))

顺便说一下,您需要对 RarityID 而不是 RarityMainTypeID 而不是 MainType 等执行相同的操作