Cookie-based TempData provider

Source: Internet
Author: User

Original link http://brockallen.com/2012/06/11/cookie-based-tempdata-provider/
TempData is a nice feature in MVC, if I'm not mistaken, enlighten the Flash module from the Ruby on the rails. It is basically a way of keeping a certain state across redirects.

The default implementation of Rails uses cookies to store data, which makes this quite a lightweight mechanism to pass data from one request to the next. Unfortunately, TempData's default implementation of MVC uses session state as the backing store to make it less desirable. That's why I want to show how to build an implementation that uses cookies, so here is Cookietempdataprovider.

in achieving this, it is important to acknowledge that the data stored in TempData is being sent to the client as a cookie, which means that it is open to view and modify by the end user. Therefore, I want to add protection to be modified and viewed (the modification is two more important). perform encrypted and signed Forms authentication cookies and view states using the same protection facility as the ASP. due to the limited size of cookies, we are also doing compression.

the code is available on GitHub. I also wrap this up to NuGet package (Brockallen.cookietempdata) so everything is necessary to reference the assembly through NuGet, and now all the controllers will use Cookie-based tempdata providers. If you are interested in the details of the pattern, please continue reading ...

The code is self-explanatory:

public class cookietempdataprovider:itempdataprovider{    const string cookiename = "TempData";  & nbsp;  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. key        value = Protect (bytes); nbsp;      //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. key        var bytes = U Nprotect (value);       //Decompress to json         value = Decompress (bytes);       //Convert the JSON back to a Dictionar y        return Deserialize (value);   }    String Getcookievalue (ControllerContext controllercontext)     {         HttpCookie C = Controllercontext.httpcontext.request.cookies[cookiename];        if (c! = null)         {             return c.value;       }         return null;   }    void Issuecookie ( ControllerContext ControllerContext, String value)     {        HttpCookie C = new HttpCookie (cookiename, value)         {            //don ' t allow JavaScript access to the cookie             HttpOnly = true,            /Set the path so and other apps on the same server don ' t see the Cookie      &nbs p;     Path = controllercontext.httpcontext.request.applicationpath,           //Ideally we ' re always going over SSL, but is Flexible for non-ssl apps            Secure = controllercontext.httpcontext.request.issecureconnection       };         if (value = = null)         {            /If we have a expired cookie to clear the COO with no data then issue kie            c.expires = DateTime.Now.AddMonths (-1);        }        if (value! = NULL | | Controllercontext.httpcontext.request.cookies[cookiename]! = null)         {            /If we have data and then issue the COOKIE&NBSP;&NBSP;         //Also, if the request has a cookie and we need to issue the COO kie           //which might act as a means to clear the cookie &N bsp;           CONTROLLERCONTEXT.HTTPCONTEXT.RESPONSE.COOKIES.ADD (c);       }    }    string Protect (byte[] data)     {         if (data = = NULL | | data. Length = = 0) return null;        return Machinekey.encode (data, Machinekeyprotection.all);   }    byte[] Unprotect (string value)     {         if (string.isnullorwhitespace (value)) return null;         return Machinekey.decode (value, Machinekeyprotection.all);   }    byte[] Compress (string value)     {        if (value = = null) return null;        var data = Encoding.UTF8.GetBytes (value);         using (var input = new MemoryStream (data))         {             using (var output = new MemoryStream ())              {                 using (Stream cs = new Deflatestream (output, compressionmode.compress))                  {                     input. CopyTo (CS);               }                return output. ToArray ();           }        }   }    string Decompress (byte[] data)     {         if (data = = NULL | | data. Length = = 0) return null;        using (var input = new MemoryStream (data))  & nbsp;      {            using ( var output = new MemoryStream ())             {                 using Stream cs = new Deflatestream ( Input, compressionmode.decompress))                  {                    cs. CopyTo (output);               }                 var result = output. ToArray ();                return Encoding.UTF8.GetString (Result);           }        }   }    string Serialize (idictionary< String, object> data)     {        if (data = = NULL | | data. Keys.count = = 0) return null;        javascriptserializer ser = new JavaScriptSerializer ();        return ser. Serialize (data);   }    idictionary<string, OBJECT&GT Deserialize (string data)     {        if ( String.isnullorwhitespace (data)) return null;        JavaScriptSerializer ser = New JavaScriptSerializer ();        return ser. Deserialize<idictionary<string, object>> (data);   }}

Typically, using a custom Tempdataprovider You must override Createtempdataprovider from the controller base class such as:

public class homecontroller:controller{public ActionResult Index () {return View (); } protected override Itempdataprovider Createtempdataprovider ()  {  return new cookietemp Dataprovider ();     }}

benefits-This means that you must override this in each controller or you must plan ahead and create a common controller base class for the entire application. Fortunately there is another way--tempdataprovider is not negligible on the controller base class. This means that after the controller is created, you can specify it, which is easy to do in a custom controller factory in the NuGet package:

Class cookietempdatacontrollerfactory:icontrollerfactory{    Icontrollerfactory _inner;     Public cookietempdatacontrollerfactory (icontrollerfactory inner)     {         _inner = inner;   }    public IController Createcontroller (RequestContext RequestContext, string controllername)     {        //Pass-thru to the normal factory        var Controllerinterface = _inner. Createcontroller (RequestContext, controllername);        var controller = Controllerinterface as controller;        if (Controller! = null)          {           //If we get a MVC Controller then add the cookie-based tempdata provider            Controller. Tempdataprovider = new Cookietempdataprovider ();       }         return controller;   }    public Sessionstatebehavior Getcontrollersessionbehavior (RequestContext RequestContext, string controllername)     {         return _inner. Getcontrollersessionbehavior (RequestContext, controllername);   }    public void Releasecontroller (IController Controller)     {        _inner. Releasecontroller (Controller);   }}

The last thing to do is configure the custom controller factory and do this from a separate assembly by Preapplicationstartmethod allowing code to run before Applicaton_start Magic :

[Assembly:preapplicationstartmethod (typeof (BrockAllen.CookieTempData.AppStart), "Start")]namespace brockallen.cookietempdata{public class AppStart {public static void Start () {var current            Factory = ControllerBuilder.Current.GetControllerFactory ();        ControllerBuilder.Current.SetControllerFactory (New Cookietempdatacontrollerfactory (currentfactory)); }    }}
Original link http://brockallen.com/2012/06/11/cookie-based-tempdata-provider/
Code path

Cookie-based TempData provider

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.