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

时间:2015-07-10 18:23:20

标签: asp.net-mvc model-view-controller listbox many-to-many

我是MVC的新手,非常感谢任何建议。我有几个模型/表一起工作。我遇到的麻烦是与多对多的关系。我想要的是有一个用户可以多选的列表框,并传递这些值以保存在连接表中,同时将主条目保存到另一个表。

我的模特:

    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")
}

我的DBContext:

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天,并且已经从我在线阅读的内容中做了大量的试验和错误。此时,创建视图会显示一个列表框,该列表框从“能力”表中提取标题。当我尝试保存时,我收到验证错误“值”1“无效。”,其中1是该能力的ID。调试时,我看到模型状态无效,错误是

{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 helper尝试其他任何东西它将不会引入数据并且通常在我甚至看到创建页面之前崩溃。对不起,这太久了,我只想提供所有可能的信息。 :)感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

SelectedAbilities而不是Abilities生成一个列表框:

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

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