Asp.net mvc 2 浏览器cookie中的ASP.NET MVC TempData

Asp.net mvc 2 浏览器cookie中的ASP.NET MVC TempData,asp.net-mvc-2,cookies,tempdata,Asp.net Mvc 2,Cookies,Tempdata,我试图使用自定义的ITempDataProvider提供程序将TempData存储在浏览器的cookie中,而不是会话状态。但是,除了读取响应流后无法从响应流中删除cookie之外,其他一切都正常工作 有什么想法吗? 谢谢 public class CookieTempDataProvider : ITempDataProvider { internal const string TempDataCookieKey = "__ControllerTempData";

我试图使用自定义的ITempDataProvider提供程序将TempData存储在浏览器的cookie中,而不是会话状态。但是,除了读取响应流后无法从响应流中删除cookie之外,其他一切都正常工作

有什么想法吗?
谢谢

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

        public CookieTempDataProvider(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }
            _httpContext = httpContext;
        }

        public HttpContextBase HttpContext
        {
            get
            {
                return _httpContext;
            }
        }

        protected virtual IDictionary<string, object> LoadTempData(ControllerContext controllerContext)
        {
            HttpCookie cookie = _httpContext.Request.Cookies[TempDataCookieKey];
            if (cookie != null && !string.IsNullOrEmpty(cookie.Value))
            {
                IDictionary<string, object> deserializedTempData = DeserializeTempData(cookie.Value);

                // Remove cookie                
                cookie.Expires = DateTime.MinValue;
                cookie.Value = string.Empty;
                _httpContext.Request.Cookies.Remove(TempDataCookieKey);

                if (_httpContext.Response != null && _httpContext.Response.Cookies != null)
                {
                    HttpCookie responseCookie = _httpContext.Response.Cookies[TempDataCookieKey];
                    if (responseCookie != null)
                    {
                        // Remove cookie
                        cookie.Expires = DateTime.MinValue;
                        cookie.Value = string.Empty;
                        _httpContext.Response.Cookies.Remove(TempDataCookieKey);

                    }
                }

                return deserializedTempData;
            }

            return new Dictionary<string, object>();
        }

        protected virtual void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
        {

            string cookieValue = SerializeToBase64EncodedString(values);  
            var cookie = new HttpCookie(TempDataCookieKey);
            cookie.HttpOnly = true;
            cookie.Value = cookieValue;

            _httpContext.Response.Cookies.Add(cookie);
        }

        public static IDictionary<string, object> DeserializeTempData(string base64EncodedSerializedTempData)
        {
            byte[] bytes = Convert.FromBase64String(base64EncodedSerializedTempData);
            var memStream = new MemoryStream(bytes);
            var binFormatter = new BinaryFormatter();
            return binFormatter.Deserialize(memStream, null) as IDictionary<string, object> /*TempDataDictionary : This returns NULL*/;
        }

        public static string SerializeToBase64EncodedString(IDictionary<string, object> values)
        {
            MemoryStream memStream = new MemoryStream();
            memStream.Seek(0, SeekOrigin.Begin);
            var binFormatter = new BinaryFormatter();
            binFormatter.Serialize(memStream, values);
            memStream.Seek(0, SeekOrigin.Begin);
            byte[] bytes = memStream.ToArray();
            return Convert.ToBase64String(bytes);
        }

        IDictionary<string, object> ITempDataProvider.LoadTempData(ControllerContext controllerContext)
        {
            return LoadTempData(controllerContext);
        }

        void ITempDataProvider.SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
        {
            SaveTempData(controllerContext, values);
        }
    }
公共类CookieTempDataProvider:ITempDataProvider
{
内部常量字符串TempDataCookieKey=“\uuu ControllerTempData”;
HttpContextBase_httpContext;
公共CookieTempDataProvider(HttpContextBase httpContext)
{
if(httpContext==null)
{
抛出新ArgumentNullException(“httpContext”);
}
_httpContext=httpContext;
}
公共HttpContextBase HttpContext
{
得到
{
返回httpContext;
}
}
受保护的虚拟IDictionary LoadTempData(ControllerContext ControllerContext)
{
HttpCookie cookie=httpContext.Request.Cookies[TempDataCookieKey];
if(cookie!=null&!string.IsNullOrEmpty(cookie.Value))
{
IDictionary deserializedTempData=DeserializeTempData(cookie.Value);
//删除cookie
cookie.Expires=DateTime.MinValue;
cookie.Value=string.Empty;
_httpContext.Request.Cookies.Remove(TempDataCookieKey);
if(_httpContext.Response!=null&&u httpContext.Response.Cookies!=null)
{
HttpCookie responseCookie=_httpContext.Response.Cookies[TempDataCookieKey];
if(responseCookie!=null)
{
//删除cookie
cookie.Expires=DateTime.MinValue;
cookie.Value=string.Empty;
_httpContext.Response.Cookies.Remove(TempDataCookieKey);
}
}
返回反序列化的时间数据;
}
返回新字典();
}
受保护的虚拟void SaveTempData(ControllerContext ControllerContext,IDictionary值)
{
字符串cookieValue=SerializeToBase64EncodedString(值);
var cookie=新的HttpCookie(TempDataCookieKey);
cookie.HttpOnly=true;
cookie.Value=cookieValue;
_httpContext.Response.Cookies.Add(cookie);
}
公共静态IDictionary反序列化时间数据(基于字符串的64EncodedSerializedTempData)
{
byte[]bytes=Convert.FromBase64String(base64EncodedSerializedTempData);
var memStream=新内存流(字节);
var binFormatter=新的BinaryFormatter();
返回binFormatter。反序列化(memStream,null)为IDictionary/*TempDataDictionary:返回null*/;
}
公共静态字符串序列化为SE64EncodedString(IDictionary值)
{
MemoryStream memStream=新的MemoryStream();
memStream.Seek(0,SeekOrigin.Begin);
var binFormatter=新的BinaryFormatter();
序列化(memStream,值);
memStream.Seek(0,SeekOrigin.Begin);
byte[]bytes=memStream.ToArray();
返回Convert.tobase64字符串(字节);
}
IDictionary ITempDataProvider.LoadTempData(ControllerContext ControllerContext)
{
返回LoadTempData(controllerContext);
}
void ITempDataProvider.SaveTempData(ControllerContext ControllerContext,IDictionary值)
{
SaveTempData(controllerContext,值);
}
}

嗨,我也有同样的问题,这是CookieTempDataProvider实现的问题

所以我对代码做了一些修改,现在它工作得很好

当它从cookie中读取数据时,它会将其从请求和响应中删除。但在SaveData函数中添加另一个具有空值的cookie,该函数在请求处理完成时调用

需要注意的要点:如果要删除cookie,必须设置超时值并将其发送回客户端,然后浏览器将删除它。我们无法从代码a中执行此操作,cookie由浏览器处理

我发现将expiration设置为DateTime.MinValue不会使chrome中的cookie过期(不知道其他浏览器),所以我将它设置为2001-01-01:)

这是工作代码

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

    public CookieTempDataProvider(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }
        _httpContext = httpContext;
    }

    public HttpContextBase HttpContext
    {
        get
        {
            return _httpContext;
        }
    }

    protected virtual IDictionary<string, object> LoadTempData(ControllerContext controllerContext)
    {
        if (_httpContext.Request.Cookies.AllKeys.Contains(TempDataCookieKey)) //we need this because
        //Cookies[TempDataCookieKey] will create the cookie if it does not exist
        {
            HttpCookie cookie = _httpContext.Request.Cookies[TempDataCookieKey];
            if (cookie != null && !string.IsNullOrEmpty(cookie.Value))
            {
                IDictionary<string, object> deserializedTempData = DeserializeTempData(cookie.Value);

                // Remove cookie                
                cookie.Expires = new DateTime(2000, 1, 1);
                cookie.Value = string.Empty;
                _httpContext.Request.Cookies.Remove(TempDataCookieKey);

                if (_httpContext.Response != null && _httpContext.Response.Cookies != null)
                {
                    HttpCookie responseCookie = _httpContext.Response.Cookies[TempDataCookieKey];
                    if (responseCookie != null)
                    {
                        // Remove cookie
                        cookie.Expires = new DateTime(2000, 1, 1);
                        cookie.Value = string.Empty;
                        _httpContext.Response.Cookies.Remove(TempDataCookieKey);

                    }
                }

                return deserializedTempData;
            }
        }
        return new Dictionary<string, object>();
    }

    protected virtual void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
    {
        if (values != null && values.Count > 0)
        {
            //there are values to set, so add the cookie. But no need to expire it as we need the browser to send the 
            //cookie back with the next request
            string cookieValue = SerializeToBase64EncodedString(values);
            var cookie = new HttpCookie(TempDataCookieKey);
            cookie.HttpOnly = true;
            cookie.Value = cookieValue;

            _httpContext.Response.Cookies.Add(cookie);
        }
        else
        {
            //Still we need to add the cookie with the expiration set, to make the client browser remove the cookie from the request.
            //Otherwise the browser will continue to send the cookie with the response

            //Also we need to do this only if the requet had a tempdata cookie

            if (_httpContext.Request.Cookies.AllKeys.Contains(TempDataCookieKey))
            {
                {
                    HttpCookie cookie = _httpContext.Request.Cookies[TempDataCookieKey];

                    // Remove the request cookie                
                    cookie.Expires = new DateTime(2000, 1, 1);
                    cookie.Value = string.Empty;
                    _httpContext.Request.Cookies.Remove(TempDataCookieKey);

                    var rescookie = new HttpCookie(TempDataCookieKey);
                    rescookie.HttpOnly = true;
                    rescookie.Value = "";
                    rescookie.Expires = new DateTime(2000, 1, 1); //so that the browser will remove the cookie when it receives the request
                    _httpContext.Response.Cookies.Add(rescookie);
                }
            }
        }
    }

    public static IDictionary<string, object> DeserializeTempData(string base64EncodedSerializedTempData)
    {
        byte[] bytes = Convert.FromBase64String(base64EncodedSerializedTempData);
        var memStream = new MemoryStream(bytes);
        var binFormatter = new BinaryFormatter();
        return binFormatter.Deserialize(memStream, null) as IDictionary<string, object> /*TempDataDictionary : This returns NULL*/;
    }

    public static string SerializeToBase64EncodedString(IDictionary<string, object> values)
    {
        MemoryStream memStream = new MemoryStream();
        memStream.Seek(0, SeekOrigin.Begin);
        var binFormatter = new BinaryFormatter();
        binFormatter.Serialize(memStream, values);
        memStream.Seek(0, SeekOrigin.Begin);
        byte[] bytes = memStream.ToArray();
        return Convert.ToBase64String(bytes);
    }

    IDictionary<string, object> ITempDataProvider.LoadTempData(ControllerContext controllerContext)
    {
        return LoadTempData(controllerContext);
    }

    void ITempDataProvider.SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
    {
        SaveTempData(controllerContext, values);
    }
}
公共类CookieTempDataProvider:ITempDataProvider
{
内部常量字符串TempDataCookieKey=“\uuu ControllerTempData”;
HttpContextBase_httpContext;
公共CookieTempDataProvider(HttpContextBase httpContext)
{
if(httpContext==null)
{
抛出新ArgumentNullException(“httpContext”);
}
_httpContext=httpContext;
}
公共HttpContextBase HttpContext
{
得到
{
返回httpContext;
}
}
受保护的虚拟IDictionary LoadTempData(ControllerContext ControllerContext)
{
如果(_httpContext.Request.Cookies.AllKeys.Contains(TempDataCookieKey))//我们需要它,因为
//Cookies[TempDataCookieKey]将创建不存在的cookie
{
HttpCookie cookie=httpContext.Request.Cookies[TempDataCookieKey];
if(cookie!=null&!string.IsNullOrEmpty(cookie.Value))
{
IDictionary deserializedTempData=DeserializeTempData(cookie.Value);
//删除cookie
cookie.Expires=新的日期时间(2000,1,1);
cookie.Value=string.Empty;
_httpContext.Request.Cookies.Remove(TempDataCookieKey);
if(_httpContext.Response!=null&&u httpContext.Response。
public class CookieTempDataProvider : ITempDataProvider
{
    const string cookieKey = "temp";

    public IDictionary<string, object> LoadTempData(ControllerContext controllerContext)
    {
        var cookie = controllerContext.HttpContext.Request.Cookies[cookieKey];   

        if (cookie != null) {
            return JsonConvert.DeserializeObject<IDictionary<string, object>>(cookie.Value);
        }

        return null;
    }

    // Method is called after action execution. The dictionary mirrors the contents of TempData.
    // If there are any values in the dictionary, save it in a cookie. If the dictionary is empty,
    // remove the cookie if it exists.
    public void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
    {
        var ctx = controllerContext.HttpContext;

        if (values.Count > 0) {
            var cookie = new HttpCookie(cookieKey)
            {
                HttpOnly = true,
                Value = JsonConvert.SerializeObject(values)
            };

            ctx.Response.Cookies.Add(cookie);
        } else if (ctx.Request.Cookies[cookieKey] != null) {

            // Expire cookie to remove it from browser.
            ctx.Response.Cookies[cookieKey].Expires = DateTime.Today.AddDays(-1);
        }
    }
}