实施 ITempDataProvider 与使用 Cookie
Implementing ITempDataProvider vs Using Cookies
我正在尝试使用 TempData 将数据从一个请求发送到另一个请求。
但是,由于 TempData 使用服务器会话,而此应用程序将进行网络部署,我将不得不使用 cookie 或数据库持久性,因为会话不会从一台服务器传输到另一台服务器.
有许多实现可以使用 cookie 而不是默认会话:
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);
}
...
参考。 http://brockallen.com/2012/06/11/cookie-based-tempdata-provider/
但是,这些方法中的 none 似乎会在请求结束后删除 cookie。
在请求完成后使用 TempData 使数据过期(除非您使用 TempData.Keep("myKey");
)不是全部意义所在吗?
为什么不直接使用 cookie 而不是实现 ITempDataProvider? difference/benefit 是什么?
进一步阅读:
这是一个更简单的基于 cookie 的实现:
这是 Microsoft 的 SessionState 提供程序实现:
编辑澄清:在以下代码中,Microsoft 将在会话加载后将其删除,以便无法再次加载:
// If we got it from Session, remove it so that no other request gets it
session.Remove(TempDataSessionStateKey);
我在网上找到的 None 个解决方案使 cookie 过期;所以,基本上它们实际上并不是 临时 数据。他们都只是让 cookie 在 LoadTempData() 之后继续存在,所以在那一点上,您甚至可能根本不使用 TempData。
在下面的实现中,cookie 只会在 HTTP 请求的持续时间内存在(因为 TempData 只应该如此),如果你想保持更长的时间,你可以像往常一样使用 TempData.Keep("yourKey")
将再次调用 SaveTempData() 方法(根据 the MVC source)。
最后一件事,此代码未针对速度或安全性进行优化。
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
}
}
}
}
我正在尝试使用 TempData 将数据从一个请求发送到另一个请求。
但是,由于 TempData 使用服务器会话,而此应用程序将进行网络部署,我将不得不使用 cookie 或数据库持久性,因为会话不会从一台服务器传输到另一台服务器.
有许多实现可以使用 cookie 而不是默认会话:
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);
}
...
参考。 http://brockallen.com/2012/06/11/cookie-based-tempdata-provider/
但是,这些方法中的 none 似乎会在请求结束后删除 cookie。
在请求完成后使用 TempData 使数据过期(除非您使用 TempData.Keep("myKey");
)不是全部意义所在吗?
为什么不直接使用 cookie 而不是实现 ITempDataProvider? difference/benefit 是什么?
进一步阅读:
这是一个更简单的基于 cookie 的实现:
这是 Microsoft 的 SessionState 提供程序实现:
编辑澄清:在以下代码中,Microsoft 将在会话加载后将其删除,以便无法再次加载:
// If we got it from Session, remove it so that no other request gets it
session.Remove(TempDataSessionStateKey);
None 个解决方案使 cookie 过期;所以,基本上它们实际上并不是 临时 数据。他们都只是让 cookie 在 LoadTempData() 之后继续存在,所以在那一点上,您甚至可能根本不使用 TempData。
在下面的实现中,cookie 只会在 HTTP 请求的持续时间内存在(因为 TempData 只应该如此),如果你想保持更长的时间,你可以像往常一样使用 TempData.Keep("yourKey")
将再次调用 SaveTempData() 方法(根据 the MVC source)。
最后一件事,此代码未针对速度或安全性进行优化。
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
}
}
}
}