Phil posted on December 11, 2009 03:06

Here’s a class that’ll make your life easier when you want to deal with saving information in cookies on your user’s browser. Everyone needs a wrapper class for all those external data-stores – session, cookies, file system, web.config and app.config, registry, log files, etc. Here’s a class usable in ASP.NET Web Forms and ASP.NET MVC.

Wrapper Class

Here’s a static class that you can simply include in your web project, and refer to its static properties to get to your cookies. Any and all simple datatypes can be used, and heck, even serialized versions of your POCO objects can be saved/retrieved here. Image if you wanted to save those shopping cart items, a collection of user prefs, or whatever, you could simply override the .toString() method in your custom class.

Just Make Properties

The key pattern here is that you purposefully create new properties for each piece of data that you want to save/retrieve. This solves the problem of:

  • having to remember strings all over your project.
  • ensuring no duplicates exist – imagine if multiple developers created a defect by using the same string indexer for their cookie, and ended up stomping each other’s value?
  • typos in cookie names.

Instead, the data access cookie-retrieval is done through named properties. This solution solves all those potential problems. Here’s a peek at one of these properties.

public static string UserFullName
{
get { return GetCookieVal(CookieItem.UserFullName); }
set { UpdateCookieVal(CookieItem.UserFullName, value, 365); }
}

Enums Help

With the aforementioned ‘remembering strings’ problem, the pattern that this class uses relies internally on an enum to handle the naming of the value in the cookie. The enum will boil down to an integer, but really we don’t care what the key’s is actually stored as in the cookie. We really only care to access/read/save the values constantly and easily from our calling code.

Download

Download the cookie class, or copy/paste from below. You can see that I pre-loaded it with some amusing properties for your entertainment!

Be sure to change the ApplicationName const at the top.

Special thanks to Special-K!

using System;
using System.Web;

namespace MyNamespace
{
public class Cookies
{
private const string ApplicationName = "MyCoolApplication";

private enum CookieItem
{
UserGuid,
UserFullName,
UserLoginExpiry,
UserHadForBreakfast,
UserTimezone
}
/**************
All cookie values are accessible by public static methods.
No typos/duplicates are possible from calling code!
**************/

public static string UserFullName
{
get { return GetCookieVal(CookieItem.UserFullName); }
set { UpdateCookieVal(CookieItem.UserFullName, value, 365); }
}

public static Guid UserGuid
{
get { return new Guid(GetCookieVal(CookieItem.UserGuid)); }
set { UpdateCookieVal(CookieItem.UserGuid, value.ToString(), 365); }
}

public static DateTime UserLoginExpiry
{
get { return DateTime.Parse(GetCookieVal(CookieItem.UserLoginExpiry)); }
set { UpdateCookieVal(CookieItem.UserLoginExpiry, value.ToString(), 365); }
}

public static string UserHadForBreakfast
{
get { return GetCookieVal(CookieItem.UserHadForBreakfast); }
set { UpdateCookieVal(CookieItem.UserHadForBreakfast, value, 1); }
}

private static string GetCookieVal(CookieItem item)
{
HttpCookie cookie = GetAppCookie(false); //get the existing cookie
return (cookie != null && (cookie.Values[item.ToString()] != null)) //value or empty if doesn't exist
? cookie.Values[item.ToString()]
: string.Empty;
}

private static void UpdateCookieVal(CookieItem item, string val, int expireDays)
{
//get the existing cookie (or new if not exists)
HttpCookie cookie = GetAppCookie(true);

//modify its contents & meta.
cookie.Expires = DateTime.Now.AddDays(expireDays);
cookie.Values[item.ToString()] = val;

//add back to the http response to send back to the browser
HttpContext.Current.Response.Cookies.Add(cookie);
}

private static HttpCookie GetAppCookie(bool createIfDoesntExist)
{
//get the cookie or a new one if indicated
return HttpContext.Current.Request.Cookies[ApplicationName] ?? ((createIfDoesntExist) ? new HttpCookie(ApplicationName) : null);
}

}
}


Posted in: c# , asp.net , best practices , code blowout , development  Tags:
Actions: E-mail | Permalink | Comments (0) |

So your application needs to send emails to stakeholders/customers/admins/managers. You know the kind of emails:

  • password reminders,
  • account balances,
  • reminders & status updates
  • confirmations of all sorts

Typically my development routine consisted of something like this:

  1. Write a template email. String constants with placeholders, etc. Dear [FirstName] [LastName],
  2. Read all appropriate details from a data-store. You know, the things specific to the recipient of the email. Replace [FirstName] [LastName] with real names, or a link specific to their account to reset their password, etc.
  3. Write the email sending business logic. System.Net.Mail and all the goodness within. Attachments, BCC, SMTP, all those good things provided by that namespace. (Thank you Microsoft, for helping us forget CDONTS.)
  4. Put in your own email address to receive the unit tests and integration tests.
  5. Brace for the email flood into your mail client.
  6. Context switch between the mail client and development IDE. More back and forth for you!

New Tool in the Toolbox – Already Built into the .NET Framework!

While testing, you can have emails sent to a directory instead of being sent to SMTP server. Simply put this in your web.config:

<system.net> 
    <mailSettings> 
        <smtp deliveryMethod="SpecifiedPickupDirectory"> 
            <specifiedPickupDirectory pickupDirectoryLocation="c:\SomeEmailDirectory\" /> 
        </smtp> 
    </mailSettings> 
</system.net> 

 

So What?

So how much time does it really save you? It’s negligible, really, when your mail server is on the LAN. If you are working with an SMTP server that is unreliable, slow, or keeping accounting on mail count/charging for bandwidth, the seconds per sent email can add up.

No matter about SMTP servers… good, bad or ugly. You could monitor a directory with the .NET FileSystemWatcher to watch for newly dropped email files, and then open them automatically!

Imagine, your unit or integration tests create a new email to be sent, and another dev tool (using FileSystemWatcher) can automatically ShellExecute it for you. That saves you the time of switching to the directory, double clicking the newly created email, and then getting on with the work of checking for correctness.

Credit

Yep, this StackOverflow question keeps on giving!

http://stackoverflow.com/questions/54929/hidden-features-of-asp-net


Posted in: asp.net , c# , development , email , shortcuts , testing  Tags:
Actions: E-mail | Permalink | Comments (0) |