【问题标题】:Use the same instance of model view across views in ASP MVC 3在 ASP MVC 3 中跨视图使用相同的模型视图实例
【发布时间】:2012-04-18 13:31:53
【问题描述】:

我有两个视图:第一个有一个表单,当它提交时,它会填写一个模型视图 (QuizzModelView)。

现在提交后,我被重定向到另一个视图,该视图也有一个我要提交的表单。问题是我想对两个视图使用相同的 QuizzModelView。这意味着,在提交第二个表单时,我还想提交前一个表单的值。我可以通过创建隐藏输入来做到这一点,这些输入采用来自第一个视图的值。

有没有办法在没有隐藏输入的情况下做到这一点。

谢谢

编辑: 解释更多:

我的模型视图包含:QuizzModelView.field1、QuizzModelView、.field2

  • 第一步:View1将填写QuizzModelView.field1

  • 第二步:我被重定向到 view2

  • 第三步:View2将填写QuizzModelView.field2

现在我希望能够获取 QuizzModelView.field1 和 QuizzModelView.field2。但我只得到 QuizzModelView.field2 因为提交 View2 时 QuizzModelView.field1 丢失了

这是我的行动:

[HttpPost]
public ActionResult TAFPart2PopupEvents(QuizzModelView model)
{
    return PartialView("PartialViews/_TAFPart2PopupEvents", model);
}


[HttpPost]
public ActionResult TAFPart3PopupEvents(QuizzModelView model)         
{
    // here I want to use 
    // model.field1 and model.field2
}

【问题讨论】:

  • 创建一个视图,将您的QuizzModelView 和其他成员包含在一个对象中。显示该对象,然后提交并接受该视图模型? (虽然你描述的方式有点模棱两可,更详细的会很好)。
  • 两个视图是否都将QuizzModelView 定义为模型?例如@model QuizzModelView 并通过 (View(model: Quizz))?
  • 是的,他们有。问题是在第二个视图中提交表单时,会创建另一个 QuizzModelView 实例,因此之前的值会丢失。
  • 那么你也可以发布操作吗?

标签: asp.net-mvc-3 model-view


【解决方案1】:

技术上(学究式地),您将无法使用模型的同一个实例。但是,您可以将其放入会话中并通过重定向传递。 Session 的优点是不像隐藏字段那样容易被篡改。另外,您不必为每个步骤实际绑定整个模型 - 只需每个步骤中的单个字段:

[HttpPost]
public ActionResult TAFPart2PopupEvents(string field1)
{
    QuizzModelView model = new QuizzModelView();
    model.Field1 = field1
    Session["Quiz"] = model;

    return PartialView("PartialViews/_TAFPart2PopupEvents", model);
}

[HttpPost]
public ActionResult TAFPart3PopupEvents(string field2)         
{
    var model= (QuizzModelView )Session["Quiz"];

    // Fill in field2 here
    model.Field2 = field2;

}

编辑:用一些实际细节来解决布赖恩的评论 -

这种带有会话的方法比隐藏字段更不容易受到数据篡改的影响,如果这是一个问题的话。通过视图中的隐藏字段,恶意用户可以轻松覆盖以前的数据。根据模型的大小,隐藏字段也可能会使视图膨胀。

会话也有过期的缺点。这是处理过期的简单方法。如果这是通过 Ajax 调用的,那么您必须将错误消息传递回客户端而不是在那里进行处理。

[HttpPost]
public ActionResult TAFPart3PopupEvents(string field2)         
{
    var model= Session["Quiz"] as QuizzModelView;

    if (model == null)
    {
        // Add some kind of message here.
        // TempData is like Session, but only persists across one request.
        TempData["message"] = "Session Expired!";

        return RedirectToAction("Index");
    }

    // Fill in field2 here
    model.Field2 = field2;

    ....
}

【讨论】:

  • 如果您还没有依赖会话,我会在会话中使用隐藏输入。
  • 是的,我知道隐藏输入更简单,但是在问题中我放了一个简单版本的代码,实际上我有 30 多个字段和 2 个以上的视图,所以在最终视图中我会有真的有很多隐藏的输入。这不会是个问题吗?
  • 拥有 30 多个字段,会话听起来更容易。或者删除临时数据库表中的每个步骤(分配给登录用户,以防他们离开中间),但这是完全不同的情况。如果每个步骤都在逐步添加更多隐藏字段,那么更改字段名称之类的事情将是一个更大、更容易出错的更新痛点。通常,如果您可以避免将应用程序状态存储在视图中,那将是一件好事。
  • 我同意 30 多个字段可能太多,无法通过隐藏输入传递。但是,如果会话无效,听起来也会丢失很多输入。如果愤怒的用户(由于会话到期丢失输入)是可能的,我会寻找比会话更永久的东西,比如暂时将其保存到数据库。
【解决方案2】:

如果您希望 TAFPart3PopupEvents 操作能够访问数据,则需要将其存储在某个地方。有许多不同的选项(会话、查询字符串、数据库),但我认为隐藏输入(通常)是最简单的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-02
    • 2011-07-15
    • 1970-01-01
    • 2021-04-23
    • 2011-07-29
    • 2011-06-30
    • 2014-02-21
    • 1970-01-01
    相关资源
    最近更新 更多