簡體   English   中英

驗證MVC(4)和EF(4)中的導航屬性

[英]Validation for Navigation Properties in MVC (4) and EF (4)

我使用EF創建了一個模型,然后在MVC中創建了一個控制器和視圖。 模型類型A具有類型B的Navigation屬性。 因此,當我創建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檢查值?

問題是您的下拉列表的值為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

因此,我找到了一種(詳細的)方式來吃我的蛋糕,也不必在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);
}

無需添加額外字段(類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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM