繁体   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