TempData

ASP.NET MVC的TempData用于传输一些临时的数据,例如在各个控制器Action间传递临时的数据或者给View传递一些临时的数据,相信大家都看过“在ASP.NET页面间传值的方法有哪几种”这个面试题,在ASP.NET MVC中TempData的就是其中的一种传值方法。TempData默认是使用Session来存储临时数据的,TempData中存放的数据只一次访问中有效,一次访问完后就会删除了的。这个一次访问指的是一个请求到下一个请求,因为在下一个请求到来之后,会从Session中取出保存在里面的TempData数据并赋值给TempData,然后将数据从Session中删除。我们看一下ASP.NET MVC Preview5源码:

image

也就是说TempData只保存到下一个请求中,下一个请求完了之后,TempData就会被删除了。注意这里TempData使用Session来做存储的,Session是对应特定用户的,所以并不存在并发问题。如果你用数据库来做TempData的存储介质的话,必须要考虑这个情况的。至于如何自定义TempData的存储介质,你可以参考“ASP.NET MVC: 用db4o来做TempDataProvider(另附一个泛型的RedirectToAction方法)”这一篇文章。

前面说到的在我们的BaseController中有一个显示提示信息给用户的方法,这个提示信息就是临时的信息,我们可以使用TempData来实现。下面让我们来实现这个提示信息的方法:

复制代码
protected  ActionResult ShowMsg(List < string >  msgs)
{
TempData[
" Messages " =  msgs;
return  RedirectToAction( " Message " );


public  ActionResult Message()
{
return  View(TempData[ " Messages " as  List < string > );
}
复制代码

因为我们的Controller都继承自这个我们自定义的BaseController,所以我么可以才Controller中这样来给用户显示提示信息:

image

TEMPDATA应用例子,通过TEMPDATA实现添加数据时防止页面刷新出现重复提交数据的情况:

STEP01:保存数据到TEMPDATA,定义页面跳转到结果显示页

 public ActionResult Save(Models.GuestBookForm data)
        {

            if (!ModelState.IsValid)
            {
                //验证失败
                return RedirectToAction("Write");
            }

            MvcStudyDemo.Models.MvcGuestbookEntities db = new Models.MvcGuestbookEntities();

            db.AddToMessage(new Models.Message()
            {

                Body = data.MsgName + data.Email,
                AdminReply = data.Content,
                IsSecret = false,
                AdminReplyTime = DateTime.Now,
                CreateTime = DateTime.Now,
                MemberID = 38

            });

            db.SaveChanges();

            //ViewData["Name"] = data.MsgName;
            //ViewData["Email"] = data.Email;
            //ViewData["Content"] = data.Content;


            //return View();


            //保存临时数据,页面跳转防止重复提交
            TempData["LastPostGuestBookForm"] = data;

            return RedirectToAction("Result");


        }

STEP2:新建RESULT动作

 public ActionResult Result()
        {
            if (TempData["LastPostGuestBookForm"] == null)
            {
                return RedirectToAction("Index");
            }

            var model = (Models.GuestBookForm)TempData["LastPostGuestBookForm"];

            return View(model);
        }

STEP3:新建RESULT动作视图

 

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcStudyDemo.Models.GuestBookForm>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
 Result
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Result</h2>

    <fieldset>
        <legend>Fields</legend>
        
        <div class="display-label">MsgName</div>
        <div class="display-field"><%: Model.MsgName %></div>
        
        <div class="display-label">Email</div>
        <div class="display-field"><%: Model.Email %></div>
        
        <div class="display-label">Content</div>
        <div class="display-field"><%: Model.Content %></div>
        
    </fieldset>
    <p>
        <%: Html.ActionLink("Back to List", "Index") %>
    </p>

</asp:Content>

### 使用 `tempData` 替代环形缓冲区的实现方式 环形缓冲区是一种常见的数据结构,用于管理固定大小的队列。如果希望用 `tempData` 来替代环形缓冲区,则可以通过动态分配内存或其他临时存储机制来模拟其功能。 #### 动态数组作为 `tempData` 可以使用动态数组(如 Python 的列表或 C++ 中的向量)代替传统的静态环形缓冲区。这种方式允许更灵活地扩展和缩减容量,而无需手动处理指针操作。 以下是基于 Python 和 C++ 的两种实现: --- #### **Python 实现** ```python class TempDataBuffer: def __init__(self, capacity): self.capacity = capacity # 缓冲区最大容量 self.temp_data = [] # 存储数据的临时容器 def enqueue(self, item): # 添加元素到缓冲区 if len(self.temp_data) >= self.capacity: self.temp_data.pop(0) # 移除最早的数据项 self.temp_data.append(item) def dequeue(self): # 获取并移除最旧的元素 if not self.temp_data: raise IndexError("Temp data buffer is empty.") return self.temp_data.pop(0) def get_buffer(self): # 查看当前缓冲区中的所有数据 return list(self.temp_data) # 示例代码 buffer = TempDataBuffer(capacity=5) for i in range(7): buffer.enqueue(i) print(buffer.get_buffer()) # 输出最近加入的五个元素 [2, 3, 4, 5, 6] ``` 上述代码通过维护一个动态调整长度的列表实现了类似环形缓冲区的功能[^1]。 --- #### **C++ 实现** 在 C++ 中,可以利用标准库中的 `std::vector` 或者其他 STL 容器完成类似的逻辑。 ```cpp #include <iostream> #include <vector> class TempDataBuffer { private: std::vector<int> tempData; // 动态数组存储数据 size_t capacity; public: TempDataBuffer(size_t cap) : capacity(cap) {} void enqueue(int value) { // 插入新数据 if (tempData.size() >= capacity && !tempData.empty()) { tempData.erase(tempData.begin()); // 删除最早的条目 } tempData.push_back(value); } int dequeue() { // 取出最早的数据 if (tempData.empty()) throw std::out_of_range("Buffer underflow"); int frontValue = tempData.front(); tempData.erase(tempData.begin()); return frontValue; } const std::vector<int>& getData() const { return tempData; } // 返回整个缓存内容 }; int main() { TempDataBuffer buffer(5); // 创建容量为5的缓冲区 for (int i = 0; i < 7; ++i) { buffer.enqueue(i); } for (const auto& val : buffer.getData()) { std::cout << val << " "; // 打印最后五次插入的内容 } } ``` 此版本同样支持 FIFO 行为,并且能够自动丢弃超出容量范围的老化数据。 --- #### 数据结构分析 当采用 `tempData` 方法替换传统环形缓冲区时,主要考虑以下几个方面: - **性能开销**:相比固定的环形缓冲区,动态数组可能带来额外的时间复杂度 O(n),尤其是在频繁调用删除头部的操作时。 - **灵活性**:由于不需要预先定义大小,因此更适合不确定输入规模的应用场景。 - **线程安全性**:对于多线程环境下的访问控制需特别注意同步问题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值