3

情况:在一些用 asp.net 编写的项目管理软件中,我有一个创建项目页面(工作正常)。我需要添加将任务从模板列表添加到此项目预创建的能力,但可用任务列表取决于创建表单中的某些值。

我的抽象解决方案是这样的:

  • 我有一个“创建”视图和一个“添加任务”视图 - 都强类型到控制器中定义的复合视图模型
  • 我的 Create 方法检查使用哪个按钮来调用它 - 如果按钮是“添加任务”,它会呈现 AddTasks 视图,从创建视图传递模型,再次全部在同一个控制器中。
  • AddTasks 视图使用两个按钮之一发布到创建视图,一个加载视图,另一个导致实际的数据库保存。

我的问题是这样的:

  • 不同的视图使用相同模型的不同属性,但是在它们之间传递这个模型时,数据被重置(在任何情况下都重新加载或保存)。
  • 我猜这是由于数据的自动绑定而发生的——尽管我认为表单上不存在的字段不会覆盖传递下来的现有模型数据。
  • 目前在控制器中几乎没有任何代码来操作模型——在这些情况下,它只在视图之间传递。

这是控制器代码:

    // POST: /Project/Create/<viewModel>
    [Authorize, AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create([Bind(Exclude = "Id,id")] ProjectViewModel model)
    {
        if (model.SubmitValue == "Create")
        {
            try
            {
                model.Project.Id = Guid.NewGuid();
                model.Save(this.User.Identity.Name);
                return this.RedirectToAction("Details", new {id = model.Project.Id});
            }
            catch (Exception e)
            {
                this.ModelState.AddModelError(e.ToString(), e.ToString());
            }
            return View(model);
        }

        if(model.SubmitValue == "AddTasks")
        {
            return this.View("AddTasks",model);
        }

        return this.View(model);

    }


    //POST: /Project/AddTasks/ + model
    [Authorize, AcceptVerbs(HttpVerbs.Post)]
    public ActionResult AddTasks([Bind(Include = SelectedCarrierTasks")]ProjectViewModel model)
    {
        return View(model);
    }

问题是:如何在这些视图中维护模型的状态,直到最终保存它?

我宁愿避免使用任何 hackish(TempData)或 JS 依赖的解决方案,但如果它们真的是最好的解决方案,我不会拒绝这些。

谢谢,亚当托利

4

4 回答 4

3

一个简单的解决方案是将 ViewModel 对象保存在 Session 变量中,并从这个源绑定 View。这当然不是最优雅的解决方案。另一种选择,可能不太优雅,是将此模型数据保存在数据库中,并带有一些临时/未保存的标志。

于 2009-11-05T16:58:21.967 回答
2

问题是当您显示添加任务视图时,您没有为“项目”对象提供字段,因此ModelState会丢失与项目相关的数据,您需要提供此字段以确保您不会丢失该数据。

您不需要显示这些字段,它们可以是隐藏类型,并且它们将保留值。只要确保如果您将绑定到视图模型,您将需要像这样正确命名这些字段Model.Project.Property

于 2009-11-05T16:24:21.600 回答
2

也许我正在尝试解决错误的问题(ala Bruce Eckel)。我将尝试转移到不需要这种模糊边界的结构。我不想仅仅将 REST 范式硬塞进一个有状态的应用程序中。

可能这些控件属于同一页面,我可以使用一些 JQuery 优点将其放入选项卡窗格中,以便于查看。

感谢那些回答的人,我发现每一个都很有用,一旦我有更多的代表,我会尽量记住给他们投票。

于 2009-11-06T17:21:26.470 回答
1

目前我无法评论其他人的问题,但唯一真正的选择是会话,如果您想在 Web 请求期间保持对象状态,或者将其序列化并将其放置在隐藏字段中。

或者最后一个选择是更改页面的工作方式,以便您可以在每次请求后保存对象......

如果您使用 nHibernate,那么您可能需要查看对话模式,但这实际上只是将 nHibernate 会话保存到 asp.net 会话中......

于 2009-11-06T14:08:52.123 回答