【问题标题】:How to persist a data set between MVC calls如何在 MVC 调用之间持久化数据集
【发布时间】:2009-03-24 19:26:59
【问题描述】:

下面的设置方法可行,但不是正确使用 TempData,第一次使用后会掉下来。我怀疑我应该使用 ViewData,但我正在寻找一些指导以正确使用它。

在我的 Home 控制器中,我有一个 Index 操作,显示哪些成员需要创建字母:

Function Index() As ActionResult
    Dim members = GetMembersFromSomeLongRunningQuery()
    TempData("members") = members
    Return View(members)
End Function

在索引视图中,我有一个创建字母的链接:

<%=Html.ActionLink("Create Letters", "CreateLetters", "Home")%>

回到 Home 控制器,我有一个 CreateLetters 函数来处理这个:

Function CreateLetters() As ActionResult
    Dim members = TempData("members")
    For Each member In members
        '[modify member data regarding the letter]
    Next
    TempData("members") = members
    Return RedirectToAction("Letter", "Home")
End Function

最后,有一个创建实际字母的字母视图。它的 ContentType 是“application/msword”,所以数据实际上是在 Word 而不是浏览器中出现的。

就像我说的,这在第一次通过时效果很好。但是,由于字母出现在 Word 中,当用户返回浏览器时,他们仍然坐在带有“创建字母”链接的屏幕上。如果他们再次尝试点击它(即第一次尝试后卡纸),他们会在 CreateLetters 中收到错误,因为 TempData("members") 现在是空的。我知道 TempData 是这样工作的(单次请求),这就是我试图摆脱它的原因。

如何将其重构为使用 ViewData?或者,如何同时显示 Letter 页面(即 Word 文档)并将应用重定向回索引?

【问题讨论】:

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


    【解决方案1】:

    我只是在另一个视图上再次检索该对象,但为什么不在第一次检索时缓存该对象

    Function Index() As ActionResult
        Dim members = GetMembersFromSomeLongRunningQuery()
    
    // Pseudo code (am a C# man sorry)
        Cache.Remove("MembersItem")
        Cache.Add(members,"MembersItem", CacheExpiry....)
    
        TempData("members") = members
        Return View(members)
    End Function
    
    
    Function CreateLetters() As ActionResult
        Dim members = Cache.Get("MembersItem")
    
        For Each member In members
            '[modify member data regarding the letter]
        Next
        TempData("members") = members
        Return RedirectToAction("Letter", "Home")
    End Function
    

    您还应该考虑将查询结果缓存指定时间或使其依赖于更新。如果会话对象是用户特定的数据,您也可以使用它。

    【讨论】:

      【解决方案2】:

      TempData 旨在通过重定向保留数据,而 ViewData 旨在将数据传递给视图。尽管 TempData 可以通过创建可以在 Letter 操作中调用的扩展方法(以及替换 TempData("members") = members CreateLetters 中的一行)

      using System.Web.Mvc;
      
      namespace GoFetchV2.ExtensionMethods
      {
          public static class TempDataExtensions
          {
              public static void Keep( this TempDataDictionary tempData, string key )
              {
                  var value = tempData[ key ];
                  tempData[ key ] = value;
              }
          }
      }
      

      类似...

      Function CreateLetters() As ActionResult
          Dim members = TempData("members")
          ' Do something with members but want to keep it for the next action '
          TempData.Keep("members")
          Return RedirectToAction("Letter", "Home")
      End Function
      
      Function Letter() As ActionResult
          Dim members = TempData("members")
          ' Do something with members but want to keep it for the next action '
          TempData.Keep("members")
          ' Return the msword binary data '
      End Function
      

      【讨论】:

      • 那么更合适的方法是什么?
      【解决方案3】:

      你能把它塞进一个应用程序变量吗?应用程序(“成员”)?

      【讨论】:

      • 你能解释一下为什么而不仅仅是讽刺吗?连个链接?作为一个从未使用过“经典 ASP”,甚至没有使用过经典 ASP.NET(网络表单)的人,这样的 cmets 本身意义不大。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 2011-09-03
      • 2013-02-21
      • 2011-12-20
      • 1970-01-01
      相关资源
      最近更新 更多