【问题标题】:Wizard in asp.NET MVC3 using a static object使用静态对象的 asp.NET MVC3 中的向导
【发布时间】:2011-06-21 11:45:43
【问题描述】:

我正在尝试使用实体框架在 MVC3 中创建一个向导。它需要在几个步骤中保持对象(在本例中为文章)的状态。
我的控制器中有一个静态变量,用于实例化一篇新文章。在不同的操作中,我使用 TryUpdateModel 将表单映射到静态变量。问题是,TryUpdateModel() 似乎也更新了数据库。我需要 TryUpdateModel 进行自动映射,并更新静态 _article 变量,但我不希望它在最后一步之前一直保存到数据库中!

N.B:我知道在 MVC 中创建向导有很多可能的解决方案,但我想知道如何才能使这种方式工作,所以请不要替代 MVC 向导模式。

谢谢。

namespace website.Controllers
{
    public class ArticlesController : BaseController
    {
        // private static variable to hold the chosen article in the wizard
        private static articles _article = new articles();

    /// <summary>
    /// Index page shows a list of articles in a webgrid
    /// </summary>
    /// <returns></returns>
    public ActionResult Index()
    {
        List<articles> _articles = Data.getArticles();
        return View(_articles);
    }

    /// <summary>
    /// First page of the article wizard
    /// </summary>
    /// <returns></returns>
    public ActionResult BasicDetails(string id, string nextButton)
    {

        // back or next doesn't matter - store form values
        if (_article != null) TryUpdateModel(_article);

        if (nextButton != null)
        {
            return RedirectToAction("ArticleGroup");
        }
        else
        {
            _article = Data.GetArticleById(id);
            return View(_article);
        }
    }

    /// <summary>
    /// Second page of the article wizard
    /// </summary>
    /// <returns></returns>
    public ActionResult ArticleGroup(string nextButton, string backButton)
    {
        TryUpdateModel(_article);

        if (backButton != null)
            return RedirectToAction("BasicDetails");
        else if (nextButton != null)
        {
            return RedirectToAction("Price");
        }
        else
        {
            return View(_article);
        }
    }

    /// <summary>
    /// Third page of the article wizard
    /// </summary>
    /// <returns></returns>
    public ActionResult Price(string nextButton, string backButton)
    {

        TryUpdateModel(_article);

        if (backButton != null)
        {
            return RedirectToAction("ArticleGroup");
        }
        else if (nextButton != null)
            return RedirectToAction("LinkedClubs");
        else
        {
            return View(_article);
        }
    }

    /// <summary>
    /// Last page of the article wizard
    /// </summary>
    /// <returns></returns>
    public ActionResult LinkedClubs(string backButton)
    {

        if (backButton != null)
            return RedirectToAction("Price");
        else
            return View(_article);
    }


}
}

【问题讨论】:

  • TryUpdateModel 不更新任何数据库。这是一个 MVC 特定的方法。它甚至不知道您正在使用数据库。它的作用是将提供的模型与请求参数绑定并应用验证逻辑。现在即使您当前的设计是错误的,您也不想要替代品?您直接在视图中使用域模型,而不是使用视图模型。很抱歉这么说,但我担心这样的设计会非常崎岖不平。在 ASP.NET 应用程序中还保留用户特定状态的静态对象!?怎么回事?如果两个用户同时填写向导会怎样?
  • 如果我理解正确,您使用的是静态来保存数据。这在我不知道从哪里开始的 Web 应用程序中是非常错误的。如果您有多个用户(并且它是一个网站,因此您将有多个用户),他们最终将共享该静态数据。他们会看到彼此的变化,覆盖彼此的变化,破坏彼此的变化。这将是一个巨大的混乱。
  • 谢谢你们。我刚刚开始使用 MVC,我了解到控制器中的静态私有变量是每个会话的容器。当然,如果模式被打破,它会回到绘图板上。无论如何,再次感谢您的提醒。

标签: asp.net-mvc entity-framework asp.net-mvc-3 wizard


【解决方案1】:

而不是使用静态变量来保存您的状态信息(顺便说一句,这是一个严重错误),您应该传递一个状态包来保存您在页面之间需要的信息。

【讨论】:

    【解决方案2】:

    通常数据实体(映射到数据库的实体)和视图模型实体(与该用户合作的实体)分开使用。当用户在某个步骤后发布数据时 - 您将 TryUpdateModel() 设置为会话对象(特定于用户,而不是所有应用程序作为静态变量)。 在最后一步,您调用业务逻辑方法UpdateModel(viewmodel),它使用所有填充属性通过视图模型的 id 更新所有列。

    【讨论】:

    • 清除,所以对于向导中的每一步,我都需要使用单独的视图模型,并在最后一步中获取实体,将其更新并保存到数据库中?
    • 是的,你是对的。并且永远不要在控制器中使用静态变量作为用户特定数据的容器:)
    猜你喜欢
    • 1970-01-01
    • 2012-03-19
    • 2011-03-11
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    • 2012-06-23
    相关资源
    最近更新 更多