0

EF でモデルを作成し、MVC でコントローラーとビューを作成しました。モデル タイプAには、タイプするナビゲーション プロパティがありBます。だから私が作成するとき、私Aはを選択したいと思いますB

コントローラーを作成し、スカラー プロパティ用に作成されたフィールドのみを表示する MVC ウィザード。そこで、作成アクションをA次のように変更しました。

public ActionResult Create() //Create action for A
{
    List<B> b = db.B.ToList(); //db is my DataContext

    ViewData["B"] = companies.Select(option => new SelectListItem
                    {
                        Text = (option.Name.ToString()),
                        Value = (option.Id.ToString())
                    });
    return View();
}

そして私の見解に追加されました:

<div class="editor-label">
    @Html.LabelFor(model => model.B)
</div>
<div class="editor-field">
    @Html.DropDownListFor(model => model.B,  (IEnumerable<SelectListItem>)ViewData["B"], "---- Select B ----")
    @Html.ValidationMessageFor(model => model.B)
</div>

これまでのところすべて問題なく、HTML を取得できます

<select class="valid" id="B" name="B">
    <option value="">---- Select B ----</option>
    <option selected="selected" value="1">TestB</option>
</select>

ただし、送信するとエラーが発生します。

The value '1' is invalid.

検証を記述していないので、どこかで自動生成されたに違いありません。ViewData["B"] コレクション ID に対して値をチェックするように修正するにはどうすればよいですか?

4

3 に答える 3

1

問題は、ドロップダウン リストの値がId- ですが、プロパティがB.

代わりに、ナビゲーション プロパティの FK にバインドする必要があります。あなたのモデルがわかりません(これが役に立たない場合は、投稿する必要があります)

<div class="editor-field">
    @Html.DropDownListFor(model => model.BId,  (IEnumerable<SelectListItem>)ViewData["B"], "---- Select B ----")
    @Html.ValidationMessageFor(model => model.BId)
</div>

model.Bに変更したことに注意してくださいmodel.BId

于 2012-08-25T19:47:44.260 に答える
0

だから私は、FK IDのために余分なフィールドを入力することなく、ケーキを持ってそれを食べる(冗長な)方法を見つけました

POST作成アクションをFormCollection形式に変更しました。

[HttpPost]
public ActionResult Create(FormCollection collection) //POST create for A
{
    A a = new A();

    a.Name = collection["Name"];
    a.Description = collection["Description"];

    try
    {
        int bId = Int32.Parse(collection["B"]);
        a.B = db.B.First(option => option.Id == bId);
        ValidateModel(a);
    }
    catch
    {
        ModelState.AddModelError("B", new Exception("bId does not match an existing B"));
    }

    if (ModelState.IsValid)
    {
        db.A.Add(a);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    //Failed
    //Go back to create form
    List<B> blist = db.B.ToList();

    ViewData["B"] = blist.Select(option => new SelectListItem
    {
        Text = (option.Name.ToString()),
        Value = (option.Id.ToString())
    });

    return View(a);
}
于 2012-08-25T21:38:33.787 に答える
0

余分なフィールド (クラス A の BId) を追加したり、FormCollection からモデル フィールドを読み取ったりしない別の方法は、model.b.Id をビューに直接バインドすることです。

<div class="editor-label">
    @Html.LabelFor(model => model.B)
</div>
<div class="editor-field">
    @Html.DropDownListFor(model => model.B.Id,  (IEnumerable<SelectListItem>)ViewData["B"], "---- Select B ----")
    @Html.ValidationMessageFor(model => model.B)
</div>

このバインディングは Id を A のナビゲーション プロパティ B にバインドします。Name プロパティをバインドするには、データベース コンテキストから B を一度読み取る必要があります。

[HttpPost]
public ActionResult Create(A a){
   B b = db.Bs.Find(a.B.Id);
   a.B = b;
   db.As.Add(a);
   db.SaveChanges();
}
于 2016-05-26T21:31:04.237 に答える