簡體   English   中英

C#類實例保存字符串引用但不包含對象引用

[英]C# Class Instance Holding String Reference But Not Object Reference

好吧,所以我花了整整五個或六個小時來解決這個問題。 我相信,我正在使用ASP.NET MVC 4和EF 5.0在C#中工作。 這是我的問題:我的控制器中有一個方法采用自定義類作為參數(這些名稱已被糖果主題混淆了:P)。 ViewError類如下所示:

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);
}

根據我的理解,這都應該起作用。 現在這是一個很奇怪的部分-我可以通過調試消息和“監視”窗口(使用Visual Studio)確認ViewError是否已正確創建並在其ModelObject中保留了ViewModel的深層克隆(我必須將其轉換回來,因為EatCandy方法期望將EatCandyViewModel作為參數)。 但是,當我前進並將ViewError傳遞給EatCandy時,其中的ModelObject為null! 我最初以為這是因為它僅將viewModel的引用傳遞給對象,並且正在收集垃圾,這就是為什么我添加了Clone()方法的原因。 字符串,它也是一個引用類型,但是通過了。 為什么不是物體? 有人知道嗎?

如果您需要更多信息,請詢問。 並且無視此數據庫的荒謬性-我故意對其進行混淆,而不僅僅是愚蠢。

這行不通。 RedirectToAction導致瀏覽器無法訪問302,而該瀏覽器無法承載復雜的模型。

有一些替代方法,您可以使用TempData來存儲模型,進行重定向並檢索數據。 您甚至可以直接調用EatCandy操作而不是重定向,但是自動匹配視圖將不起作用,並且您必須在EatCandy操作結束時強制使用“ EatCandy”視圖名稱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM