2012-07-06 87 views
1

我正在ASP.NET MVC3(我的第一個)中開發一個Web應用程序,意思是跟蹤我工作的工程公司的數據處理步驟。Create View for ViewModel post返回具有空外鍵屬性的ViewModel

下面是一些領域模型:

數據集:

Partial Public MustInherit Class Dataset 
    Public Property DatasetID As System.Guid 
    Public Property Name As String 

    Public Overridable Property ProcessDatasets As ICollection(Of ProcessDataset) = New HashSet(Of ProcessDataset) 
    Public Overridable Property DeliveryBatches As ICollection(Of DeliveryBatch) = New HashSet(Of DeliveryBatch) 

End Class 

過程:

Partial Public Class Process 
    Public Property ProcessID As System.Guid 
    Public Property Name As String 
    Public Property Type As String 
    Public Property Description As String 
    Public Property SOP As String 
    Public Property ProcessOrder As Nullable(Of Integer) 

    Public Overridable Property ProcessDatasets As ICollection(Of ProcessDataset) = New HashSet(Of ProcessDataset) 

End Class 

ProcessDataset:(歸因連接表)

Partial Public Class ProcessDataset 
    Public Property ProcessID As System.Guid 
    Public Property DatasetID As System.Guid 
    Public Property OwnerID As Nullable(Of System.Guid) 
    Public Property Started As Nullable(Of Date) 
    Public Property Completed As Nullable(Of Date) 

    Public Overridable Property Dataset As Dataset 
    Public Overridable Property Process As Process 
    Public Overridable Property ProcessOwner As ProcessOwner 

End Class 

我的目標是選擇數據集(使用域模型)的指數或詳細視圖或多個數據集,然後單擊以Add New Process to Dataset(s)一個鏈接,打開這個期望創建視圖。由創建視圖創建的任何ProcessDatasets將自動引用選定的數據集,而用戶不必從列表中選擇它們。

下面是我爲ProcessDataset創建的ViewModel。

ProcessStatusDataset:

Public Class ProcessStatusDataset 

    Public Property ProcessDataset As ProcessDataset 
    Public Property Datasets As IEnumerable(Of Dataset) 

End Class 

控制器方法在ProcessDatasetController:

' 
' GET: /ProcessDataset/Create 

Function CreateProcessStatus(id As Guid) As ViewResult 
    Dim processStatus As New ProcessStatusDataset 
    processStatus.Datasets = db.Datasets.Where(Function(d) d.DatasetID = id) 
    ViewBag.ProcessID = New SelectList(db.Processes, "ProcessID", "Name") 
    ViewBag.OwnerID = New SelectList(db.ProcessOwners, "ProcessOwnerID", "Name") 
    Return View(processStatus) 
End Function 

' 
' POST: /ProcessDataset/Create 

<HttpPost()> 
Function CreateProcessStatus(processstatusdataset As ProcessStatusDataset) As ActionResult 
    If ModelState.IsValid Then 
     For Each dataset In processstatusdataset.Datasets 
      Dim processdataset As New ProcessDataset 
      processdataset.ProcessID = processstatusdataset.ProcessDataset.ProcessID 
      processdataset.OwnerID = processstatusdataset.ProcessDataset.OwnerID 
      processdataset.Completed = processstatusdataset.ProcessDataset.Completed 
      processdataset.Started = processstatusdataset.ProcessDataset.Started 
      processdataset.DatasetID = dataset.DatasetID 
      db.ProcessDatasets.Add(processdataset) 
     Next 
     db.SaveChanges() 
     Return RedirectToAction("Index") 
    End If 

    ViewBag.ProcessID = New SelectList(db.Processes, "ProcessID", "Name", processstatusdataset.ProcessDataset.ProcessID) 
    ViewBag.OwnerID = New SelectList(db.ProcessOwners, "ProcessOwnerID", "Name", processstatusdataset.ProcessDataset.OwnerID) 
    Return View(processstatusdataset) 

CreateProcessStatus查看:

@ModelType ProductionDataTrackingMVC.ProcessStatusDataset 
@Code 
    ViewData("Title") = "Add New Process to Datasets" 
End Code 
<h2> 
    Add New Process to Datasets</h2> 
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 
@Using Html.BeginForm("CreateProcessStatus","ProcessDataset") 
    @Html.ValidationSummary(True) 
    @<fieldset> 
     <legend>Process Status</legend> 
     <div class="editor-label"> 
      @Html.LabelForPascalCase(Function(model) model.ProcessDataset.Process): 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownList("ProcessID", String.Empty) 
      @Html.ValidationMessageFor(Function(model) model.ProcessDataset.ProcessID) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelForPascalCase(Function(model) model.ProcessDataset.ProcessOwner): 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownList("OwnerID", String.Empty) 
      @Html.ValidationMessageFor(Function(model) model.ProcessDataset.OwnerID) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelForPascalCase(Function(model) model.ProcessDataset.Started): 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(Function(model) model.ProcessDataset.Started) 
      @Html.ValidationMessageFor(Function(model) model.ProcessDataset.Started) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelForPascalCase(Function(model) model.ProcessDataset.Completed): 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(Function(model) model.ProcessDataset.Completed) 
      @Html.ValidationMessageFor(Function(model) model.ProcessDataset.Completed) 
     </div> 
     <br /> 
     <div> 
      <table> 
       <tr> 
        <th> 
         Dataset Type 
        </th> 
        <th> 
         @Html.LabelForPascalCase(Function(model) model.Datasets.FirstOrDefault().Name) 
        </th> 
       </tr> 
    @For Each item In Model.Datasets 
     Dim currentItem = item 
       @<tr> 
        <td> 
         @currentItem.GetType().BaseType.Name 
        </td> 
        <td> 
         @Html.DisplayFor(Function(modelItem) currentItem.Name) 
        </td> 
       </tr> 
    Next 
      </table> 
     </div> 
     <p> 
      <input type="submit" value="Add New Process Status" /> 
     </p> 
    </fieldset> 
End Using 
<div> 
    @Html.ActionLink("Back to Process Status Datasets List", "Index") 
</div> 

在這一點上,ProcessStatusDataset傳遞到CreateProcessStatus POST方法總是帶有空白Guids,其中應該有一個ID爲ProcessOwnerDatasets財產也是Nothing

當我看着呈現的頁面我看到的來源:

<form action="/ProcessDataset/CreateProcessStatus/e29bc119-b8c2-4ac5-9ce7-c9780673c193" method="post"> 

當鏈路末端的GUID是在Dataset詳情選擇單Dataset的ID查看。

任何人都可以指向正確的方向。我一直在搜索谷歌沒有運氣。

回答

0

下拉框

我不認爲這會工作:

...

@Html.DropDownList("ProcessID", String.Empty) 

...

相反,你應該嘗試這樣的事:

...

@{ 
    Dim processes = DirectCast(ViewBag.Processes, SelectList); 
} 

@Html.DropDownListFor(Function(model) model.ProcessDataset.ProcessId, processes, "Select Process") 

...

'remember to set this on the post too, in case of returning the same view. 
ViewBag.Processes = New SelectList(db.Processes, "ProcessID", "Name")     

...

這應該讓模型綁定(如果你不知道,你可能想要谷歌這個概念它)去做它的魔力。否則,只需將HttpPost操作方法的返回類型更改爲FormCollection並檢查密鑰以檢查您從帖子中帶回的內容。

數據集問題

我不認爲你設置任何HTML表單字段期望看到的東西回到你的帖子。

+0

我不確定我明白你在這裏建議什麼。你的答案的數據集問題部分是什麼意思? – Brian 2012-07-06 17:14:27

+0

你說過,在你的後期操作中'Datasets'屬性是'Nothing',這是因爲沒有任何字段存儲這些信息在你的html表單中。你是否檢查過我提到的'FormCollection'方法,這可能有助於理解發布結果的情況。 – danielQ 2012-07-06 17:28:37

+0

我明白你在說什麼。我認爲,因爲我將模型傳遞到具有數據集的視圖中,視圖會將相同的模型返回到添加的數據。看來這個視圖創建了一個新的模型來回傳?我將如何使數據集保留在發回控制器的模型中?順便說一句,你的下拉建議工作,謝謝。 – Brian 2012-07-06 17:36:06