2012-11-28 83 views
3

我正在進入我第一次嘗試使用MVC4進行Web開發,並且遇到了一個我剛纔知道的一般問題是Web開發中的核心問題之一,但似乎無法將我的思想包裹在內。在MVC4中的控制器之間傳遞模型

所以我有兩種型號:EmployeeCompanyEmployee具有Company,因此/Employee/Create包含一個字段,或者爲如果不存在選擇現有Company,或者ActionLink/Company/Create的下拉列表。 但問題在於:如果用戶必須創建Company,則需要在兩個視圖中保留現有的Employee模型 - 超過/Company/Create,然後返回/Employee/Create

所以我的第一種方法是在Employee模型傳遞到/Company/Create@Html.ActionLink("Add...", "Create", "Organization", Model , null),但後來當我到達CompanyCreate(Employee emp),所有emp的的價值觀是null

第二個問題是,如果我嘗試返回/Employee/Create,我會傳回Employee,這將解決爲POST操作。

基本上,整個思路是拯救/Employee/Create頁的狀態,跳轉到/Company/Create創建Company記錄,然後回到/Employee/Create完成創建Employee。 我知道有一個很好理解的解決方案,因爲,但我似乎無法將其良好地分階段,以獲得良好的Google結果。

我雖然已經關於使用會話,但似乎這樣做將是一個有點雜牌的。我真的很喜歡這個優雅的解決方案。

編輯:很難相信這個問題沒有標準的解決方案。感覺這應該是使用HTTP的最基本的單一問題。

回答

2

所以它看起來像你的主要問題是缺乏數據源爲四十二說,或更普遍的某種持久性。這可以通過將數據庫作爲數據源來支持您的Model,這可能是您想要的永久解決方案。另一種選擇是使用會話。如果這不是生產代碼,並且您需要某些「工作」,會話將是一個快速解決方案。我傾向於查看Entity Framework Code First方法(因爲它比較簡單,並且可以根據當前模型創建數據庫)。

你提到你是MVC的新手,所以我會推薦[Intro to ASP.NET MVC 4] [1] 這是一個非常容易學習初學者的教程。我甚至從那個開始。

編輯

我會用它爲奇數,以創造一種在一個數據庫,後來需要進行清理,如果用戶放棄在網頁「臨時」條目的認同。我有一個想法是使用ajax(通常我喜歡在jQuery庫的幫助下做到這一點)。我不知道你對圖書館的知識是什麼,但我的基本前提是如下:

  1. 用戶單擊其中一個按鈕。
  2. 通過對您的控制器使用異步調用,您需要完成一些工作並返回結果。你的控制器方法可能需要返回一個JSONResult。
  3. 使用此結果,您更新您的視圖。我的想法是使用結果填充表單。
  4. 現在用戶可以點擊「提交」併發送到一個方法,然後更新/保存到數據庫。

如果你不熟悉jQuery,你可能想看看它。

發表有關使用jQuery和JsonResult:https://stackoverflow.com/a/9463272/1200520

+0

我*使用EF代碼優先。但問題是,在用戶點擊「提交」之前,我在數據庫中創建記錄似乎很瘋狂。「如果用戶離開創建一個公司,但放棄了一半,那麼現在我的數據庫中有一個員工的無用的半成品記錄。 –

+0

我已經編輯了上述答案。 –

+0

看起來這將是我現在的計劃是開始學習JQuery和AJAX方法,在「創建員工」頁面中顯示「創建公司」對話框。謝謝! –

0

你不能在URL中通過周圍的物體(GET請求),這就是爲什麼值在你的第一種方法全部無效。通常,您將使用EmployeeId作爲參數傳遞,然後從控制器中的數據源重新獲取Employee對象。

所以,你的鏈接將

@Html.ActionLink("Add...", "Create", "Organization", new { id = Model.EmployeeId }, null) 

和動作方法

public ActionResult Create(int id) 
{ 
    //hit the db to grab the Employee by id 
} 

這是處理在asp.net mvc的這種情況下的典型方式。

+0

但就是這樣。在用戶點擊「創建公司」鏈接時,「僱員」將不會被髮布,因此沒有「Id」可以放入URL中。整個想法是保存'/ Employee/Create'頁面的狀態,跳轉到'/ Company/Create'來創建'Company'記錄,然後返回到'/ Employee/Create'來完成'Employee' '。 –

0

你可以使用TempData的將數據存儲到一個請求。 http://www.devcurry.com/2012/05/what-is-aspnet-mvc-tempdata.html

您還可以使用POST請求,這也是相當不錯的常用解決方案。

您也可以考慮在ajax模式中添加公司並刷新下拉值。

+0

在單服務器開發環境中可能會正常工作,但如果生產站點處於打開狀態一個農場,它會停止工作,堅持視圖上的臨時數據將攜帶請求之間的值 –

1

您是否知道<input type="submit" name"createEmployee" value="Create Employee" /> name屬性在POST請求中作爲參數傳遞,默認的ModelBinder會綁定它?

這意味着,您可以在一個表單上有多個提交按鈕。

比方說,你有一個視圖模型,如:

public class CreateCompanyWithEmployeeModel 
{ 
public Employee Employee { get; set; } 
public Company Company { get; set; } 

public string createEmployee { get; set; } 
public string createCompany { get; set; } 

public string State { get { return (String.IsNullOrEmpty(createCompany)) ? "createEmployee" : "createCompany"; }} 
} 

當然,這些自定義類型爲你的員工和公司,如:

public class Employee 
{ 
    // Employee properties here 
} 

public class Company 
{ 
    // Company properties here 
} 

然後你就可以有這樣一個動作:

public ActionResult CreateCompanyWithEmployee(CreateCompanyWithEmployeeModel model) 
    { 
     switch (model.State) 
     { 
      case "createEmployee": 
       // Do your createEmployee Stuff 
       break; 
      case "createCompany": 
       // Do your createCompany Stuff 
       break; 
      default: 
       throw new NotImplementedException(String.Format("State {0} not implemented", model.State)); 
     } 
     return View(); 
    } 

而在視圖中,您將擁有如下表格:

<% using(Html.BeginForm()) { %> 

    <%=(Model.State == "createEmployee") ? Html.EditorFor(Model.Employee) : Html.DisplayFor(Model.Employee) %> 
    <%=(Model.State == "createCompany") ? Html.EditorFor(Model.Company) : Html.DisplayFor(Model.Company) %> 

    <input type="submit" name="<%=Model.State%>" value="Submit" /> 

<% } %> 

然後,您只需根據您的情況構建您的EditorForDisplayFor控件即可。如果您不想在公司創建期間顯示員工,那麼您只需使用HiddenFor即可將員工數據保留到表單中,直到公司編輯完成。在員工完全有效之前沒有顯示公司數據。

我知道這個例子並不完全乾淨,但爲了清晰的方法,我需要保持這個簡單。基本上,如果你使用這種方法很多,你會讓ViewModel繼承一個處理視圖模型狀態處理的接口,並且你將有定製的Html Helpers根據狀態等等來呈現表單。

我們使用這種方法很多。它適用於全球所有瀏覽器。

+0

這是我提出的答案。 –

0

你必須做出這樣的解決方法:

  1. 字符串屬性添加到公司的模型,命名EncodedEmployee
  2. 顯示你的創建員工查看你現在正在做的方式。用戶可以點擊「創建公司」鏈接。
  3. 當用戶選擇「創建公司」時,請確保一個名爲「CreateCompanyFirst」的Action被調用。這一行動將是這樣的:

    public ActionResult CreateCompanyFirst(Employee emp) 
    { 
        string jsonemp = Json(emp); 
    
        Company emptyCompany = new Company{}; 
    
        emptyCompany.EncodedEmployee = jsonemp ; 
    
        return View(emptyCompany); 
    } 
    
  4. 當「創建公司視圖」獲取呈現,請務必將EncodedEmployee的屬性保存在一個隱藏字段。

  5. 我猜你已經爲創建公司實施了一項操作。下面這段代碼需要略作修改:

    public ActionResult CreateCompany(Company cmp) 
    { 
        // Save your company 
    
        // if cmp.EncodedEmployee is not null 
    
         // De serialize the employee, return View(employee) 
    
        // else return what you were returning before 
        // (maybe "thanks for creating a company, come back soon") 
    } 
    
  6. 你會回到你的員工的屏幕,作爲填補前場。

顯然這意味着views/actions/routes是功能性的,並沒有期待或做任何魔術調整,否則它不會工作。

相關問題