2013-07-26 53 views
1

好的,所以我花了大約五六個小時工作在這個無濟於事。我正在C#中使用ASP.NET MVC 4和EF 5.0,我相信。這裏是我的問題:我的控制器中有一個方法需要一個自定義類作爲參數(這些名稱已被糖果爲主題混淆:P)。該ViewError類看起來像這樣:C#類實例保存字符串引用但不是對象引用

public class ViewError<T> where T : class 
{ 
    public T ModelObject { get; set; } 
    public string Message { get; set; } 

    public ViewError(string message, T modelObject) 
    { 
     Message = message; 
     ModelObject = modelObject; 
    } 

    public ViewError() 
    { 
     Message = null; 
     ModelObject = default(T); 
    } 
} 

(這是一個通用的,所以我可以找出什麼類型的ModelObject是從代碼中這是無關緊要的,雖然,我已經測試過它取一個通用的「對象」。並且發生同樣的問題。)

控制器方法看起來像這樣。它所要做的就是詢問誰在吃糖果,如果有ViewError,它會顯示消息。 (視圖有一個顯示ViewBag.Message的段落)。

public ActionResult EatCandy(ViewError<EatCandyViewModel> error) 
{ 
    ViewBag.BrandList = new SelectList(db.Brands, "ID", "Name"); 
    // If there's a notification, pass it to the view, along with the model 
    if(error.Message != null) 
    { 
     ViewBag.Message = error.Message; 
     return View(error.ModelObject); 
    } 
    return View(); 
} 

在後:

[HttpPost] 
public ActionResult EatCandy(EatCandyViewModel viewModel) 
{ 
    if(ModelState.IsValid) 
    { 
     CandyEater eater = (CandyEater)viewModel; 
     db.CandyEaters.Add(eater); 
     db.SaveDatabase(); // Custom convenience wrapper for SaveChanges() 
     return RedirectToAction("ChooseCandyToEat", eater); 
    } 
    return View(viewModel); 
} 

漂亮的標準的東西。現在,在ChooseCandyToEat方法中,它提出了一個特定品牌可用的糖果列表。如果該品牌沒有任何可用的糖果,我希望它發送一個錯誤回到EatCandy方法(通過ViewError對象),告訴他們沒有糖吃,並將模型發回,以便食客不會吃糖,不得不再次輸入他們的信息,只需選擇不同品牌的糖果。

public ActionResult ChooseCandyToEat(CandyEater eater) 
{ 
    // Get the list of candy associated with the brand. 
    IEnumerable<Candy> candyList = db.Candies.Where(b => b.Brand == eater.DesiredBrand) 
              .Where(e => !e.Eaten); 
    // If the brand has no candy, return an error message to the view 
    if(candyList.Count() == 0) 
    { 
     EatCandyViewModel viewModel = (EatCandyViewModel)eater; 
     ViewError<EatCandyViewModel> viewError = new ViewError<EatCandyViewModel>("Oh noes! That brand has no candy to eat!", viewModel.Clone()); // This is a deep clone, but even if it wasn't, it would still be weird. Keep reading. 
     return RedirectToAction("EatCandy", viewError); 
    } 
    return View(candyList); 
} 

根據我的理解,這應該都是可行的。現在,這是一個奇怪的部分 - 我可以通過調試消息和Watch窗口(使用Visual Studio)確認ViewError已正確創建,並且在其ModelObject中保留了viewModel的深層克隆(我必須將其轉換回來,因爲EatCandy方法需要一個EatCandyViewModel作爲參數)。但是,當我向前一步並將ViewError傳遞給EatCandy時,其中的ModelObject爲null!我原本以爲這是因爲它只傳遞了viewModel的引用到對象中,並且正在收集垃圾,這就是爲什麼我添加了Clone()方法的原因。儘管如此,字符串也是參考類型。爲什麼不是對象?有人知道嗎?

如果您需要更多信息,只需詢問。而忽視這個數據庫的荒謬 - 我故意混淆了它,不僅僅是愚蠢。

回答

0

這是行不通的。 RedirectToAction會在瀏覽器中產生一個302,但它不能承載複雜的模型。

還有一些選擇,你可以使用TempData存儲模型,做重定向和檢索數據。您甚至可以直接調用EatCandy操作而不是重定向,但是與視圖匹配的自動功能無效,您必須在EatCandy操作結束時強制使用「EatCandy」視圖名稱。

+0

好的,謝謝。我已經構建了一些函數來操作TempData並傳遞錯誤 - 很高興知道這是一種有效的方法。 –

相關問題