2013-02-17 56 views
2

我有以下幾點[HTTPGET] Create()方法家長信息:創建於MVC4子對象 - 不被傳遞給創建()控制器

public ActionResult Create(int? parentId) 
    { 
     var model = new CreatePersonViewModel(); 

     // pull parent from db 
     var parent = _db.Persons.FirstOrDefault(s => s.Id == parentId); 

     model.Parent = parentSet; 

     return View("Create", model); 
    } 

如果我創建從一個新的Person另一個人的Details頁面中,我傳入該父Person的ID,然後構造一個包含Parent的viewModel。

的POST看起來是這樣的:

[HttpPost] 
    public ActionResult Create(CreatePersonViewModel viewModel) 
    { 
     if (ModelState.IsValid) 
     { 

      var parent = viewModel.Parent; // This is always null for some reason 

      var person = new Person() { Name = viewModel.Name }; 

      // if it has a parent, build new relationship 
      if (parent != null) 
      { 
       person.Parent = parent; 
       parent.Children.Add(person); 
      }; 

      _db.Save(); 

      return RedirectToAction("detail", "person", new { personId = person.Id }); 
     } 
     return View(viewModel); 
    } 

出於某種原因,視圖模型得到推回POST方法不會包含在GET控制器方法中定義的父。我如何告訴MVC將父母從GET推送到POST,而不會讓父視圖隱藏一個隱藏字段?

萬一有幫助,我的觀點是在這裏:

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

    <fieldset> 
     <legend>CreatePersonViewModel</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Name) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Name) 
      @Html.ValidationMessageFor(model => model.Name) 
     </div> 

     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 

回答

2

控制器動作只會收到明確包含在HTML表單數據。

如果您想要接收父對象,則需要將其置於隱藏的<input>標記中。

請注意,來自客戶端的任何數據都完全受到攻擊者的控制,不能被信任。

+0

我錯了,認爲這不雅?我覺得我應該能夠告訴服務器將數據直接傳遞給相應的POST方法,而不是發送與客戶端無關的數據(並且不必要地將數據公開給攻擊者)。我錯過了什麼嗎? – user2062383 2013-02-17 04:35:40

+0

@ user2062383:是;這不可能。 POST來自客戶端;你不能告訴客戶發送一些東西而不發送給客戶端。考慮使用服務器端會話狀態。 – SLaks 2013-02-18 21:54:56

0

Web是無狀態的,那麼服務器如何知道你想要在幕後傳遞什麼數據?

您可以使用TempData傳遞數據,它將保留在服務器上,直到您的下一個請求被讀取。不過,我不相信你在這裏需要。由於您沒有使用除父ID和名稱以外的任何內容,因此將其存儲在客戶端上 - 即您的viewmodel僅包含這些字段 - 您的viewmodel中沒有實體。

當您發佈到服務器負載您的家長,分配一個新的孩子並保存它。沒有意義將整個對象發送給客戶端。

另外我會在te服務器上驗證當前用戶是否有權訪問這些記錄 - 如果適用的話,除非您的應用程序允許所有用戶訪問所有人員。