【问题标题】:Pass complex object with redirect in ASP.NET MVC?在 ASP.NET MVC 中通过重定向传递复杂对象?
【发布时间】:2011-03-23 18:30:39
【问题描述】:

嗨,

我有一个看起来像这样的操作:

[AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Register(AdRegister adRegister, IEnumerable<HttpPostedFileBase> files)

AdRegister 是一个复杂的类,我需要在 Register 操作中将它传递给重定向方法,如下所示:

return this.RedirectToAction("Validate", adRegister);

验证操作如下所示:

public ActionResult Validate(AdRegister adRegister)

我知道我可以传递简单的参数,但在这种情况下它是一个复杂的对象。此示例不起作用,adRegister 的属性将为空。

这可能吗?如果可以,怎么做?

致以最诚挚的问候

更多信息: 注册操作将使用 adRegister 并对其进行一些魔术,然后将其发送到验证操作。 Validate 操作将向用户返回一个验证页面。当用户点击授权按钮时,adRgister 将从表单中填写,然后发送到将保存的 vValidate 帖子。我已经考虑将 adRegister 暂时放在缓存或数据库中,但如果我可以简单地将它传递给下一个操作会更好。

【问题讨论】:

    标签: c# .net asp.net-mvc controls action


    【解决方案1】:

    一种可能性是在查询字符串中传递简单的属性:

    return RedirectToAction(
        "Validate", 
        new { 
            foo = adRegister.Foo, 
            bar = adRegister.Bar, 
            ... and so on for all the properties you want to send
        }
    );
    

    另一种可能性是将其存储在 TempData(针对重定向的生命周期)或 Session(针对 ASP.NET 会话的生命周期):

    TempData["adRegister"] = adRegister;
    return RedirectToAction("Validate");
    

    然后从 TempData 中检索它:

    public ActionResult Validate()
    {
        adRegister = TempData["adRegister"] as AdRegister;
        ...
    }
    

    另一种可能性(也是我向您推荐的一种)是将这个对象持久保存在数据存储区的 POST 方法中:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Register(AdRegister adRegister, IEnumerable<HttpPostedFileBase> files)
    {
        ...
        string id = Repository.Save(adRegister);
        return RedirectToAction("Validate", new { id = adRegister.Id });
    }
    

    然后在重定向后从数据存储中获取它:

    public ActionResult Validate(string id)
    {
        AdRegister adRegister = Repository.Get(id);
        ...
    }
    

    【讨论】:

    • 好的,那么它不可能将复杂对象直接发送到动作。 TempData 的问题可能是用户刷新页面。最好的方法是将其存储在数据库中,然后以设定的时间间隔运行清理(用户可以进入第 2 阶段然后中止,如果是这样,数据仍将在数据库中)。
    • @SnowJim,是的,您对用户刷新页面是正确的。这就是为什么我不建议你使用它。最好的办法是存储在数据库或Session中。
    • @Darin Dimitrov,是的,会话可能是要走的路,我不必清理数据库。唯一的问题是,如果最终用户的提交速度很慢,但我想我可以将会话超时设置为 60 分钟。那应该这样做。这也将占用更多的服务器内存,但它根本不会涉及数据库。假设我决定将它保存在数据库中,目标表会受到很多影响,创建表的副本并将临时数据放在那里更好吗?
    • @SnowJim,如果只是临时数据,会话可能更有意义。但是,如果以后可以重用这些数据,最好将其永久存储在数据库中。当然你也可以使用一个临时表,但是如果你决定走这条路,你可以配置你的session provider to use SQL server,这样它就不会存储在内存中,它会自动进入数据库。这样你就不会在服务器上消耗内存,也不应该关心持久性=>它是透明的。
    • @Darin Dimitrov,感谢您的帮助!在这种情况下,用户将 1. 填写表单并点击提交 2. 该操作将获取用户想要发布的广告 3. 触发验证操作并将广告数据发送回用户 4.a 结束用户授予广告,然后将其保存在数据库 4.b 中返回带有广告的注册表单(使用已知数据自动填写表单)。这是复杂对象的生命周期。
    【解决方案2】:

    一个想法可能会创建一个会话变量并传递一个引用该会话变量的键,如果对象需要跨几个视图?

    【讨论】:

    • 是的,这可以工作,唯一的问题是如果用户需要很长时间提交页面,会话可能已经被删除。那么最好将其存储在数据库中。但话又说回来,会话超时可以设置为 60 分钟,这应该足够了。
    • 如果这个工作流是特定的,那将需要很长时间并且需要保持会话实时,通过定期 ajax 调用保持会话实时比设置会话超时更好......
    【解决方案3】:

    ASP.NET MVC 的临时数据应该是完美的。

    也就是说,TempData 或 Session 是一种选择,但也有一些缺点,例如非常违反并且经常模糊或难以调试。可能更可取的是将临时值“存储”在持久存储中,例如用户的配置文件或您自己的数据库,然后通过 validate 方法传递一个密钥,然后该方法可以从所述存储加载数据。这也开启了回收废弃手推车等的可能性。

    【讨论】:

    • 啊哈我确实有一个缓存,我可以设置计时器。我可以将对象存储在此缓存中,然后每次 ti 用户提交时将超时更新为 60 分钟或类似的时间。这意味着我不必手动清理数据库,如果用户做了一些奇怪的事情,比如刷新等,我仍然可以恢复数据。
    • 要小心——在大多数情况下,ASP.NET 缓存比会话存储更违反。当内存不足时,它是第一个受到攻击的东西。我会使用缓存上的会话来获取用户数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 2016-05-27
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多