2012-12-09 87 views
0

我似乎無法通過ViewBag或ViewData傳遞任何數據到視圖。它只是繼續返回null。mvc3查看viewdata和viewbag爲空

的ViewResult代碼:

public ViewResult EditProduct(Guid id) 
    { 
     var product = _repository.Products.FirstOrDefault(x => x.ID == id); 

     ViewData["Categories"] = _repository.Categories; 
     ViewData["CategoryList"] = _repository.Categories.Select(x => new SelectListItem { Text = x.Name, Value = x.ID.ToString(), Selected = product.ID == x.ID }); 
     ViewBag.Test = "Hello"; 

     return View(product); 
    } 

,這是剃刀代碼:

@model NightingalecrossMVC.Domain.Entities.Product 
@{ 
    var test = ViewData.Eval("CategoryList"); 

    var test2 = ViewBag.Test; 

    ViewBag.Title = "Edit Treatment"; 

    AjaxOptions ajaxOpts = new AjaxOptions 
    { 
     UpdateTargetId = "saveData", 
     HttpMethod = "Post", 
     LoadingElementId = "loader" 
    }; 
} 

這究竟是爲什麼?它適用於任何其他視圖?!

回答

0

原因讓空值是因爲我有這樣的:

public ViewResult CreateProduct() 
    { 
     return View("EditProduct", new Product()); 
    } 

它需要的是這樣的:

public ViewResult CreateProduct() 
    { 
     ViewBag.CategoryList = _repository.Categories.Select(x => new SelectListItem { Text = x.Name, Value = x.ID.ToString() }); 
     return View("EditProduct", new Product()); 
    } 

編輯

其實你不能讓一個selectlistitem列表像那樣,因爲LINQ中的ToString()方法,它需要用{}而不是新的SelectListItem來延長,以便從中獲得適當的功能。但是這樣會降低可讀性。所以最好的解決方案是創建一個返回IEnumerable的函數,然後你可以創建一個SelectList。

關於使用SelectList並且DropDownList不支持該過載,一直存在爭議。但是SelectList確實實現了IEnumerable,因此不應該支持SelectList。

+0

我很高興你找到了解決方案。如果有疑問,您可以隨時設置一個虛擬值 - 例如一個字符串 - 並通過它來確定問題是否存在於您的控制器或剃刀視圖中。您也可以在控制器上設置一個斷點,並在您想要調試的變量上加上一個監視點,然後使用f10逐行執行。我也意識到你可以在前一天在Razor視圖中添加斷點。在這種情況下,您最好使用ViewModel而不是ViewData - http://msdn.microsoft.com/en-us/vs2010trainingcourse_aspnetmvc3fundamentals_topic7.aspx。 –

+0

我嘗試了一個ViewModel,並沒有很好地工作,我認爲這個問題沒有可擴展性,所以一個ViewModel會矯枉過正。與斷點有關的問題是,我不知道CreateProduct正在調用EditProduct,因此當我在EditProduct中放置斷點時沒有任何命中。但是在那時,當我開始在某些時候突破並想出執行代碼的位置時,我很快發現問題的真正根源。 –

+0

當然,但您的ViewModel只能是實體的財產,例如'公共實體類型YourEntity {get;設置;};'和ViewModel中的其他屬性。然後在你的資源庫/服務中,有一個像'GetEntityEditViewModelID'這樣的方法,它創建並清空ViewModel的實例,然後做與ViewBag完全相同的事情(但是將其填充到ViewModel中)。這樣做的額外計算成本將會非常小,您將在GET和POST之間使用一致的ViewModel,並且最終您的控制器上的代碼庫代碼會更少。 –