using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
using System.Collections;
using System.Text;
using System.Web.Security;
using System.Web.Caching;
#region Storage types
// The storage types from which the value is retrieved.
public enum Sources
{
None = 0,
Session = 1,
Cookie = 2,
QueryString = 4,
Cache = 8,
SharedCache = 16,
ServerCookie = 32
}
// The storage types where the value is saved.
// Each type has a byte value that can be added up to denote several types within the same value.
public struct Targets
{
public static readonly byte
None = 0,
Session = 1,
Cookie = 2,
QueryString = 4,
Cache = 8,
SharedCache = 16,
ServerCookie = 32;
}
#endregion
namespace System.Web
{
/// <summary>
/// Static object to get/set Session, Cookie and Querystring variables
/// </summary>
public partial class LocalBase
{
//private static HttpContext _context;
public static HttpContext Context
{
get { return HttpContext.Current; }
}
// _context = HttpContext.Current ?? _context;
// return _context;
// }
// set
// {
// _context = HttpContext.Current = value;
// }
//}
public static char KeyDelimiter = '_';
public static TimeSpan DefaultCookieLifeTime = TimeSpan.FromDays(100);
public static TimeSpan DefaultCacheLifeTime = TimeSpan.FromMinutes(20);
public static TimeSpan DefaultSessionLifeTime
{
get { return TimeSpan.FromMinutes(Context.Session.Timeout); }
set { Context.Session.Timeout = (int)value.TotalMinutes; }
}
// COOKIES
public static bool CookiesSupported
{
get { return Context.Request.Browser.Cookies; }
}
public static bool SetCookie<T>(string key, T value)
{
return SetCookie<T>(key, value, DefaultCookieLifeTime, false, false, null, null, null, null);
}
public static bool SetCookie<T>(string key, T value, bool compress, bool encrypt)
{
return SetCookie<T>(key, value, DefaultCookieLifeTime, compress, encrypt, null, null, null, null);
}
public static bool SetCookie<T>(string key, T value, TimeSpan lifeTime, bool compress, bool encrypt)
{
return SetCookie<T>(key, value, lifeTime, compress, encrypt, null, null, null, null);
}
public static bool SetCookie<T>(string key, T value, TimeSpan lifeTime, bool compress, bool encrypt,
string path, string domain, bool? httpOnly, bool? secure)
{
string strValue = Serialization.ToJson<T>(value);
return SetCookie(key, strValue, lifeTime, compress, encrypt, path, domain, httpOnly, secure);
}
public static bool SetCookie(string key, string value)
{
return SetCookie(key, value, DefaultCookieLifeTime, false, false, null, null, null, null);
}
public static bool SetCookie(string key, string value, bool compress, bool encrypt)
{
return SetCookie(key, value, DefaultCookieLifeTime, compress, encrypt, null, null, null, null);
}
public static bool SetCookie(string key, string value, TimeSpan lifeTime)
{
return SetCookie(key, value, lifeTime, false, false, null, null, null, null);
}
public static bool SetCookie(string key, string value, TimeSpan lifeTime, bool compress, bool encrypt)
{
return SetCookie(key, value, lifeTime, compress, encrypt, null, null, null, null);
}
public static bool SetCookie(string key, string value, TimeSpan lifeTime, bool compress, bool encrypt,
string path, string domain, bool? httpOnly, bool? secure)
{
if (!CookiesSupported)
return false;
HttpCookie cookie;
HttpResponse response = Context.Response;
HttpRequest request = Context.Request;
try
{
// Compression is applied before encryption since the unencrypted text usually
// contains more repetitive patterns the compression can use.
if (compress)
value = Compression.CompressToBase64(value);
if (encrypt)
value = CookieEncryption.Encrypt(value);
//value = HttpUtility.HtmlAttributeEncode(value);
// Split our key by the key delimiter. Any delimiter character after the 1st one is ignored.
string[] keys = key.Split(new char[] { KeyDelimiter }, 2);
// Determine if the key contains a subkey
bool keyContainsParentAndChild = keys.Length > 1;
if (!keyContainsParentAndChild)
{
cookie = response.Cookies[key];
// This also resets the expiry date
cookie.Value = value;
// The request is also updated in case it is accessed before the response completes
request.Cookies[key].Value = value;
}
else // The key provided is in the {parent}_{child} format
{
cookie = response.Cookies[keys[0]];
// This also resets the expiry date
cookie[keys[1]] = value;
// The request is also updated in case it is accessed before the response completes
request.Cookies[keys[0]][keys[1]] = value;
}
if (value == null)
cookie.Expires = DateTime.Now.AddDays(-1);
else
cookie.Expires = DateTime.Now.Add(lifeTime);
if (path != null)
cookie.Path = path;
if (domain != null)
cookie.Domain = domain;
if (httpOnly.HasValue)
cookie.HttpOnly = httpOnly.Value;
if (secure.HasValue)
cookie.Secure = secure.Value;
return true;
}
catch (Exception ex)
{
return false;
}
}
public static T GetCookie<T>(string key)
{
return GetCookie<T>(key, false, false);
}
public static T GetCookie<T>(string key, bool uncompress, bool decrypt)
{
return Serialization.FromJson<T>(GetCookie(key, uncompress, decrypt));
}
public static string GetCookie(string key) { return GetCookie(key, false, false); }
public static string GetCookie(string key, bool uncompress, bool decrypt)
{
if (!CookiesSupported) return null;
string value = null;
HttpCookie cookie;
string[] keys = key.Split(new char[] { KeyDelimiter }, 2);
try
{
cookie = Context.Request.Cookies[keys[0]];
}
catch (HttpRequestValidationException ex)
{
//string offensiveKey = ex.Message;
//offensiveKey = offensiveKey.Substring(offensiveKey.IndexOf(" (") + 2);
//offensiveKey = offensiveKey.Substring(0, offensiveKey.IndexOf("="));
//SetCookie(offensiveKey, null);
Context.Response.Cookies.Clear(); // Clear all cookies from response cookie collection
Context.Request.Cookies.Clear(); // Clear all cookies from request cookie collection
throw new HttpRequestValidationException(
ex.Message + "\n This error occured because some HTML like characters were found in the cookie." +
"\n Please note that as a security measure Univar clears all cookies when this happens.",
ex.InnerException);
}
catch (Exception ex)
{
throw new ArgumentException(ex.Message, ex.InnerException);
}
if (cookie != null)
{
if (keys.Length < 2)
value = cookie.Value;
else
value = cookie[keys[1]];
}
if (decrypt)
value = CookieEncryption.Decrypt(value, true);
if (uncompress)
value = Compression.UncompressFromBase64(value, true);
return value; // HttpUtility.HtmlDecode(value);
}
// SESSIONS
/// <summary>
/// Gets and sets the amount of time, in minutes, allowed between requests before
/// the session-state provider terminates the session.
/// </summary>
/// <value>The time-out period, in minutes.</value>
public static int SessionTimeOut
{
get { return Context.Session.Timeout; }
set { Context.Session.Timeout = value; }
}
public static string GetSession(string key)
{
return GetSession<string>(key);
}
public static T GetSession<T>(string key)
{
if (Context.Session == null)
throw new InvalidOperationException(
"The session state is null. This happens when it is accessed before the PreInit event of the page.");
object value = Context.Session[key];
if (value != null)
return (T)value;
else
return default(T);
}
public static void SetSession(string key, object value)
{
SetSession<object>(key, value);
}
public static void SetSession<T>(string key, T value)
{
if (value != null)
Context.Session[key] = value;
else
Context.Session.Remove(key);
}
// QUERY STRINGS
/// <summary>
/// Gets the query string.
/// </summary>
/// <returns>Any information in the query string</returns>
public static string GetQueryString()
{
return Context.Request.Url.Query;
}
public static T GetQueryString<T>(string key)
{
return GetQueryString<T>(key, false, false);
}
public static T GetQueryString<T>(string key, bool uncompress, bool decrypt)
{
return Serialization.FromJson<T>(GetQueryString(key, uncompress, decrypt));
}
public static string GetQueryString(string key)
{
return GetQueryString(key, false, false);
}
public static string GetQueryString(string key, bool uncompress, bool decrypt)
{
// Get the the value under the specified key.
// It took me quite a long time to figure this out but for unknown reasons, the request
// replaces every '+' character in the query with an empty character.
// To compensate all spaces need to be restored as their original '+' equivalent.
string value = Context.Request.QueryString[key];
if (value == null)
return null;
value = value.Replace(" ", "+");
if (decrypt)
value = CookieEncryption.Decrypt(value, true);
if (uncompress)
value = Compression.UncompressFromBase64(value, true);
return HttpUtility.UrlDecode(value);
}
public static NameValueCollection SetQueryString(string key, string value)
{
return SetQueryString<string>(key, value, false, false, false, false);
}
public static NameValueCollection SetQueryString(string key, string value, bool skipRefresh)
{
return SetQueryString<string>(key, value, false, false, false, skipRefresh);
}
public static NameValueCollection SetQueryString(string key, string value, bool replaceOriginal, bool skipRefresh)
{
return SetQueryString<string>(key, value, replaceOriginal, false, false, skipRefresh);
}
public static NameValueCollection SetQueryString(NameValueCollection originalQueryString,
string key, string value, bool compress, bool encrypt, bool skipRefresh)
{
return SetQueryString<string>(originalQueryString, key, value, compress, encrypt, skipRefresh);
}
public static NameValueCollection SetQueryString<T>(string key, T value)
{
return SetQueryString<T>(Context.Request.QueryString, key, value, false, false, false);
}
public static NameValueCollection SetQueryString<T>(string key, T value, bool compress, bool encrypt)
{
return SetQueryString<T>(Context.Request.QueryString, key, value, compress, encrypt, false);
}
public static NameValueCollection SetQueryString<T>(string key, T value, bool compress, bool encrypt, bool skipRefresh)
{
return SetQueryString<T>(Context.Request.QueryString, key, value, compress, encrypt, skipRefresh);
}
public static NameValueCollection SetQueryString<T>(string key, T value, bool replaceOriginal,
bool compress, bool encrypt, bool skipRefresh)
{
return SetQueryString<T>(replaceOriginal ? null : Context.Request.QueryString, key, value,
compress, encrypt, skipRefresh);
}
public static NameValueCollection SetQueryString<T>(NameValueCollection originalQueryString,
string key, T value, bool compress, bool encrypt, bool skipRefresh)
{
NameValueCollection nvc = CloneQueryCollection(originalQueryString);
string queryValue = Serialization.ToJson<T>(value, Format.None, false);
// Compression is applied before encryption since the unencrypted text usually
// contains more repetitive patterns the compression can use.
if (compress)
queryValue = Compression.CompressToBase64(queryValue);
if (encrypt)
queryValue = CookieEncryption.Encrypt(queryValue);
if (value != null)
if (nvc[key] == null)
nvc.Add(key, queryValue);
else
nvc[key] = queryValue;
else
nvc.Remove(key);
if (!skipRefresh)
Context.Response.Redirect(Context.Request.Url.AbsolutePath + "?" + ConstructQueryString(nvc));
return nvc;
}
public static string ConstructQueryString(NameValueCollection queryString)
{
string queryText = "";
for (int i = 0; i < queryString.Count; i++)
queryText += string.Format("{0}{1}={2}", i == 0 ? "" : "&", queryString.Keys[i], queryString[i]);
if (queryText.Length > 2048)
{
throw new Exception(
"The size of the query string has reached " + queryText.Length + "(Maximum allowed is 2048).");
}
return queryText;// HttpUtility.UrlEncode(queryText);
}
public static string ConstructQueryString(bool clearActualQueryString, params object[] keyValuePairs)
{
// Get an editable copy of the query string collection which does not allow editing.
NameValueCollection nvc = CloneQueryCollection(clearActualQueryString ? null : Context.Request.QueryString);
if (keyValuePairs != null)
{
for (int i = 0; i < keyValuePairs.Length; i = i + 2)
{
if (keyValuePairs[i + 1] != null) // Delete keys with null values
{
if (nvc[keyValuePairs[i].ToString()] == null)
nvc.Add(keyValuePairs[i].ToString(), keyValuePairs[i + 1].ToString());
else
nvc[keyValuePairs[i].ToString()] = keyValuePairs[i + 1].ToString();
}
}
}
return ConstructQueryString(nvc);
}
/// <summary>
/// The query string collection that the context request returns is inherently read only.
/// This function constructs and returns an editable copy of it.
/// </summary>
/// <param name="originalQueryString">The query string collection to copy</param>
/// <returns>An editable copy of the query string</returns>
private static NameValueCollection CloneQueryCollection(NameValueCollection originalQueryString)
{
NameValueCollection nvc = new NameValueCollection();
if (originalQueryString != null)
nvc.Add(originalQueryString);
return nvc;
}
public static void CopyQueryStringToSession(bool clearQueryString)
{
foreach (KeyValuePair<string, string> keyValue in Context.Request.QueryString)
SetSession(keyValue.Key, keyValue.Value);
if (clearQueryString)
ClearAnchorAndQueryString();
}
public static void CopyQueryStringToCookie(TimeSpan lifetime, bool clearQueryString)
{
foreach (KeyValuePair<string, string> keyValue in Context.Request.QueryString)
SetCookie(keyValue.Key, keyValue.Value, lifetime);
if (clearQueryString)
ClearAnchorAndQueryString();
}
public static void ClearAnchorAndQueryString()
{
Context.Response.Redirect(Context.Request.Url.AbsolutePath);
}
/// <summary>
/// Gets the anchor string from a URL. Its usage is limited to code generated URLs only.
/// </summary>
/// <param name="url">The URL from which to get the anchor tag.
/// Please note that the anchor tag is never sent as part of the HTTP request by any browser and
/// therefore it is inaccessible from the server side.
/// So this method can only be used with code generated URLs only.
/// </param>
/// <returns></returns>
public static string GetAnchor(string url)
{
string[] urlParts = url.Split('#');
return urlParts.Length > 1 ? urlParts[1] : null;
}
/// <summary>
/// Sets the anchor value in the actual page url.
/// </summary>
/// <param name="control">The control to which the page will be anchored to.</param>
public static void SetAnchor(System.Web.UI.Control control)
{
RedirectTo(Context.Request.Url.PathAndQuery, "", control.ClientID);
}
/// <summary>
/// Sets the anchor value in the actual page url.
/// </summary>
/// <param name="anchor">The client control ID to which the page will be anchored to.</param>
public static void SetAnchor(string anchor)
{
RedirectTo(Context.Request.Url.PathAndQuery, "", anchor);
}
public static void RedirectTo(string url, string queryString) { RedirectTo(url, queryString, null); }
public static void RedirectTo(string url, string queryString, string anchor)
{
//if (width + height > 0) ctx.Response.Redirect(url, "_blank",
// string.Format("menubar=0,width={0},height={1}", width, height));
Context.Response.Redirect(CreateUrl(url, queryString.ToString(), anchor));
}
public static string CreateUrl(string baseUrl, string queryString, string anchor)
{
if (!string.IsNullOrEmpty(queryString))
baseUrl = baseUrl.TrimEnd('?') + "?" + queryString.TrimStart('?');
if (!string.IsNullOrEmpty(anchor))
baseUrl = baseUrl.TrimEnd('#') + "#" + anchor.TrimStart('#');
return baseUrl;
}
public static void RefreshPage()
{
Context.Response.Redirect(Context.Request.Url.PathAndQuery, true);
}
// CACHE
public static void SetCache(string key, object value)
{
SetCache<object>(key, value, DefaultCookieLifeTime, null, CacheItemPriority.Normal, null);
}
public static void SetCache<T>(string key, T value)
{
SetCache<T>(key, value, DefaultCookieLifeTime, null, CacheItemPriority.Normal, null);
}
public static void SetCache<T>(string key, T value, TimeSpan lifeTime)
{
SetCache<T>(key, value, lifeTime, null, CacheItemPriority.Normal, null);
}
/// <summary>
/// Saves a value to the cache. The key associated with the value is associated with the session ID such that
/// it is not shared with other users.
/// </summary>
/// <typeparam name="T">The object type.</typeparam>
/// <param name="key">The key under which the value is to be saved.</param>
/// <param name="value">The value to save.</param>
/// <param name="lifeTime">The lifetime of the cache object.</param>
/// <param name="cacheDependencies">The file or cache key dependencies for the cache object that determine when it must be removed.</param>
/// <param name="cacheItemPriority">The cache priority that the cache object is given to determine when it must be removed.</param>
/// <param name="cacheItemRemovedCallback">The event that is called whenever the cache object is removed.</param>
public static void SetCache<T>(string key, T value, TimeSpan lifeTime, CacheDependency cacheDependencies,
CacheItemPriority cacheItemPriority, CacheItemRemovedCallback cacheItemRemovedCallback)
{
SetSharedCache<T>(Context.Request.AnonymousID + KeyDelimiter + key, value, lifeTime, cacheDependencies,
cacheItemPriority, cacheItemRemovedCallback);
}
public static string GetCache(string key)
{
return GetCache<string>(key);
}
public static T GetCache<T>(string key)
{
return GetSharedCache<T>(Context.Request.AnonymousID + KeyDelimiter + key);
}
// SHARED CACHE
public static void SetSharedCache(string key, object value)
{
SetSharedCache<object>(key, value, DefaultCacheLifeTime, null, CacheItemPriority.Normal, null);
}
public static void SetSharedCache<T>(string key, T value)
{
SetSharedCache<T>(key, value, DefaultCacheLifeTime, null, CacheItemPriority.Normal, null);
}
public static void SetSharedCache<T>(string key, T value, TimeSpan lifeTime)
{
SetSharedCache<T>(key, value, lifeTime, null, CacheItemPriority.Normal, null);
}
/// <summary>
/// Saves a value to the cache. The key can be accessed by other users.
/// </summary>
/// <typeparam name="T">The object type.</typeparam>
/// <param name="key">The key under which the value is to be saved.</param>
/// <param name="value">The value to save.</param>
/// <param name="lifeTime">The lifetime of the cache object.</param>
/// <param name="cacheDependencies">The file or cache key dependencies for the cache object that determine when it must be removed.</param>
/// <param name="cacheItemPriority">The cache priority that the cache object is given to determine when it must be removed.</param>
/// <param name="cacheItemRemovedCallback">The event that is called whenever the cache object is removed.</param>
public static void SetSharedCache<T>(string key, T value, TimeSpan lifeTime,
CacheDependency cacheDependencies, CacheItemPriority cacheItemPriority,
CacheItemRemovedCallback cacheItemRemovedCallback)
{
if (value != null)
HttpRuntime.Cache.Insert(key, value, cacheDependencies, DateTime.Now.Add(lifeTime),
System.Web.Caching.Cache.NoSlidingExpiration, cacheItemPriority, cacheItemRemovedCallback);
else
HttpRuntime.Cache.Remove(key);
}
public static string GetSharedCache(string key)
{
return GetSharedCache<string>(key);
}
public static T GetSharedCache<T>(string key)
{
object value = Context.Cache[key];
return value == null ? default(T) : (T)value;
}
// AUTHENTICATION
public static bool UserIsAuthenticated()
{
return (Context.User != null
&& Context.User.Identity != null
&& !string.IsNullOrEmpty(Context.User.Identity.Name));
}
public static string UserName
{
get
{
if (Context.User.Identity.IsAuthenticated)
return Context.User.Identity.Name;
// If we have never seen them return the current anonymous key for the user
string userName = GetCookie("Userkey");
return !string.IsNullOrEmpty(userName) ? userName : Context.Profile.UserName;
}
set
{
SetCookie("Userkey", value, DefaultCookieLifeTime);
}
}
}
}