I use this in a self hosted web service, so I am not using a ton of libraries. I wanted a simple yet easy-to-use cookie repository. The reason the repository is static is that I wanted the ability to use the repository within Razor templates without having to use a reference object. I just find it simpler.
I feel it's pretty well-rounded in functionality as it stands right now, but a review is always nice.
using System;
using System.Collections.Generic;
using System.Linq;
namespace CookieRepository
{
class Program
{
static void Main(string[] args)
{
CookieRepository<bool>.Add("myid", "Authenticated", true);
// do something...
// Check cookie again.
if (CookieRepository<bool>.ValueEquals("myid", "Authenticated", true))
{
Console.WriteLine("Value was true, user is Authenticated.");
}
else
{
Console.WriteLine("Value was false, user is NOT Authenticated.");
}
// do something...
// Update cookie.
CookieRepository<bool>.Set("myid", "Authenticated", false);
// do something...
// Lets do another check.
if (CookieRepository<bool>.ValueEquals("myid", "Authenticated", true))
{
Console.WriteLine("Value was true, user is Authenticated.");
}
else
{
Console.WriteLine("Value was false, user is NOT Authenticated.");
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
public static class CookieRepository<T>
{
private static readonly HashSet<Cookie<T>> Cookies = new HashSet<Cookie<T>>();
/// <summary>
/// Used when you want to add a cookie and being sure that cookie by same Key does not already exist.
/// </summary>
/// <param name="SessionId">Session Id of owner</param>
/// <param name="Key">Cookie known as</param>
/// <param name="Value">Value of the cookie</param>
/// <returns></returns>
public static bool Add(string SessionId, string Key, T Value)
{
lock (Cookies)
{
if (Cookies.Any(x => x.SessionId == SessionId && x.Key == Key))
{
return false;
}
else
{
Cookies.Add(new Cookie<T>(SessionId, Key, Value));
}
return true;
}
}
/// <summary>
/// Adds or Replaces a cookie, used when ensurance that cookie by key does not already exist is of any importance.
/// </summary>
/// <param name="SessionId">Session Id of owner</param>
/// <param name="Key">Cookie known as</param>
/// <param name="Value">Value of the cookie</param>
public static void Set(string SessionId, string Key, T Value)
{
lock (Cookies)
{
var Cookie = GetCookie(SessionId, Key);
if (Cookie != null)
{
Cookies.Remove(Cookie);
}
Cookies.Add(new Cookie<T>(SessionId, Key, Value));
}
}
/// <summary>
/// Removes Cookie by specific key.
/// </summary>
/// <param name="SessionId">Session Id of owner</param>
/// <param name="Key">Cookie known as</param>
public static void Remove(string SessionId, string Key)
{
lock (Cookies)
{
var Cookie = GetCookie(SessionId, Key);
if (Cookie != null)
{
Cookies.Remove(Cookie);
}
}
}
/// <summary>
/// Removes all cookies for a specific Session. (On disconnect)
/// </summary>
/// <param name="SessionId">Session Id of owner</param>
public static void RemoveAll(string SessionId)
{
lock (Cookies)
{
var SessionCookies = Cookies.Where(x => x.SessionId == SessionId).ToList();
foreach (var Cookie in SessionCookies)
{
Cookies.Remove(Cookie);
}
}
}
/// <summary>
/// Returns ALL cookies that exist in cache by Key
/// </summary>
/// <param name="key">Cookie known as</param>
/// <returns>Queryable Interface</returns>
public static IEnumerable<Cookie<T>> GetAll(string Key)
{
lock (Cookies)
{
return Cookies.Where(x => x.Key == Key);
}
}
/// <summary>
/// Tries to get Value from an Cookie by Owner and Key
/// </summary>
/// <param name="SessionId"></param>
/// <param name="Key">Cookie known as</param>
/// <param name="value">Out Cookie</param>
/// <returns>Whether any Cookie Value could be found</returns>
public static bool TryGetValue(string SessionId, string Key, out T value)
{
value = GetValue(SessionId, Key);
return value != null;
}
/// <summary>
/// Returns Cookie value by Owner and Key
/// </summary>
/// <param name="sessionid">Session Id of owner</param>
/// <param name="key">Cookie known as</param>
/// <returns>Cookie Value</returns>
private static T GetValue(string sessionid, string key)
{
lock (Cookies)
{
return Cookies.Where(x => x.SessionId == sessionid && x.Key == key).Select(x => x.Value).FirstOrDefault();
}
}
/// <summary>
/// Tries to get Cookie by Owner and Key
/// </summary>
/// <param name="SessionId">Session Id of owner</param>
/// <param name="Key">Cookie known as</param>
/// <param name="Cookie">Out Cookie</param>
/// <returns>Whether any Cookie could could be found</returns>
public static bool TryGetCookie(string SessionId, string Key, out Cookie<T> Cookie)
{
Cookie = GetCookie(SessionId, Key);
return Cookie != null;
}
/// <summary>
/// Returns Cookie by Owner and Key
/// </summary>
/// <param name="SessionId">Session Id of owner</param>
/// <param name="Key">Cookie known as</param>
/// <returns>Cookie Object</returns>
private static Cookie<T> GetCookie(string SessionId, string Key)
{
lock (Cookies)
{
return Cookies.FirstOrDefault(x => x.SessionId == SessionId && x.Key == Key);
}
}
/// <summary>
/// Tries to find Cookie Value and Compare it with our matchwith value.
/// </summary>
/// <param name="SessionId">Session Id of owner</param>
/// <param name="Key">Cookie known as</param>
/// <param name="matchwith">Value to compare with</param>
/// <returns>Wheter cookie exsist and value matches with input value</returns>
public static bool ValueEquals(string SessionId, string Key, T matchwith)
{
T Value;
if (!TryGetValue(SessionId, Key, out Value))
{
return false;
}
return Value.Equals(matchwith);
}
}
public class Cookie<T> : IEquatable<string>
{
public Cookie(string sid, string key, T value)
{
SessionId = sid;
Value = value;
Key = key;
}
public string SessionId { get; private set; }
public string Key { get; private set; }
public T Value { get; private set; }
public bool Equals(string other)
{
return string.Format("{0}-{1}", SessionId, Key).Equals(other);
}
public override bool Equals(object other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
if (!(other is Cookie<T>)) return false;
return Equals((T)other);
}
public override string ToString()
{
return string.Format("{0}-{1}", SessionId, Key);
}
public override int GetHashCode()
{
int hash = 13;
hash = (hash * 7) + SessionId.GetHashCode();
hash = (hash * 7) + Key.GetHashCode();
return hash;
}
}
}