How to store additional details in your web session cookie

If you're using the ASP.NET membership you're probably aware that one of the things it usesto keep the user logged in can be a cookie. This cookie can be used to store additional details also to help you cut down on the database calls required for simple things like the user's name or email address.

You could write your own extension to handle the cookie creation and management but you might find it easier to use a third party library called FormsAuthenticationExtensions

This extension can be installed using Nuget: Install-Package FormsAuthenticationExtensions

Once installed you can use it very easily by adding the following code to your application where the user's is being logged in:

using FormsAuthenticationExtensions;

public bool Login(string userName, string password)
		{
            // handle your own logic to check the username and password and log in the user

            // if the login is successful, store some additional details into the session ticket
            if (User.Identity.IsAuthenticated)
            {
                var user = // make a database call to get this user's name and email address

                var ticketData = new NameValueCollection
                {
                    { "firstname", user.Firstname },
                    { "surname", user.Surname },
                    { "email", user.Email }
                };
                new FormsAuthentication().SetAuthCookie(userName, true, ticketData);
            }

            return loggedIn;
		}

As you can see the above code will take the user's email and name and store it along with the session cookie.

To read the values from the cookie in your MVC controller you can use something like this:

using FormsAuthenticationExtensions;

public ActionResult MyContactDetails()
        {
            // get the email from cookie
            var ticketData = ((FormsIdentity)User.Identity).Ticket.GetStructuredUserData();
            var emailFromCookie = ticketData["id"];

            return View();
        }

Or if you want to display the cookie details in your razor view you can do this:

@using FormsAuthenticationExtensions;
@{
    var ticketData = ((FormsIdentity)User.Identity).Ticket.GetStructuredUserData();
}

email : @ticketData["email"] 

Finally, if you need to update any of the details in the cookie (for example, if the user updates their email address) you can simply do something like this:

using FormsAuthenticationExtensions;

[HttpPost]
        public ActionResult MyContactDetails(ViewModel model)
        {
            // check cookie for data
            var ticketData = ((FormsIdentity)User.Identity).Ticket.GetStructuredUserData();

            if (ModelState.IsValid)
            {
                // update some of the cookie information with the new data
                ticketData = new NameValueCollection
                {
                    { "firstname", model.Firstname },
                    { "surname", model.Surname },
                    { "email", model.Email }
                };
                new FormsAuthentication().SetAuthCookie(model.Email, true, ticketData);

                return RedirectToAction("MyContactDetailsSuccess");
            }

            return View(model);
        }

As you can see it's very easy to use and a great way of storing small data in your app to help cut down on database calls. You need to be a little careful with this and ensure that you only store the bare minimum of information here. Cookies can't be too large so if you have anything more than 3-5 additional string data types and you might want to look at using a Session value instead. You should also avoid storing any complex data types in your cookies.

Fix for CKEditor with MVC3 when using multiple submit buttons

I had an issue this weekend while updating some code from WebForms to MVC3 when using the brilliant CKEditor. Many of our forms display 2 submit buttons - one for publishing and one to save as a draft. When using WebForms there was never any issue with this. I'd just make 2 <asp:Buttons>, add some On_Click handlers and everything was great. With MVC3 I noticed that when using the CKEditor on my forms that I was having to click on the submit buttons twice before the page would submit.

At first I thought this was down to the MVC validation. I removed the validation but the issue still occured. "Ah, it must be the way I handle the postback with the 2 buttons!", I thought, but this didn't seem to work either. I put my button logic and the validation back on my page and removed the class I had put on the textarea of my form to get the CKEditor working and everything worked as expected. The issue was down to the CKEditor and how it was handling multiple submit buttons in a single form. You need to force CKEditor to update the textarea before carrying on with posting the page.

I did some searching on the CKEditor forums and on Google. I came across a piece of javascript that you can add to your webpage to work around this issue (asp.net forums link). Simply add the following to your page and it will resolve the '2 clicks to submit' issue you're having. Note you can add other events to this code if you want but paste and on keyup events should cover you 99% of the time.

$(document).ready(function () {
    for (instance in CKEDITOR.instances) {
        CKEDITOR.instances[instance].on("instanceReady", function () {
            //set keyup event
            this.document.on("keyup", function () { CKEDITOR.instances[instance].updateElement(); });
            //and paste event
            this.document.on("paste", function () { CKEDITOR.instances[instance].updateElement(); });
        });
    }
});