首页 新闻 搜索 专区 学院

关于TempData的生命周期,未使用但在跨控制器的时候却拿不到值

0
[已解决问题] 解决于 2014-11-17 18:38

  C# MVC 里面有个 TempData,用法跟 ViewData差不多,但是 TempData 是存储在 session 中的,我记得很重要的一点是 他存储的值只能被使用一次,他是可以跨控制器访问的。

  我有 A、B、C、三个方法,A() 里有一个 TempData["sourcea"] ,B()里有一个 TempData["sourceb"],C()里有一个 TempData["sourcec"],A()返回视图提交到B(),B()返回视图提交到C(),C()返回视图读取 TempData["sourcea"]、TempData["sourceb"]、TempData["sourcec"]的值,现在的问题是 C里面只读取得到 TempData["sourcec"]。

  大神们能帮忙解释一下这是为什么吗?为什么TempData["sourcea"]和TempData["sourceb"]读不到?在线等!!!求解答!!!以下是全部代码。

控制器:

        public ActionResult A()
        {
            TempData["sourcea"] = "来自星星的A-a";
            return View();
        }

        public ActionResult B()
        {
            TempData["sourceb"] = "来自博客园的你-b";
            return View();
        }

        public ActionResult C()
        {
            TempData["sourcec"] = "来自银河系的我-c";
            return View();
        }

 

视图A、B差不多,就是提交的地址不一样:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>A</title>
</head>
<body>
    <div>
        <form action="/DataBind/B" method="POST">
            <input type="submit" value="提交到B"/>
        </form>
    </div>
</body>
</html>

 

视图C读取TempData里面的值:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>C</title>
</head>
<body>
    <div>
        <ul>
            <li>@TempData["sourcea"]</li>
            <li>@TempData["sourceb"]</li>
            <li>@TempData["sourcec"]</li>
        </ul>
    </div>
</body>
</html>
晓菜鸟的主页 晓菜鸟 | 老鸟四级 | 园豆:2594
提问于:2014-10-20 10:32
< >
分享
最佳答案
2

时刻记住WEB是Stateless(无状态的),IIS老年痴呆症,你每次去访问,拿到一个礼物,出来,再进去,他就再给你一个礼物,完全不记得你是谁。

象你这样已经三进宫了,三进三出,不要被NET欺骗了,回归最原始的WEB思考。

有几个方法让你告诉IIS

1、QUERYSTRING (别怕让人看到,WEB就是要让人看的,机密的东西没有那么多)

2、FORM 提交

3、Cookie\Session(比较重要,比较少的数据才放在这里面)

其他的数据真的有需要,可以使用数据库查询、静态函数、缓存类等,相当于你从前台querystring或是Form提交一个ID,

后台再到数据库、静态函数、缓存类中去取出完整的对象,不要以为这是重复的工作或是担心性能啥的。

奖励园豆:5
爱编程的大叔 | 高人七级 |园豆:30698 | 2014-10-20 11:48

大叔,像我这种.Net的web应该怎么理解啊?他不是纯粹的web。

晓菜鸟 | 园豆:2594 (老鸟四级) | 2014-10-20 12:01

@晓菜鸟: 他就是纯粹的WEB。

或者你这样记,后台==》前台你怎么写都可以的,

前台==》后台,或者前台页面1==》前台页面2,只有三个途径

QUERYSTRING

FORM

SESSION/COOKIE

你如果学习一下AJAX,把前台就当前台,纯粹的HTML+JAVASCRIPT(包括用MVC实现的),后台纯粹提供数据,

这样你可能会容易摆脱NET的错误理解。

 

你这样想吧,不管你在页面里面写了多少的C#代码,最后都会被IIS拍平成为HTML,

然后输出给IE。所以里面的变量啥的,都已经没了,只要你没有办法在HTML(查看源代码)

里面看到的东东,他都是不存在的。(Cookie/Session除外)

 

你IE与服务器(IIS)之间是远程连接,所有的数据都要在互联网上跑一趟的,

IE从页面A提交到页面B,在网线上传输的是这些

FORM Data +  FORM HEADER (这里面包含COOKIE之类的东东)

所以做WEB都要在合理的情况下,尽可能减少需要往返传输的数据。

 

这个数据越大,你的网页处理速度就越慢。

爱编程的大叔 | 园豆:30698 (高人七级) | 2014-10-20 12:06

@爱编程的大叔: 嗯,您说的这个我能明白,但是我了解到的 TempData 其内部就是靠 Session实现的,他就是把值存储到 Session 中,既然是保存在 session 中,那我应该能拿到值啊?

晓菜鸟 | 园豆:2594 (老鸟四级) | 2014-10-20 13:12

@晓菜鸟:  

MVC中 ViewData、ViewBag、TempData的区别与联系

TempData  保存在Session中,Controller每次执行请求的时候,会从Session中先获取 TempData,而后清除Session,获取完TempData数据,虽然保存在内部字典对象中,但是其集合中的每个条目访问一次后就从字典表中删 除。具体代码层面,TempData获取过程是通过SessionStateTempDataProvider.LoadTempData方法从 ControllerContext的Session中读取数据,而后清除Session,故TempData只能跨Controller传递一次。

爱编程的大叔 | 园豆:30698 (高人七级) | 2014-10-20 13:26

@爱编程的大叔: 大叔,Tempdata只能被使用一次,在使用一次之后就会清空Tempdata里面已使用的值,但是我A()和B()里面的Tempdata的值我只在C进行输出,A()和B()本身是没对他们进行输出的,那他应该是有值的啊?

您看看这编博客:

http://blog.csdn.net/dfyong/article/details/6660935

在Controller,执行中可以加入新的值到TempData中,Action结束之后它还要把没有使用过的数据给存起来。

http://developer.51cto.com/art/200904/118494.htm

 

晓菜鸟 | 园豆:2594 (老鸟四级) | 2014-10-20 13:33
其他回答(2)
0

这个问题暂时还是没有彻底理解,最近一段时间在赶项目,没怎么上博客园,先谢谢“爱编程的大叔”了,感谢!

晓菜鸟 | 园豆:2594 (老鸟四级) | 2014-11-17 18:38
-1

TempData["sourcea"]、TempData["sourceb"]不能夸视图view访问,你需要在方法c中赋值给viewbag,viewbag["sourcea"]=TempData["sourcea"]、viewbag["sourceb"]=TempData["sourceb"],然后在c视图再获取viewbag的值。

cdblh | 园豆:202 (菜鸟二级) | 2016-10-08 06:31
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册