实施ITempDataProvider VS使用Cookie [英] Implementing ITempDataProvider vs Using Cookies

查看:203
本文介绍了实施ITempDataProvider VS使用Cookie的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用TempData的从一个请求到另一个发送数据。

然而,由于TempData的使用服务器会话,这种应用是Web的养殖,我就必须要么使用cookies或数据库持久性,相反,因为会议将不会从一台服务器转移到其他。

有可代替使用默认会话的饼干数目实现:

 公共类CookieTempDataProvider:ITempDataProvider
{
    常量字符串CookieName =TempData的;    公共无效SaveTempData(
        ControllerContext controllerContext,
        IDictionary的<字符串对象>值)
    {
        //将临时数据字典成JSON
        字符串值=序列化(值);
        // COM preSS的JSON(它确实有助于)
        VAR字节= com的preSS(值);
        // SIGN并通过asp.net机器密钥加密数据
        值=保护(字节);
        //发出的cookie
        IssueCookie(controllerContext,值);
    }    公众的IDictionary<字符串对象> LoadTempData(
        ControllerContext controllerContext)
    {
        //获取饼干
        VAR值= GetCookieValue(controllerContext);
        //验证并通过asp.net计算机密钥解密值
        VAR字节=撤消(值);
        // DECOM preSS到JSON
        值= DECOM preSS(字节);
        //将JSON转换回字典
        返回反序列化(值);
    }
...

参考。 http://brockallen.com/2012/06/11/cookie-基于TempData的提供商/

但是,这些方法似乎以除去该cookie请求结束后。

时不使用TempData的过期的数据的请求完成后(除非你使用 TempData.Keep(的myKey); )的整点?

为什么不直接使用cookies,而不是实施ITempDataProvider的?有什么区别/效益?

延伸阅读:

下面是一个简单的基于cookie的实现:

下面是微软的执行SessionState会提供的:

在下面的code,微软移除会话被加载后,使得它不能被再次装入:编辑澄清

  //如果我们从会议得到了它,将其取下,没有其他的要求得到它
session.Remove(TempDataSessionStateKey);


解决方案

我在网上找到了解决方案的无过期饼干;所以,基本上他们不是真正的临时数据。他们都只是让饼干生存过去LoadTempData(),所以在这一点上,你可能也不会,甚至在所有使用TempData的。

在下面的实现,cookie将只能存活的HTTP请求的时间(如TempData的情况应该只是一个),如果你想保持更长的时间,你可以使用 TempData.Keep( yourKey),你通常会这将再次调用SaveTempData()方法(按<一个href=\"https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/TempDataDictionary.cs\"相对=nofollow> MVC的源)。

最后一件事,这code不是速度或安全性进行了优化。

 公共类CookieTempDataProvider:ITempDataProvider
{
    公共常量字符串TempDataCookieKey =__ControllerTempData;    公众的IDictionary&LT;字符串对象&gt; LoadTempData(ControllerContext控制器)
    {
        的HttpCookie饼干= controller.HttpContext.Request.Cookies [TempDataCookieKey]        字典&LT;字符串对象&gt; tempDataDictionary =新词典&LT;字符串对象&gt;();        如果(饼干!= NULL)
        {
            对(INT keyIndex = 0; keyIndex&下; cookie.Values​​.Count; keyIndex ++)
            {
                字符串键= cookie.Values​​.GetKey(keyIndex);
                如果(!string.IsNullOrEmpty(键))
                {
                    字符串base64Value = cookie.Values​​.Get(keyIndex);
                    字节[]缓冲= Convert.FromBase64String(base64Value);
                    使用(MemoryStream的毫秒=新的MemoryStream(缓冲))
                    {
                        BinaryFormatter的格式化=新的BinaryFormatter();
                        对象值= formatter.Deserialize(毫秒);
                        tempDataDictionary.Add(键,值);
                    }
                }
            }            cookie.Expires = DateTime.Now.AddDays(-1d); //过期饼干所以没有其他的要求得到它
            controller.HttpContext.Response.SetCookie(饼干);
        }        返回tempDataDictionary;
    }    公共无效SaveTempData(ControllerContext控制器,IDictionary的&LT;字符串对象&gt;的值)
    {
        的HttpCookie饼干= controller.HttpContext.Request.Cookies [TempDataCookieKey]
        布尔hasVa​​lues​​ =(值=空&放大器;!&放大器; values​​.Count大于0);        如果(饼干== NULL)
        {
            饼干=新的HttpCookie(TempDataCookieKey);
            controller.HttpContext.Response.Cookies.Add(饼干);
        }        如果(hasVa​​lues​​)
        {
            的foreach(KeyValuePair&LT;字符串对象&gt; KVP价值观)
            {
                BinaryFormatter的格式化=新的BinaryFormatter();
                使用(MemoryStream的毫秒=新的MemoryStream())
                {
                    formatter.Serialize(MS,kvp.Value);
                    字节[]字节= ms.GetBuffer();
                    字符串base64Value = Convert.ToBase64String(字节);                    字符串keyExists = cookie.Values​​.Get(kvp.Key);
                    如果(keyExists!= NULL)
                    {
                        cookie.Values​​.Set(kvp.Key,base64Value);
                    }
                    其他
                    {
                        cookie.Values​​.Add(kvp.Key,base64Value);
                    }
                }
            }            cookie.Expires = DateTime.Now.AddDays(1D);
            controller.HttpContext.Response.SetCookie(饼干);
        }
        其他
        {
            如果空值传递//删除会议
            如果(controller.HttpContext.Request.Cookies [TempDataCookieKey]!= NULL)
            {
                cookie.Expires = DateTime.Now.AddDays(-1d); //过期饼干所以没有其他的要求得到它
            }
        }
    }
}

I am trying to use TempData to send data from one request to another.

However, since TempData uses a server session, and this application is to be web-farmed, I will have to either use cookies or database persistance, instead, since the session won't transfer from one server to the other.

There are a number of implementations available to use cookies instead of the default session:

public class CookieTempDataProvider : ITempDataProvider
{
    const string CookieName = "TempData";

    public void SaveTempData(
        ControllerContext controllerContext,
        IDictionary<string, object> values)
    {
        // convert the temp data dictionary into json
        string value = Serialize(values);
        // compress the json (it really helps)
        var bytes = Compress(value);
        // sign and encrypt the data via the asp.net machine key
        value = Protect(bytes);
        // issue the cookie
        IssueCookie(controllerContext, value);
    }

    public IDictionary<string, object> LoadTempData(
        ControllerContext controllerContext)
    {
        // get the cookie
        var value = GetCookieValue(controllerContext);
        // verify and decrypt the value via the asp.net machine key
        var bytes = Unprotect(value);
        // decompress to json
        value = Decompress(bytes);
        // convert the json back to a dictionary
        return Deserialize(value);
    }
...

Ref. http://brockallen.com/2012/06/11/cookie-based-tempdata-provider/

However, none of these methods seem to remove the cookie after the request has ended.

Isn't the whole point of using TempData to expire the data after the request has finished (unless you use TempData.Keep("myKey");)?

Why not just use cookies instead of implementing ITempDataProvider? What's the difference/benefit?

Further reading:

Here is a simpler cookie-based implementation:

Here is Microsoft's implementation of SessionState provider:

Edit for clarification: In the following code, Microsoft is removing the session after it is loaded such that it cannot be loaded again:

// If we got it from Session, remove it so that no other request gets it
session.Remove(TempDataSessionStateKey);

解决方案

None of the solutions I found on the web expired the cookie; so, basically they weren't actually temporary data. They all just let the cookie survive past the LoadTempData() so at that point, you may as well not even be using TempData at all.

In the following implementation, the cookie will only survive for the duration of the HTTP request (as TempData is only supposed to) and if you want to keep it longer, you can use TempData.Keep("yourKey") as you normally would which will call the SaveTempData() method again (as per the MVC source).

One last thing, this code is NOT optimized for speed or security.

public class CookieTempDataProvider : ITempDataProvider
{
    public const string TempDataCookieKey = "__ControllerTempData";

    public IDictionary<string, object> LoadTempData(ControllerContext controller)
    {
        HttpCookie cookie = controller.HttpContext.Request.Cookies[TempDataCookieKey];

        Dictionary<string, object> tempDataDictionary = new Dictionary<string, object>();

        if (cookie != null)
        {
            for (int keyIndex = 0; keyIndex < cookie.Values.Count; keyIndex++)
            {
                string key = cookie.Values.GetKey(keyIndex);
                if (!string.IsNullOrEmpty(key))
                {
                    string base64Value = cookie.Values.Get(keyIndex);
                    byte[] buffer = Convert.FromBase64String(base64Value);
                    using (MemoryStream ms = new MemoryStream(buffer))
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        object value = formatter.Deserialize(ms);
                        tempDataDictionary.Add(key, value);
                    }
                }
            }

            cookie.Expires = DateTime.Now.AddDays(-1d); // expire cookie so no other request gets it
            controller.HttpContext.Response.SetCookie(cookie);
        }

        return tempDataDictionary;
    }

    public void SaveTempData(ControllerContext controller, IDictionary<string, object> values)
    {
        HttpCookie cookie = controller.HttpContext.Request.Cookies[TempDataCookieKey];
        bool hasValues = (values != null && values.Count > 0);

        if (cookie == null)
        {
            cookie = new HttpCookie(TempDataCookieKey);
            controller.HttpContext.Response.Cookies.Add(cookie);
        }

        if (hasValues)
        {
            foreach (KeyValuePair<string, object> kvp in values)
            {
                BinaryFormatter formatter = new BinaryFormatter();
                using (MemoryStream ms = new MemoryStream())
                {
                    formatter.Serialize(ms, kvp.Value);
                    byte[] bytes = ms.GetBuffer();
                    string base64Value = Convert.ToBase64String(bytes);

                    string keyExists = cookie.Values.Get(kvp.Key);
                    if (keyExists != null)
                    {
                        cookie.Values.Set(kvp.Key, base64Value);
                    }
                    else
                    {
                        cookie.Values.Add(kvp.Key, base64Value);
                    }
                }
            }

            cookie.Expires = DateTime.Now.AddDays(1d);
            controller.HttpContext.Response.SetCookie(cookie);
        }
        else
        {
            // delete session if null values are passed
            if (controller.HttpContext.Request.Cookies[TempDataCookieKey] != null)
            {
                cookie.Expires = DateTime.Now.AddDays(-1d); // expire cookie so no other request gets it
            }
        }
    }
}

这篇关于实施ITempDataProvider VS使用Cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆