Find the Latitude Longitude Of Your Home with Google Maps

Q: How to find the latitude and longitude coordinates of a place when you either have the street address or the zip code or just the name of a city.

Following are steps involved:

1. Open the Google Maps website and enter the address details in the search box.

2. Zoom In the Google Maps as much as possible until you locate the place for which you need the latitude and longitude.

3. Right click that exact location on Google Maps and select “Center Map Here”

4. Click the “Link to this Page” hyperlink on Google Maps website and copy paste the URL into notepad – look for the value of ll parameter in the URL – they are the latitude and longitude coordinates of your home.

http://maps.google.com/maps?q=san+francisco&ll=17.421306,78.457553

Copy paste that value in the Google Maps Search box again to confirm the location on Google Maps.

latitude-longitude-hyderabad

 

How to Create a Mashup by Combining 3 Different APIs

This tutorial will show you how to create a mashup of three different APIs including integration with Google Maps. This idea came about when I was searching through ProgrammableWeb’s API directory for a couple APIs that complimented each other enough that I could use one to provide the other with data. What I came up with will be known as the “Beer Mashup”.

Step 1. API Discovery

While looking through ProgrammableWeb’s directory, I found an IP geolocating tool called ipLoc. It simply accepts in an IP address and returns relevant location-specific data on it such as it’s state, city, country, postal code, etc.

I then found the very cool Beer Mapping Project, which has a huge directory of bars and pubs from not only across the US, but many other countries as well. Instantly I noticed that this was a perfect compliment to ipLoc because the BeerMapping API requires a city (which we can get from the ipLoc API) to return a list of local bars and pubs.

Lastly, I also wanted to integrate Google Maps into this mashup to plot out the addresses of the bars and pubs to add a bit of interactivity to the page instead of just displaying each bar in a simple HTML list.

Step 2. Variable Initialization

I usually find it best to start PHP documents off with some of the variables that I want to set globally within the script. Here I add a line that silences PHP warning messages (Google Maps spits out many of these if you happen to try to map an invalid address) and my BeerMashup and Google Maps API keys. We will end up using these API keys when we get to their respective steps below.

<ol>
	<li>&lt;?php</li>
	<li> error_reporting(E_ERROR|E_PARSE);  //Silence Errors</li>
	<li>//Initialize Variables</li>
	<li> $beer_api = 'YOUR_BEERMAPPING_API_KEY';</li>
	<li> $gmaps_api = 'YOUR_GOOGLEMAPS_API_KEY';</li>
</ol>

Step 3. IP Geolocation Setup

The ipLoc API allows you to either specify an IP address to get data on, or use the default IP address that the script finds.

Default Version: http://iploc.mwudka.com/iploc/json/
Static Version (IP address is hardcoded): http://iploc.mwudka.com/iploc/68.162.155.110/json/

  1. //Set Location
  2. //Visitor IP Address
  3. $ip = getenv(“REMOTE_ADDR”);
  4. //via IPLoc
  5. $iploc = file_get_contents(“http://iploc.mwudka.com/iploc/$ip/json/&#8221;);  //Format: JSON
  6. $ipdata = json_decode($iploc, true);

After a little testing, I realized that the default version of the ipLoc API was finding the location (Scottsdale, AZ, USA) of my hosting provider’s server rather than my home computer’s IP location (Pittsburgh, PA, USA). To circumvent this, I decided to use the static IP version of the API (Line 2 above) and passed in the IP address that is detected by the getenv(“REMOTE_ADDR”) php variable.

After checking if the data has been successfully returned as a decoded json formatted string, we need to extract only the specific data we want to pass to the BeerMapping API, which is the city and state.

  1. // Error checking
  2. if ($ipdata[‘city’]) {
  3. $city = $ipdata[‘city’];
  4. $state = $ipdata[‘region’];
  5. $location = $city .”, “. $state;
  6. } else {
  7. $err = “No location data returned for your IP address: “. $ip;
  8. }

Step 4. Integrating Google Maps

This step needs to be done now because the next step will add the location points to Google Maps – and Google Maps has to be initialized before any of that can happen.

To make the Google Maps integration as easy and painless as possible, I’ve enlisted the help of a great PHP class called Phoogle from System Seven Designs. This class takes care of all the Google Maps API heavy lifting for us while just allowing us to worry about the data.

All we need to do to get this to work is to first include the class file we downloaded: phoogle.php, then set some basic map parameters such as the height, width, zoom level and your Google Maps API key. (Get one of those here).

  1. //Phoogle – GoogleMaps PHP Class
  2. require_once ‘phoogle.php’;
  3. $map = new PhoogleMap();
  4. $map->setAPIKey($gmaps_api); //Using the variable we set in Step 2
  5. $map->setHeight(450);
  6. $map->setWidth(750);
  7. $map->zoomLevel = 6;
  8. $map->showType = false;

Step 5. BeerMapping API

Since we have the combined city and state in the variable $location from Step 3, we have everything we need to pull data from the BeerMapping API. Of course we also need one of their API keys, which can be requested here (about a 30 seconds process, start to finish).

A BeerMapping API call looks like this according to their examples:
Real Example:http://beermapping.com/webservice/loccity/71515667a86b8ec7f58cd22e3af86f6e/pittsburgh,pa

After substituting our variables in for the API Key (Step 2) and Location (Step 3), our BeerMapping API call now looks like this:
Our Example: http://beermapping.com/webservice/loccity/$beer_api/$location

After a little playing around with this API, I found that the location can’t have any spaces. So the below code first gets rid of the space bewtween the “city, state” format. Then it replaces all other spaces within the location with underscores “_”.

  1. //Format Location for use with API
  2. $locationF = str_replace(“, “, “,”, $location); // Remove space before “State”
  3. $locationF = str_replace(” “, “_”, $locationF); // Replace space with underscore in “City” name

Their data can only be returned in xml format, so we can easily extract the data returned by this call with thesimplexml_load_file PHP function.

  1. //BeerMapping – Format: XML
  2. $beerdata = simplexml_load_file (“http://beermapping.com/webservice/loccity/$beer_api/$locationF&#8221;);

As the image shows, we first load the whole file into the variable $beerdata. After checking to see if we returned any results…

  1. // Error checking
  2. $beererr = $beerdata->location->id; //$beererr will be 0 if there were no locations returned
  3. if ($beererr == ‘0’) {
  4. $err = “No breweries were found in “. $location;
  5. } else {

…the next step is to cycle through each bar/pub returned in the call, extracting all the data we need to pass into Google Maps (Step 4).

  1. $breweries = $beerdata->location;
  2. $barcount = count($breweries); //How Many?
  3. foreach ($breweries as $brewery) {
  4. $name = $brewery->name;
  5. $link = $brewery->reviewlink;
  6. $street = $brewery->street;
  7. $city = $brewery->city;
  8. $state = $brewery->state;
  9. $zip = $brewery->zip;
  10. $phone = $brewery->phone;
  11. //Location Point set for the Google Maps API
  12. $map->addAddress(“$street $city $state $zip”, “<a href=’$link’ title=’$name BeerMap’>$name</a><br/>$street<br />$city, $state $zip<br />Phone: $phone”);
  13. }
  14. }
  15. ?>

Line 1 above sets the structure location of the “locations”. Line 2 counts the amount of “locations” the API result returned. The remaining lines use a foreach loop to cycle though each “location” and pull out it’s address information. Line 14 sets a “point” for each brewery on our Google Map.

Step 6. HTML Generation

After finishing all the PHP code that we’ve created, we can now work on displaying it. The first few lines shown below are standard in any HTML document, but after that we get back to using PHP. We first check to see if the variable $err is FALSE – which would mean that the $err variable is empty, or that we never received an error. If we never got an error, we spit out the Google Map, otherwise we spit out an error message.

  1. <html xmlns=”http://www.w3.org/1999/xhtml”&gt;
  2. <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”&gt;
  3. <head>
  4. <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />
  5. <link rel=”stylesheet” type=”text/css” href=”styles.css” />
  6. <title>Bars Near <?php echo $location; ?></title>
  7. </head>
  8. <body>
  9. <div class=”wrapper”>
  10. <div class=”header”>
  11. <img class=”logo” src=”images/logo.png” alt=”The Beer Mashup” />
  12. <p class=”footer”>Developed by <a href=”http://www.cagintranet.com”>Chris Cagle</a> for <a href=”http://www.nettuts.com”>NETTUTS</a></p&gt;
  13. <div class=”mapdiv”>
  14. <?php
  15. if (!$err) {
  16. echo “<div>”;
  17. $map->printGoogleJS();
  18. $map->showMap();
  19. echo “<h3>”. $location .” <span>(“. $barcount .” Bars)</span></h3>”;
  20. } else {
  21. echo “<p class=\”error\”><b>”. $err .”</b></p>”;;
  22. }
  23. ?>
  24. </div>
  25. </div>
  26. </div>
  27. </body>
  28. </html>

After adding in some text and CSS and you now have a great looking web page that displays all the bars and pubs within the vicinity of the location of whoever is viewing the web page.

View the demo of the page as it stands now. The mashup is working great now, but we have one more improvement that will make all the difference when it comes to UI.

Step 7. Changing the Code to Allow Locations to be Input by the Visitor

At this point, our page works just fine but there is one small caveat: The visitor can only view bars from his or her current location. What if the visitor wants research bars in a different town rather than the one our IP API returned for him or her? Any visitor would want the ability to specify the location to research in.

To allow this, we will have a simple form that will accept in a city and state from the visitor then reload the page for the given location and skip the ipLoc API call completely. We will insert this code right before our<div class=”mapdiv”> line in Step 6.

  1. <form method=”post” id=”form” action=”beermashup2.php”>
  2. <span>location: (ex. New Orleans, LA)</span>
  3. <input type=”text” value=”” name=”loc” id=”loc” /><br class=”clear” />
  4. <input type=”submit” id=”submitted” value=”SEARCH” name=”submitted” />
  5. </form>

In order to make this work, we will need to wrap the code we made in the ipLoc step (Step 3) in an if-statement that checks if the form was submitted or not. If the form *was not* submitted (which will happen each time the page is initially loaded), then it will use the ipLoc IP geolocation code. If the form *was* submitted, it will take what the user submitted and set our $location variable to that.

  1. //Set Location
  2. if ( isset($_POST[‘loc’]) ) {
  3. //via user input
  4. $location = $_POST[‘loc’];
  5. } else {
  6. //Visitor IP Address
  7. $ip = getenv(“REMOTE_ADDR”);
  8. //via IPLoc
  9. $iploc = file_get_contents(“http://iploc.mwudka.com/iploc/$ip/json/&#8221;);  //Format: JSON
  10. $ipdata = json_decode($iploc, true);
  11. // Error checking
  12. if ($ipdata[‘city’]) {
  13. $city = $ipdata[‘city’];
  14. $state = $ipdata[‘region’];
  15. $location = $city .”, “. $state;
  16. } else {
  17. $err = “No location data returned for your IP address: “. $ip;
  18. }

Step 8. Putting it all Together

View the demo of the final application.

You can view the source code of the final project (which is pretty much just the steps above pushed together) and see how I ended up combining 3 separate APIs into one application. Take a stroll for yourself through the API directory over at ProgrammableWeb and see what you can come up with on your own. Working with APIs is my new obsession because it is exciting to be able to create something new and useful from someone else’s data. If this tutorial has helped you mashup a couple of APIs, post them here – I would love to see them.

This is How You Use the Google Maps API – screencast

So your client emails you and asks, “Can you put one of those flashy maps on my contact page so that users can actually see our building from a satellite’s view?”. You’ve used Google maps many times, but there is only one problem: you have no idea how to use the API. Well get out your spoon and dig in!

Step 1: Obtain a Unique API Key

If you were to download the source code that is provided with this article, you would find that it doesn’t work on your website. The reason is because Google requires all users to obtain a unique “API key” for each site that implements Google maps.

Never fear. It’s 100% free and takes about thirty seconds to sign up. First, visit Google’s sign up page and enter the url of your website. Don’t worry about adding a specific path. The root url will cover every page that is part of that domain. Agree to the terms and conditions and click “Generate API”.

Generate Key

That’s it! The page that you’ve been redirected to contains your unique key as well as a sample page – to serve as a crash course. Your key will look something like:

ABQIAAAAAq93o5nn5Q3TYaaSmVsHhR1DJfR2IAi0TSZmrrsgSOYoGgsxBSG2a3MNFcUDaRPk6tAEpdWI5Odv

You’ll also find a script path that will look like:

Yours will be different from mine because it will contain your own specific key value. Copy this and paste it into the head portion of your document.

Sign Up Complete

You might want to bookmark the link to the API documentation. You’ll undoubtedly be referencing it as your skills progress.

Step 2: Setting Up Your HTML

For the sake of simplicity, we’ll create a bare bones layout. Add the following within the body element of your document.

  1. <div id=”myMap” style=”width: 600px; height: 400px;”></div>

In a real world situation, you should move the styling to an external file (like I did in the video). The height and width values will by used by the API to determine the dimensions of your map. Don’t worry, nothing will be clipped off.

Step 3: Javascript

Next, add the following to your Javascript file. Review it a bit and then continue on.

  1. $(function() { // when the document is ready to be manipulated.
  2. if (GBrowserIsCompatible()) { // if the browser is compatible with Google Map’s
  3. var map = document.getElementById(“myMap”); // Get div element
  4. var m = new GMap2(map); // new instance of the GMap2 class and pass in our div location.
  5. m.setCenter(new GLatLng(36.158887, -86.782056), 13); // pass in latitude, longitude, and zoom level.
  6. }
  7. else {alert(“Your browser is not worthy.”);}
  8. });

To take this code line by line:

  • When the document is ready to be manipulated, run the code within.This is a jQuery syntax, but jQuery isn’t required in the least. You could also simply add an “onLoad()” attribute to your body element – though this is messy.
  • If the browser that the user is accessing the map from isn’t compatible with the API, then show an alert (see bottom). Otherwise, run the code within.
  • Create a variable called “map” and tell it to find the div that will contain the map.
  • Next, create a variable called “m” and make it equal to a new instance of the “GMap2″ class. Within the parenthesis, pass in the “map” variable that you just created previously
  • Finally, set a center point so that the map knows what to show. To do this, we create a new instance of the “GLatLng” class and pass in the latitude and longitude values. You can go here to grab the appropriate values. In my case, I’ve set the coordinates to my home town. After that, you can optionally input a zoom level – which I’ve set to the standard ’13′.

This code alone will give you a basic map that might be completely appropriate for your needs. However, if you’d like to also implement “zoom” and “map mode” features, read on.

Step 4: Refining Our Map

There are literally dozens of features that you can add to your map. We’ll go over a few of them. First, we’ll implement a zoom bar that will allows the users to incrementally zoom in or out.

Layout
  1. m.addControl(new GLargeMapControl())

Here, we’re taking our map and are adding a new control called “GLargeMapControl”.

Next, let’s add a feature that will allow the users to choose which map mode they desire – Normal, Satellite View, or a hybrid.

  1. var c = new GMapTypeControl(); // switch map modes
  2. m.addControl(c);
  • Create a variable called “c” and make it equal to a new instance of the “GMapTypeControl” class.
  • Add a new control, and pass in “c”.

If you refresh your browser, you’ll see that the user nows has the option to choose his viewing mode. But what if you want to set the default mode? In such instances, you would use “setMapType”.

  1. m.setMapType(G_SATELLITE_MAP);

When defining the default mode, you have three choices.

  • G_SATELLITE_MAP
  • G_NORMAL_MAP
  • G_HYBRID_MAP

You’re Finished!

That wasn’t too hard, was it? There are a few specific class names that you’ll need to memorize, or jot down for later reference. But other than that, it’s strikingly simple to implement such an advanced map into your websites.

 

 

Encrypting Connection Strings in web.config file

Introduction

ASP.NET stores all the configuration information in plain text files called web.config and machine.config files. We store all vital information including database connection strings, user names, passwords for the databases. Thus you end up storing all sensitive information in vulnerable plain text files which is nothing but security compromise.

Taking a clue, Microsoft has provided the capability to encrypt sensitive information in configuration files including connection strings in ASP.NET 2.0. With this new capability you can easily encrypt sections of configuration files which makes your application secure.

This new capability brings it with performance overhead that occurs when you encrypt or decrypt sections of web.config files. So use it sparingly. That means be judgmental and judicious when you decide to encrypt data.

ASP.NET 2.0 introduced Protected Configuration model that allows you to encrypt data using two Protected Configuration Providers. They are:

  • RSAProtectedConfigurationProvider: This is the default provider and uses the RSA Public Key Encryption algorithm to encrypt and decrypt data.
  • DataProtectionConfigurationProvider: This provider uses Windows Data Protection Application Programming Interface (DPAPI) to encrypt and decrypt data.

Let’s explore this new capability of encrypting and decrypting of connection strings in web.config files using above two providers available in ASP.NET 2.0.

Programmatic Encryption/Decryption

Take web.config file which contains valid connection string from some existing project. Bellow is an example of configuration section.

<configuration>
<appSettings/>
<connectionStrings>
<add name=”NorthwindConnectionString” connectionString=”Data Source=ARAS02-XP;Initial Catalog=Northwind;User ID=sa”
providerName=”System.Data.SqlClient” />
</connectionStrings>
<system.web>
<compilation debug=”true”/>
<authentication mode=”Windows”/>
<pages theme=”Theme1″ />
</system.web>
</configuration>

You can observe <connectionStrings> section in above sample which contains connection string information.

Add new form to your existing project and add the below method EncryptConnString() to code behind of the form. We will use RSAProtectedConfigurationProvider model to encrypt the connection strings. We will try to analyze this magic piece of code. Let’s start with namespaces. The System.configuration namespace contains classes which deal with the configuration information associated with client applications and ASP.NET applications. The System.Web.Configuration.WebConfigurationManager class is the preferred way to provide programmatic access to configuration files of ASP.NET web applications. You can use one of open methods provided by WebConfigurationManager that return configuration object which in turn provides the required methods and properties to handle the underlying configuration files. The GetSection method of configuration object returns the connectionStrings section object for the web.config file.

using System.Web.Configuration;
using System.Web.Security;
using System.Configuration;

public void EncryptConnString()
{

Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
ConfigurationSection section = config.GetSection(“connectionStrings”);
if (!section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection(“RsaProtectedConfigurationProvider”);
config.Save();
}
}

Encrypting Connection string using RSAProtectedConfigurationProvider model

You can observe in below listing that connectionStrings section is encrypted when we execute above method using RsaProctectedConfigurationProvider model.

<connectionStrings configProtectionProvider=”RsaProtectedConfigurationProvider”>
<EncryptedData Type=”http://www.w3.org/2001/04/xmlenc#Element&#8221;
xmlns=”http://www.w3.org/2001/04/xmlenc#”&gt;
<EncryptionMethod Algorithm=”http://www.w3.org/2001/04/xmlenc#tripledes-cbc” /&gt;
<KeyInfo xmlns=”http://www.w3.org/2000/09/xmldsig#”&gt;
<EncryptedKey xmlns=”http://www.w3.org/2001/04/xmlenc#”&gt;
<EncryptionMethod Algorithm=”http://www.w3.org/2001/04/xmlenc#rsa-1_5″ /&gt;
<KeyInfo xmlns=”http://www.w3.org/2000/09/xmldsig#”&gt;
<KeyName>Rsa Key</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>NQPKYTuUVO5SWpxXdBUpoMKYYUmEBBuAw8LXe+DxMYrkMzzAJsUVw6uZZLJXWa9ipAEx hvS2hhkGx7MHkpustn+IT+PpuxtIKSDFkumZdA/3kcaHuSO74M75Qt+BmW42v/KWNwVv 7umXLz78ka4jDeY/yf2BMpkcs35TkSS9PVM=</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>MVKe6xdu6h4DqGHmzuzeBqaWcL+m+Rl0EHi9uwQAqhZ9N56HzGgC66cXEiDJ8IGaSCrAYm 7z2ERQYKwjMyTJMkiJ3cSk7CSgqxfrT3+7+DzzKMkB489AmADfxtRyt3JE0bWIclhsHgLn YthS6mMiXTusSzRIcPMESb+ZAIkyCTPt6+2BxDNimgFX42Xt7abvNinknaUk
uJYKr7tgOzVfS00IesVA/jou1t8FTjM14b9YGvHPtBDq00Jm/cD9iGtP2OM6RnhLgy+MUr 3NPiuWutsEcUGELfOwkMvKQ6Igsg6eqae4c0dZlg==</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>

Similarly, we can encrypt connectionStrings information using DataProtectionConfigurationProvider model. Use the same above method and replace parameter for ProtectSection method with DataProtectionConfigurationProvider as shown below.

section.SectionInformation.ProtectSection(“RsaProtectedConfigurationProvider”);

<configuration>
<appSettings/>
<connectionStrings configProtectionProvider=”DataProtectionConfigurationProvider”>
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAcHu0TgBbIEyfG1RWWqIDSgQAAAACAAAAAAADZg AAqAAAABAAAACSAX+UlFBbL2xUT1mYruSgAAAAAASAAACgAAAAEAAAAODHdp8b3SFHl8S6 yVQ/Ydu4AQAAitMpkAI8SjZc349E63yEAV/mVQzOv29H2mXvz2j+2kg8FTGYV95xySZrUH ICx/i5hBq//iQNc1v/Jp0xLxJf6+K/nSQwJTnGWBn3555HJHKU8yAeQCN9Iw/6YWs/q6oV GpPwMmoSe6jS+5bHzThxQrpUqxVXB4aHKeVnAfjcdj5bIBKe9jaZ0kP31UVlB9TB5z+94G a6LNWuWWcZf/iAfrZ/EZMkEcGJE20Reb3XSm/e+LN1di2YyRxXVYV+b6MDTi7DgHC7ilZs g+/81jCn2UtW4k74wKDXrTjAS3LgWxBdFEUPnwSKbKF+/DF24MVECZ6t7oyxoPH7OqaxR/ IDnPLxHAqtd8eT9VKmzouULpQBwrO6echS1MJL8zmvCNMsLz1JnyBlwxYvst8tQs+5MCIn dQ1K9615hLiwP/JIUy9T3Hk1pCn37m8tEV+meRguS1yIOXMQ3nsPUI5d1C+Nt4068EecEk uoWujCEUHu9JcpZa2KVsnSYLix5MOEvqGPtbSMmTt7TE7leicEpEn6Hm3LWYQE2N85Skpt x5AN/Pfuwl42fMzzs07ZhRFtLDwku/a2/ZQahHIUAAAAdOITPi1vY6agWisqaA6+H/qOoc s=</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
<system.web>
<compilation debug=”true”/>
<authentication mode=”Windows”/>
<pages theme=”Theme1″ />
</system.web>
</configuration>

Encrypted Connection String using DataProtectionConfigurationProvider

You can in the similar way decrypt connection strings information using below method.

public void DecryptConnString()
{
Configuration config =WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
ConfigurationSection section = config.GetSection(“connectionStrings”);
if (section.SectionInformation.IsProtected)
{
section.SectionInformation.UnprotectSection();
config.Save();
}
}

Remember, we cannot encrypt all sections of web.config file using this above programmatic approach. There are few sections which need some additional steps before we can encrypt them with above approach.

  • <processModel>
  • <runtime>
  • <mscorlib>
  • <startup>
  • <system.runtime.remoting>
  • <configProtectedData>
  • <satelliteassemblies>
  • <cryptographySettings>
  • <cryptoNameMapping>
  • <cryptoClasses>

In order to encrypt these configuration sections you must encrypt the value and store it in the registry. There’s an aspnet_setreg.exe command-line tool to help along with this process.

Encryption/Decryption using aspnet_regiis.exe command line tool

You can also encrypt and decrypt sections in the Web.config file using the aspnet_regiis.exe command-line tool, which can be found in the <WINDOWSDIR>\Microsoft.Net\Framework\version directory. To encrypt a section of the Web.config using the DPAPI machine key with this command-line tool, use following command.

aspnet_regiis.exe -pe “connectionStrings” -app “/YourWebSiteName” –prov “DataProtectionConfigurationProvider”

To decrypt connectionStrings section using this tool, you can specify following command in aspnet_iisreg.exe tool.

aspnet_regiis.exe -pd “connectionStrings” -app “/YouWebSiteName”

Even though, ASP.NET is configured to reject all HTTP requests for resources with .config extension, but, if the malicious user gains access to web server’s file system then sensitive information in configuration file will be disclosed. Fortunately, ASP.NET 2.0 mitigates this problem by introducing encryption schemes for configuration files. You can either encrypt/decrypt configuration files including Web.config and Machine.config either programmatically or using aspnet_regiis.exe tool.

 

 

 

 

Encrypting and Decrypting a C# string

The .NET C# library provides all the basic elements for encrypting a string with a passphrase and decrypting it later. Doing this however requires a few steps in between. This post show a simple set of routines to help you do just that. We use the TripleDES encryption suite to do the actual encryption, with a little help from the MD5 hash sum generator.

The complete source code is listed below, but lets have a little look at how it works first.

 

The problem

I want to take a string, and then encrypt it using a password. The result should be a Base64 encoded string that I can store somewhere relatively safe.

01.// The message to encrypt.
02.string Msg = "This world is round, not flat, don't believe them!";
03.string Password = "secret";
04.
05.string EncryptedString = EncryptString(Msg, Password);
06.string DecryptedString = DecryptString(EncryptedString, Password);
07.
08.Console.WriteLine("Message: {0}",Msg);
09.Console.WriteLine("Password: {0}",Password);
10.Console.WriteLine("Encrypted string: {0}",EncryptedString);
11.Console.WriteLine("Decrypted string: {0}",DecryptedString);

In the EncryptString function we apply the TripleDES algorithm with a 128 bit key. But first we need to turn the above passphrase (’secret’) into a 128 bit key. One useful coincidence is that the MD5 hash algorithm accepts a set of bytes of any length and turns them into a 128 bit hash. So by running the password through the MD5 hashing algorithm we create our key.

1.// Step 1. We hash the passphrase using MD5
2.// We use the MD5 hash generator as the result is a 128 bit byte array
3.// which is a valid length for the TripleDES encoder we use below
4.
5.MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
6.byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));

The TripleDES algorithm itself turns a byte array into an encrypted byte array. So we first need to convert our C# message string (which is Unicode encoded) into a byte array through the System.Text.UTF8Encoding encoder.

The key is used to initialize the TripleDES algorithm. In addition we need to specify that we will only encode something once (CipherMode.ECB) and because its unlikely that our source string fits into a single TripleDES block we need to specify how we want to pad any remaining bytes (PaddingMode.PKCS7).

1.// Step 2. Create a new TripleDESCryptoServiceProvider object
2.TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
3.
4.// Step 3. Setup the encoder
5.TDESAlgorithm.Key = TDESKey;
6.TDESAlgorithm.Mode = CipherMode.ECB;
7.TDESAlgorithm.Padding = PaddingMode.PKCS7;

The encrypted byte array is finally converted into a Base64 encoded string for easy storage. The DecryptString function is very similar to the encryption function, except that it turns the Base64 encoded encrypted message back into the original UTF8 string.

Drawbacks to the above method

To keep the code above straightforward we made use of the fact that an MD5 hash is exactly 128 bits in length. The C# TripleDES code accepts three possible key lengths: 64 bit, 128 bit and 192 bit. Only 192 bit keys are truly TripleDES, the 128 bit key length we obtain from the MD5 hash is only sufficient for Double DES. According to Wikipedia, that would make its real key strength only equivalent to 80 bits.

The Source code

001.using System;
002.using System.Text;
003.using System.Security.Cryptography;
004.
005.namespace EncryptStringSample
006.{
007.class MainClass
008.{
009.
010.public static string EncryptString(string Message, string Passphrase)
011.{
012.byte[] Results;
013.System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
014.
015.// Step 1. We hash the passphrase using MD5
016.// We use the MD5 hash generator as the result is a 128 bit byte array
017.// which is a valid length for the TripleDES encoder we use below
018.
019.MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
020.byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
021.
022.// Step 2. Create a new TripleDESCryptoServiceProvider object
023.TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
024.
025.// Step 3. Setup the encoder
026.TDESAlgorithm.Key = TDESKey;
027.TDESAlgorithm.Mode = CipherMode.ECB;
028.TDESAlgorithm.Padding = PaddingMode.PKCS7;
029.
030.// Step 4. Convert the input string to a byte[]
031.byte[] DataToEncrypt = UTF8.GetBytes(Message);
032.
033.// Step 5. Attempt to encrypt the string
034.try
035.{
036.ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
037.Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
038.}
039.finally
040.{
041.// Clear the TripleDes and Hashprovider services of any sensitive information
042.TDESAlgorithm.Clear();
043.HashProvider.Clear();
044.}
045.
046.// Step 6. Return the encrypted string as a base64 encoded string
047.return Convert.ToBase64String(Results);
048.}
049.
050.public static string DecryptString(string Message, string Passphrase)
051.{
052.byte[] Results;
053.System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
054.
055.// Step 1. We hash the passphrase using MD5
056.// We use the MD5 hash generator as the result is a 128 bit byte array
057.// which is a valid length for the TripleDES encoder we use below
058.
059.MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
060.byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
061.
062.// Step 2. Create a new TripleDESCryptoServiceProvider object
063.TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
064.
065.// Step 3. Setup the decoder
066.TDESAlgorithm.Key = TDESKey;
067.TDESAlgorithm.Mode = CipherMode.ECB;
068.TDESAlgorithm.Padding = PaddingMode.PKCS7;
069.
070.// Step 4. Convert the input string to a byte[]
071.byte[] DataToDecrypt = Convert.FromBase64String(Message);
072.
073.// Step 5. Attempt to decrypt the string
074.try
075.{
076.ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
077.Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);
078.}
079.finally
080.{
081.// Clear the TripleDes and Hashprovider services of any sensitive information
082.TDESAlgorithm.Clear();
083.HashProvider.Clear();
084.}
085.
086.// Step 6. Return the decrypted string in UTF8 format
087.return UTF8.GetString( Results );
088.}
089.
090.public static void Main(string[] args)
091.{
092.// The message to encrypt.
093.string Msg = "This world is round, not flat, don't believe them!";
094.string Password = "secret";
095.
096.string EncryptedString = EncryptString(Msg, Password);
097.string DecryptedString = DecryptString(EncryptedString, Password);
098.
099.Console.WriteLine("Message: {0}",Msg);
100.Console.WriteLine("Password: {0}",Password);
101.Console.WriteLine("Encrypted string: {0}",EncryptedString);
102.Console.WriteLine("Decrypted string: {0}",DecryptedString);
103.}
104.}
105.}

 

ASP.NET MVC: Using Ajax, Json and PartialViews

While working on a new ASP.NET MVC project, I had a simple objective: add a new record and refresh my View. After sifting through several sites I found several resources that lead me to accomplish my goal.

I’ve compiled my result into a new sample MVC Application that I created in Visual Studio that you can download here. I’ll explain what I did using that as my reference. It’s a trimmed down version of what I did on the actual project, but it will get the point across.

Let’s assume we want to have a View that lists some People from our data source. I started out by creating a Person data model:

public class Person
{
  public Guid Id { get; set; }
  public String FirstName { get; set; }
  public String LastName { get; set; }

  public Person()
  {
    Id = Guid.NewGuid();
  }
}

Next, I created some ViewModels so that I can work with strongly typed Views:

public class PersonIndexViewModel
  {
    public PersonListViewModel PersonListModel { get; set; }

    public AddPersonViewModel AddPersonModel { get; set; }
  }

  public class PersonListViewModel
  {
    public List PersonList { get; set; }
  }

  public class AddPersonViewModel
  {
    public String FirstName { get; set; }
    public String LastName { get; set; }
}

Next, I added a People folder in my Views folder and created a strongly typed Index View on my PersonIndexViewModel. I started out with building a table and doing a foreach to display each Person object. I moved that into a PartialView (.ascx) by creating a ParitialView in my Views/Shared folder (This blog post is very helpful for showing you how to use PartialViews). I called that PersonList.ascx and that is a strongly typed partial view on my PersonListViewModel.

Now, I can update my View to display that PartialView with this code:

<% Html.RenderPartial("PersonList", Model.PersonListModel); %>

Next, I want to be able to perform a delete action to remove a Person from the DB. You’ll notice I’m using an Ajax.ActionLink in my PersonList PartialView so that I can perform the delete with Ajax.

<%= Ajax.ActionLink("delete", "JsonDelete", "People",
new { Id = person.Id },
new AjaxOptions { Confirm = "Are you sure you want to Delete this Person? This action cannot be undone.",
HttpMethod = "Delete",
OnComplete = "JsonDelete_OnComplete" })%>

In the ActionLink, I specify the Action I want to call, pass the Person.Id and in the AjaxOptions I defined a JavaScript method that should be called on complete. In my People Controller I can now add the JsonDelete method:

[AcceptVerbs(HttpVerbs.Delete)]
public JsonResult JsonDelete(Guid Id)
{
  // call your Repository to delete the Person
  bool result = _personList.Remove(toDelete);

  // return a Json Object, you could define a new class
  return Json(new
  {
    Success = result,
    Message = result ? "The person has been deleted!" : "Error!"
  });
}

You would call your Repository to delete that Person and then return a new Json Object. What I did was define a couple of properties that I will reference from the JavaScript function to give feedback to the user. Here is the JavaScript function:

function JsonDelete_OnComplete(context) {

  var JsonDelete = context.get_response().get_object();

  if (JsonDelete.Success) {
    $(this).parents('tr.item').remove();
  }

  $("#message").html(JsonDelete.Message);
}

I found this link that showed me how to use “context.get_response().get_object();” to get the Json Object in JavaScript.

Now that I can delete, the next logical step would be the ability to add a new Person. I’ll start out by creating a new form that uses my AddPersonViewModel Model:

<% using (Ajax.BeginForm("JsonAdd", "People", new AjaxOptions { OnComplete = "JsonAdd_OnComplete" }))
 {%>
<fieldset>
  <legend>Add a Person</legend>
  <%= Html.LabelFor(model => model.AddPersonModel.FirstName)%>:
  <%= Html.TextBoxFor(model => model.AddPersonModel.FirstName, new { @class = "firstname" })%>
  <%= Html.ValidationMessageFor(model => model.AddPersonModel.FirstName)%>

  <%= Html.LabelFor(model => model.AddPersonModel.LastName)%>:
  <%= Html.TextBoxFor(model => model.AddPersonModel.LastName, new { @class = "lastname" })%>
  <%= Html.ValidationMessageFor(model => model.AddPersonModel.LastName)%>

  <input id="AddBtn" name="AddBtn" type="submit" value="Add" />
</fieldset>
<% } %>

Again, I use the Ajax.BeginForm to set the Action to call and define a JavaScript function to call on complete. To my Controller I add:

public JsonResult JsonAdd(AddPersonViewModel AddPersonModel)
{
  ...

  Person newPerson = new Person
  {
    FirstName = AddPersonModel.FirstName,
    LastName = AddPersonModel.LastName
  };

  // call your Repository to add the new Person
  _personList.Add(newPerson);

  // return a Json Object, you could define a new class
  return Json(new
  {
    Success = true,
    Message = "The person has been added!",
    PartialViewHtml = RenderPartialViewToString("PersonList", new PersonListViewModel {PersonList = _personList})
  });
}

One important thing here is the method “RenderPartialViewToString”. I ran across this which was a tremendous resource in solving my problem here, which was returning a Json Object with a rendered PartialView so that I could use JavaScript/jQuery to update the page.

The post I referenced above showed where you needed to create a base Controller to inherit from and that Controller defines the methods which will return a PartialView as an HTML string:

public abstract class BaseController : Controller
  {
    protected string RenderPartialViewToString()
    {
      return RenderPartialViewToString(null, null);
    }

    protected string RenderPartialViewToString(string viewName)
    {
      return RenderPartialViewToString(viewName, null);
    }

    protected string RenderPartialViewToString(object model)
    {
      return RenderPartialViewToString(null, model);
    }

    protected string RenderPartialViewToString(string viewName, object model)
    {
      if (string.IsNullOrEmpty(viewName))
        viewName = ControllerContext.RouteData.GetRequiredString("action");

      ViewData.Model = model;

      using (StringWriter sw = new StringWriter())
      {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
        ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
      }
    }
}

Now with my JavaScript function is called, I can again reference my Json Object and then update the page:

function JsonAdd_OnComplete(context) {

  var JsonAdd = context.get_response().get_object();

  if (JsonAdd.Success) {
    $("#PersonList").html(JsonAdd.PartialViewHtml);
  }

  $("#message").html(JsonAdd.Message);
}

With this line:

$("#PersonList").html(JsonAdd.PartialViewHtml);

I have a div tag that surrounds my Html.RenderPartial call and I can use jQuery to just replace the HTML. Remember JsonAdd.PartialViewHtml contains the entire HTML of the newly rendered PartialView that we called from the Controller:

return Json(new
{
  Success = true,
  Message = "The person has been added!",
  PartialViewHtml = RenderPartialViewToString("PersonList", new PersonListViewModel {PersonList = _personList})
});

That just about sums it up how to use Ajax, jQuery, Json, and PartialViews in an effective manor in an ASP.NET MVC application.

Reducing Code by Using jQuery Templates

Reducing Code by Using jQuery Templates

imageNearly every language out there uses templates in some shape or form to minimize the amount of code that has to be written in an application. By using templates you can define a template structure once and use it to generate code, HTML or other formats. If you’ve created ASP.NET applications then you’re aware of how powerful and productive templates are when it comes to generating HTML output. However, what if you want to use templates on the client-side to generate HTML rather than writing a lot of JavaScript to manipulate the DOM?

Although templates have been available in jQuery for quite awhile through various plug-ins, the latest template framework worked on jointly by Microsoft and the jQuery team provides a great solution that doesn’t use CSS in strange ways or require a lot of knowledge about a template language. By using it you can define HTML templates in web pages and use them to render HTML output dynamically at runtime. I’ll cover the basics of using the jQuery Templates in this post but you can get additional information fromhttp://api.jquery.com/category/plugins/templates.

You can download the jQuery Templates script here along with a sample application or reference one of the following Microsoft CDN scripts:

Defining a Template Block

Templates are defined by referencing the template script mentioned above and then defining a <script> block in your page with a type of text/x-jquery-tmpl as shown next:

 

<script id="OrderSummaryTemplate" type="text/x-jquery-tmpl">
    <!-- Template goes here –>
</script>

 

Once the script tag is defined you can place template code inside of it. Any HTML that you add is output automatically once the template is rendered. Of course, adding static HTML doesn’t accomplish much so jQuery Templates provides a template tag language that contains several tags that can be placed inside of a template to define data that should be output, perform conditional logic, iterate through items, render nested templates, plus more. The different template tags available with jQuery Templates are are shown next (descriptions and some of the examples are from the jQuery Templates documentation):

Template Tag Example Description
${fieldNameOrExpression} ${ DeliveryFee } Used for insertion of data values in the rendered template. Evaluates the specified field (property) on the current data item, or the specified JavaScript function or expression.
{{html fieldNameOrExpression}} {{html Comments}} Used for insertion of HTML markup strings in the rendered template. Evaluates the specified field on the current data item, or the specified JavaScript function or expression.
{{if}}
{{if DeliveryFee > 0}}
   ${ DeliveryFee } added to your order.
{{/if}}
Used for conditional insertion of content. Renders the content between the opening and closing template tags only if the specified data item field, JavaScript function or expression does not evaluate to false (or to zero, null or undefined).
{{else}}
{{if MainItems.length==0}}
    <tr>
        <td>No items selected</td>
    </tr>
{{else}}
    <tr>
        <td>Ordered items!</td>
    </tr>    
{{/if}}
Used in association with the {{if}}…{{/if}} tag to provide alternative content based on the values of one or more expressions. The {{else}} tag can be used without a parameter, as in: {{if a}}…{{else}}…{{/if}}, or with a parameter, as in: {{if a}}…{{else b}}…{{/if}}.
{{each}}
{{each(i,mi) MainItems}}
    <tr>
        <td>
            ${ mi.NumberOrdered } ordered 
            at $ ${ mi.Price} per item
        </td>
    </tr>
{{/each}}
Used to iterate over a data array, and render the content between the opening and closing template tags once for each data item.
{{tmpl}}
<script id="movieTemplate" type="text/x-jquery-tmpl"> 
    {{tmpl "#titleTemplate"}}
    <tr>
       <td>${ Director }</td>
    </tr>
</script>

<script id="titleTemplate" type="text/x-jquery-tmpl"> 
    <tr>
        <td>${ Name }</td>
    </tr>
</script>
Used for composition of templates. Renders one or more nested template items within the rendered output of the parent template.
{{wrap}}
<script id="myTmpl" type="text/x-jquery-tmpl">
    The following wraps some HTML content:
    {{wrap "#tableWrapper"}}
        <div>
            First <b>content</b>
        </div>
        <div>
            And <em>more</em> <b>content</b>...
        </div>
    {{/wrap}}
</script>

<script id="tableWrapper" type="text/x-jquery-tmpl">
    <table><tbody>
        <tr>
            {{each $item.html("div")}}
                <td>
                    {{html $value}}
                </td>
            {{/each}}
        </tr>
    </tbody></table>
</script>
Used for composition of templates which incorporate wrapped HTML content. Rendered template items can combine wrapped HTML content with template markup.

 

Rendering a Template

Once a template is defined using a <script> block you can use the jQuery Templates tmpl() function to render the template to a container. This is done by identifying the target template, calling tmpl and passing a JSON object into it and then defining where the rendered output should go:

$('#OrderSummaryTemplate').tmpl(json).appendTo('#OrderSummaryOutput');

The JSON data can be created locally or retrieved from a remote service call as shown next:

 

$.ajax({
    dataType: 'jsonp',
    url: moviesServiceUrl,
    jsonp: '$callback',
    success: showMovies
});

// Within the callback, use .tmpl() to render the data.
function showMovies(data)
{
    // Render the template with the "movies" data and insert
    // the rendered HTML under the 'movieList' element
    $('#movieTemplate').tmpl(data).appendTo('#movieList');
}

jQuery Templates in Action

A sample application that I created to demonstrate jQuery Templates in action can be downloaded here (it’s part of the sample code available with our jQuery and AJAX Programming training course). The sample app is an ASP.NET MVC 2 project named “Order Up” that leverages jQuery heavily and uses jQuery Templates to render order details. An example of the output that’s rendered is shown next:

image
The template used to generated the Totals, Delivery Information, Items Ordered and Accessories Ordered sections is shown next:

 

<script id="OrderSummaryTemplate" type="text/x-jquery-tmpl">
    <table style="width:100%;">
        <tbody>             
            <tr>
                <td>Totals:</td>                    
            </tr>                    
            <tr>
                <td style="font-size:12pt;">
                    <table style="width:400px;">
                        <tr>
                            <td style="width:50%;">Sub Total:</td>
                            <td>$<span id="FinalSubTotal">${ FinalSubTotal }</span></td>
                        </tr>
                        <tr>
                            <td style="width:50%;">Sales Tax:</td>
                            <td>$<span id="FinalSalesTax">${ FinalSalesTax }</span></td>
                        </tr>
                        {{if DeliveryFee > 0}}
                            <tr>
                                <td style="width:50%;">Delivery Fee:</td>
                                <td>$<span id="FinalDeliveryFee">${ DeliveryFee }</span></td>
                            </tr>
                        {{/if}}
                        <tr>
                            <td style="width:50%;">Admin Fee:</td>
                            <td>$<span id="FinalAdminFee">${ AdminFee }</span></td>
                        </tr>
                        <tr style="border-top:1px solid black;">
                            <td style="width:50%;font-weight:bold;">Total:</td>
                            <td>$<span id="FinalTotal">${ FinalTotal }</span></td>
                        </tr>   
                        <tr>
                            <td colspan="2">&nbsp;</td>
                        </tr>
                        <tr>
                            <td colspan="2">Will be charged to your credit card ending with ${ CreditCard }</td>
                        </tr>                     
                    </table>                        
                </td>
            </tr> 
            <tr>
                <td>&nbsp;</td>
            </tr> 
            <tr>
                <td>Delivery Information</td>                    
            </tr>
            <tr>
                <td>
                    <table style="width:500px;">
                        <tr>
                            <td style="width:25%;">Deliver To:</td>
                            <td>${ DeliveryName }</td>
                        </tr>
                        <tr>
                            <td style="width:25%;">Address:</td>
                            <td>${ DeliveryAddress }</td>
                        </tr>
                        <tr>
                            <td style="width:25%;">Date and Time:</td>
                            <td>${ DeliveryDate } from ${ DeliveryTime }</td>
                        </tr>                        
                    </table>                         
                    </td>
            </tr>
            <tr>
                <td>&nbsp;</td>
            </tr>                    
            <tr>
                <td>Items Ordered</td>
            </tr> 
            {{if MainItems.length==0}}
                <tr>
                    <td>No items selected</td>
                </tr>
            {{else}}
                {{each(i,mmi) MainItems}}
                    <tr>
                        <td>
                            ${ mmi.Name } - ${ mmi.NumberOrdered } ordered at $ ${ mmi.Price } per item
                        </td>
                    </tr>
                {{/each}}
            {{/if}}
            <tr>
                <td>&nbsp;</td>
            </tr>   
            <tr>
                <td>Accessories Ordered</td>
            </tr> 
            {{if AccessoryItems.length==0}}
                <tr>
                    <td>No items selected</td>
                </tr>
            {{else}}
                {{each(i,ai) AccessoryItems}}
                    <tr>
                        <td>
                            ${ ai.Name  } - ${ ai.NumberOrdered } ordered at $ ${ ai.Price } per item
                        </td>
                    </tr>
                {{/each}}
            {{/if}}
            <tr>
                <td>&nbsp;</td>
            </tr>                          
        </tbody>
    </table>    
</script>

The template is rendered to a div with an ID of OrderSummaryOutput using the following code.  The code first creates a JSON object by retrieving data from controls in a checkout wizard and then calls the jQuery Templates tmpl() function:

 

function LoadApprovalDiv()
{
    var subTotal = parseFloat($('#SubTotal').text());
    $('#ClientSubTotal').val(subTotal.toFixed(2));
    var salesTaxRate = parseFloat($('#SalesTaxRate').val()) / 100;
    var salesTaxAmount = (subTotal * salesTaxRate) * .9;
    var deliveryFee = parseFloat($('#DeliveryFee').val());
    var adminFee = ((subTotal + salesTaxAmount + deliveryFee) * .05);
    var total = (Round(subTotal) + Round(salesTaxAmount) + Round(deliveryFee) + 
                 Round(adminFee));
    $('#ClientTotal').val(total);
    var deliveryAddress = $('#Delivery_Street').val();
    //See if they entered a suite
    if ($('#Delivery_Suite').val() != '') deliveryAddress += ', Suite ' + $('#Delivery_Suite').val();
    deliveryAddress += ' ' + $('#Delivery_City').val() + ' ' + $('#Delivery_StateID option:selected').text() + ' ' + 
                       $('#Delivery_Zip').val();
    var creditCard = $('#Payment_CreditCardNumber').val();
    var abbrCreditCard = '*' + creditCard.substring(creditCard.length - 5);

    var json = {
                   'FinalSubTotal'  : subTotal.toFixed(2),
                   'FinalSalesTax'  : salesTaxAmount.toFixed(2),
                   'FinalTotal'     : total.toFixed(2),
                   'DeliveryFee'    : deliveryFee.toFixed(2),
                   'AdminFee'       : adminFee.toFixed(2),
                   'DeliveryName'   : $('#Delivery_Name').val(),
                   'DeliveryAddress': deliveryAddress,
                   'CreditCard'     : abbrCreditCard,
                   'DeliveryDate'   : $('#Delivery_DeliveryDate').val(),
                   'DeliveryTime'   : $('#Delivery_DeliveryTime option:selected').text(),
                   'MainItems'      : GenerateJson('Main'),
                   'AccessoryItems' : GenerateJson('Accessory')
               };

       $('#OrderSummaryOutput').html('');
       //jQuery template example
       $('#OrderSummaryTemplate').tmpl(json).appendTo('#OrderSummaryOutput');

}

If you’re working with dynamic web applications that leverage jQuery and AJAX you’ll find that the new jQuery Templates plug-in can significantly increase your productivity and eliminate a lot of code that you’d normally have to write. It’s a great tool to have in your jQuery arsenal!

 

 

Logo_702D5F60[1]

If you or your company is interested in training, consulting or mentoring on jQuery or .NET technologies please visit http://www.thewahlingroup.com for more information. We’ve provided training, consulting and mentoring services to some of the largest companies in the world and would enjoy sharing our knowledge and real-world lessons learned with you.

 

ASP.NET MVC from Basics to Tips and Tricks

I had a great time speaking at the Fort Smith .NET User Group last week.  ASP.NET MVC is a subject that I am very passionate about.  I recently had the pleasure of developing an e-commerce website for Wolff Wire – Office Organizers using this technology.  Since then I have been using it anytime I can.  The development feels so much cleaner, and the code is more organized than in ASP.NET WebForms.  In addition the HTML output is not cluttered with ViewState and ClientIDs.

Unfortunately I wasn’t able to get quite as far as I wanted with the presentation, so I figured that I would go ahead and hit the highlights of my presentation in this blog post.

I am not an expert, so if anyone has better ways of doing things please let me know.

The Basics

First off MVC stands for Model-View-Controller.  Below some of the basic components are listed.

  • Model = Data / State
  • View = Responsible only for rendering the HTML output (.aspx page)
  • Controller = Presentation Logic (class with action methods)
    • HTTP operations are routed here
    • Responsible for selecting the appropriate View
    • Provides the View with the proper Model
  • Routing = URL Processing Engine
    • Determines based on the URL what Action Methods to call on the Controller
    • Default URL Structure = Controller Prefix/Action/ID = ex. Product/Detail/2
    • Very Customizable
  • Html Helpers = Methods that generate html (used in View)
    • Partially equates to WebForms Controls
    • Encapsulates more advanced rendering logic outside of the View
    • Html.ActionLink is very important
      • ex. Html.ActionLink( DisplayText, Action, Controller, new {ID or other defined value as property of an anonymous type}, new {anchor tag html attribute defined as a property of an anonymous type})

 

Tips and Tricks / Best Practices

  1. Use Html.ActionLink
    Do not manually create anchor tags, because if the routing configuration is changed your links will be broken.  Html.ActionLink automatically renders appropriate URLs based on the current routing configuration.
  2. Use Descriptive Keyword Rich Names Instead of Database Table IDs (SEO) In URLs
    This is particularly useful for public facing websites such as blogs or e-commerce sites.  Google and other search engines index keywords in URLs, and ID numbers yield no benefit.  Again the default URL structure in ASP.NET MVC is “Controller Prefix/Action/ID” (Product/Detail/2).  There is nothing stating that “ID” has to be an integer.  You could have something like “Product/Detail/paper-tray”.  Just be sure that the controller action methods “ID” parameter is typed as a string.  I generally keep an indexed column in my database for this.  It is a lower case variation of the display name with dashes in place of spaces.  I suppose you could also use a lookup dictionary that maps to the table ID instead.
  3. Configure Routing to Optimize URLs
    Don’t feel bound to the default URL routing configuration.  The routing is very customizable as seen below.

    routes.MapRouteLowercase(
        "Catalog",                                             
        "workspace-organizers",                          
        new { controller = "Category", action = "Index" } 
    );
    //ex. /workspace-organizers
    
    routes.MapRouteLowercase(
        "ProductCategory",                                             
        "{urlname}/cat",                          
        new { controller = "Product", action = "Index", urlname = "" } 
    );
    //ex. /desktop-accessories/cat
    
    routes.MapRouteLowercase(
        "ProductDetail",                                              
        "{urlname}/prod",                         
        new { controller = "Product", action = "Details", urlname = "" }  
    );
    //ex. /cd-holder/prod
  4. Use Strongly Typed Models
    Avoid using hard coded “Magic” strings whenever possible.  One way to send model data to the view is through the use of the ViewData dictionary object.

    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";
        return View();
    }
    <h2><%=
    
    Html.Encode(ViewData["Message"])

    %></h2>

    This is problematic for a number of reasons.  Errors from typos and broken references when refactoring may not show up until runtime.  Also complex objects stored in the dictionary will have to be typed in the view in order to access their properties.  It is best to give your view a specified model type as shown below.

    public ActionResult Index()
    {
        string strMessage = "Welcome to ASP.NET MVC!";
        return View(strMessage);
    }

    Next in the view give the page declaration’s inherits attribute a type.

    Inherits="System.Web.Mvc.ViewPage<string>"

    Then you can utilize the “Model”, which is the instance of the specified type.

    <h2><%=
    
    Html.Encode(Model)

    %></h2>

  5. Use ViewModels
    Often it is necessary to have more than one type represented as model data.  I prefer to have a model per view that consolidates all the required types.

    public class ProductIndexViewModel : ViewModelBase
    {
        public string CategoryName { get; set; }
        public IEnumerable<CatalogListItem> CatalogItems { get; set; }
    }
    public ActionResult Index(string id)
    {
        var viewmodel = new Models.ProductIndexViewModel();
        viewmodel.CatalogItems = productRepository.GetCatalogItems(id);
        viewmodel.CategoryName = categoryRepository.GetCategoryName(id);
        return View(viewmodel);
    }
  6. Use a Master ViewModel
    How do you get data to a master page so it can be used across multiple pages?  A shopping cart summary is one example of where this is needed.

    One option is to have a master controller that all relevant controllers would inherit.  The master controller could set a value in the ViewData dictionary.  Again I don’t like this because it isn’t strongly typed.

    Another option is to use RenderAction to simulate an http request and return a partial view rendered to html.  This has some advantages in that sections of a page can be cached.

    The technique I like to use is to create a master viewmodel that the other models inherit.  Master pages can have a specified model type just like normal views, so I set the master page’s type to the view model base.  This will work as long as every view that implements the master page receives a viewmodel that inherits from the master view model.

    public class ViewModelBase
    {
        public ViewModelBase()
        {
            SiteHeaderText = "MVC Outdoor Catalog";
        }
    
        public string SiteHeaderText { get; set; }
    }
    <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<MvcCatalog.Models.ViewModelBase>" %>
    <h1><%= Html.Encode(Model.SiteHeaderText) %></h1>
  7. Use Custom HTML Helper Extensions
    Use html helper extension methods for complex rendering logic.  I first started using this technique when I needed to add some functionality to navigation menu items on a master page.  Initially it was an unordered list containing links generated using Html.ActionLink.  The current page’s menu item needed to have a different CSS class.  Custom HTML Helper to the rescue.  (Originally I found a variation of this at http://www.asp.net/learn/mvc/tutorial-27-cs.aspx )

    public static class MenuItemHelper
    {
        public static string MenuItem(this HtmlHelper helper, string linkText, string actionName, string controllerName)
        {
            string currentControllerName = (string)helper.ViewContext.RouteData.Values["controller"];
            string currentActionName = (string)helper.ViewContext.RouteData.Values["action"];
    
            // Add selected class
            if (currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase) && currentActionName.Equals(actionName, StringComparison.CurrentCultureIgnoreCase))
                return string.Concat("<li class=\"selected\">", helper.ActionLink(linkText, actionName, controllerName), "</li>");
    
            // Add link
            return string.Concat("<li>", helper.ActionLink(linkText, actionName, controllerName), "</li>");
        }
    }
    <ul id="menu">              
        <%= Html.MenuItem("Home", "Index", "Home")%>
        <%= Html.MenuItem("Catalog", "Index", "Category")%>
        <%= Html.MenuItem("About", "About", "Home")%>
    </ul>
  8. Use Custom Routing Extensions
    I like all my URLs to be lower case, but I don’t want to change my controller and action methods to be lower case.  The use of a RoutingCollection extension method easily solves this.  Found this nifty extension method at: http://goneale.com/2008/12/19/lowercase-route-urls-in-aspnet-mvc/

    routes.MapRoute(
        "Default",                                            
        "{controller}/{action}/{id}",                         
        new { controller = "Home", action = "Index", id = "" }
    );

    Using the normal “MapRoute” method as in the snippet above would create a URL structure like “Product/Detail/binder-holder”.

    routes.MapRouteLowercase(
        "Default",                                            
        "{controller}/{action}/{id}",                         
        new { controller = "Home", action = "Index", id = "" }
    );

    Using the modified “MapRouteLowerCase” extension method creates a URL like “product/detail/binder-holder”.

  9. Separate Data Access Logic and Business Logic from the Controller
    The controller is really just for presentation layer management logic.  It should decide what view gets rendered and hand that view the appropriate model data.  I prefer to use the repository pattern to separate the data access logic from the controller.  I also like to use a repository interface so that it can be swapped easily with a different data access method without affecting the controller.  In this case I used manual dependency injection, but an IOC framework could be used.

    public interface ICategoryRepository
        {
            void Add(MvcCatalog.Models.Category category);
            System.Collections.Generic.IEnumerable<MvcCatalog.Models.Category> GetCategories();
            string GetCategoryName(string id);
            void Save();
        }
    ICategoryRepository categoryRepository = new CategoryRepositoryLinqToSQL();
    
    public ActionResult Index()
    {
        var viewmodel = new Models.CategoryIndexViewModel();
        viewmodel.Categories = categoryRepository.GetCategories();
        return View(viewmodel);
    }
  10. Cache Your Data
    A substantial performance gain can be made by not hitting your database for every request.  Again here is another good reason to use the repository pattern.

    public class CategoryRepositoryCached : ICategoryRepository
    {
        private const string cacheName = "Categories";
        ICategoryRepository _repository;
    
        public CategoryRepositoryCached() 
            : this(new CategoryRepositoryLinqToSQL())
        {}
    
        public CategoryRepositoryCached(ICategoryRepository repository)
        {
            _repository = repository;
        }
    
        #region ICategoryRepository Members
    
        public void Add(Category category)
        {
            _repository.Add(category);
        }
    
        public IEnumerable<Category> GetCategories()
        {
            var categories = (IEnumerable<Category>) HttpContext.Current.Cache[cacheName];
            if (categories == null)
            {
                categories = _repository.GetCategories();
                HttpContext.Current.Cache[cacheName] = categories;
            }
    
            return categories;
        }
    
        public string GetCategoryName(string id)
        {
            return _repository.GetCategoryName(id);
        }
    
        public void Save()
        {
            _repository.Save();
            HttpContext.Current.Cache.Remove(cacheName);
        }
    
        #endregion
    }
  11. jQuery + JSON Action Methods = Cool
    It is easy to return a JSON object instead of a view.

    public JsonResult Create(string CategoryName)
    {
        var category = new Models.Category();
        category.Name = CategoryName;
        category.URLName = CategoryName.ToLower().Replace(" ", "-");
        categoryRepository.Add(category);
        categoryRepository.Save();
    
        return Json(category);
    }
    <script type="text/javascript" language="javascript">
        $("#CreateNewCategory").click(function() {
            $.getJSON("/category/create/",
                      { "CategoryName": $("#NewCategoryName").val() },
                      CategoryAdded);
                  });
    
                  function CategoryAdded(category) {
                      $("#CategoryList").append("<li><a href=\"" + category.URLName + "/cat\">" + category.Name + "</a></li>");
                  }
    </script>
  12. (When using IIS 6) Use httphandlers and httpmodules for http compression and client side static file caching
    The problem with using wildcard mapping under IIS6 is that you loose a lot of IIS functionality like http compression and client side static file caching.  I use this nifty work around: http://code.msdn.microsoft.com/fastmvc
  13. Cache Appropriate Actions
    It can be useful to cache the rendered action results of pages that do not change very often.

    public class HomeController : Controller
    {
        [OutputCache(Duration=86400, VaryByParam="none")]
        public ActionResult Index()
        {
  14. Restricting Post Data Binding / UpdateModel
    Be careful when using UpdateModel to bind posted form values to an object.  Let’s say that you want to allow a user to edit a product while restricting them from changing the price.  Even if you don’t include an input box on your form someone could fake a form post.  There are several ways to protect against this.

    One way is to give a property exclude list to the UpdateModel method.  Here are those pesky magic strings again.

    UpdateModel(prod, null, null, new[] { "Price" });

    I prefer the strongly typed method of defining an interface that only has the properties that should be bound.

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(int id, FormCollection form)
    {
        var prod = productRepository.GetProductByID(id);
        try
        {
            UpdateModel<Models.IProductEdit>(prod);
            productRepository.Save();
  15. Note on Html Helper Magic Strings
    Again I think that magic strings should be avoided, but the default Html Helpers are full of them.  One approach is to use constants to contain the strings to one spot.  Another approach that is available in MVC Futures uses lambda expressions.  You could have something like this.

    <%= Html.ActionLink<HomeController>(c => c.Index()) %>

    Instead of.

    <%= Html.ActionLink("Home", "Index", "Home") %>

    The only problem is that this approach uses compiled lambda expressions which can have performance/scaling issues.  It is my understanding that these issues have been fixed in ASP.NET MVC v2 (thanks for the update Elijah Manor).

 

Download

Keep in mind that my sample project is not 100% best practices.  I was trying to start simple then refactoring toward better practices.  You can download the sample below (the sample product pictures come from the Microsoft MVC StoreFront sample).

ASP.NET MVC Sample Download

 

Convert ROWS TO COLUMNS

ROWS TO COLUMNS

How to convert rows into columns? We’re going to see how to do that using query, and there is the “Pivot” function in SQL Server 2005.

The easiest way is when you know the columns which are fixed. But most of the times, you want to do that in general not for specific columns.

Using Query:

If you have fixed columns, then all you will be doing is an “if-else” field that holds the column names and set them into different columns:

Example: We have 2 tables: LKUP_Subject which is a lookup table that holds the subject names, and the Student_Subject which contains the student grades for the different subject.

We are going to build the query having fixed columns:

  1. We use the “if-else” functionality in the query to put them in the defined columns (in SQL, it is “case”):

SELECT StudentId,
(CASE SubjectId WHEN 24 THEN ISNULL(Grade, 0) END) AS Physics,
(CASE SubjectId WHEN 25 THEN ISNULL(Grade, 0) END) AS Chemistry,
(CASE SubjectId WHEN 26 THEN ISNULL(Grade, 0) END) As Math,
(CASE SubjectId WHEN 28 THEN ISNULL(Grade, 0) END) AS English
FROM Student_Subject

2.       Then we use the “SUM” function to merge the results in 1 row like we want:

SELECT StudentId,
SUM(Physics) AS Physics,
SUM(Chemistry) As Chemistry,
SUM(Math) AS Math,
SUM(English) As English
FROM
(SELECT StudentId,
(CASE SubjectId WHEN 24 THEN ISNULL(Grade, 0) END) AS Physics,
(CASE SubjectId WHEN 25 THEN ISNULL(Grade, 0) END) AS Chemistry,
(CASE SubjectId WHEN 26 THEN ISNULL(Grade, 0) END) As Math,
(CASE SubjectId WHEN 28 THEN ISNULL(Grade, 0) END) AS English
FROM Student_Subject) s
GROUP BY StudentId


 

Now, we will build it dynamically using cursor (you can do it using temporary tables to do the same functionality for performance reasons):

 

DECLARE Cur CURSOR FOR
SELECT DISTINCT id, ‘[‘ + Description_En + ‘]’ AS Description_En
FROM LKUP_Subject

DECLARE @SubjectName NVARCHAR(MAX),
@SubjectId INT,
@Sum NVARCHAR(MAX), — The SUM part of the query
@Select NVARCHAR(MAX), — The inner query
@Sql NVARCHAR(MAX) — The total sql statement

SET @Select = ”
SET @Sum = ”
SET @Sql = ”

OPEN Cur
FETCH NEXT FROM Cur INTO @SubjectId, @SubjectName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Sum = @Sum + ‘SUM(‘ + @SubjectName + ‘) AS ‘ + @SubjectName + ‘,’
SET @Select = @Select + ‘(CASE WHEN SubjectId = ‘ + CONVERT(NVARCHAR(10), @SubjectId) + ‘ THEN Grade END) AS ‘ + @SubjectName + ‘,’
FETCH NEXT FROM Cur INTO @SubjectId, @SubjectName

END

CLOSE Cur
DEALLOCATE Cur
IF RIGHT(@Select, 1) = ‘,’
SET @Select = STUFF(@Select, LEN(@Select), 1, ‘ FROM Student_Subject’)

IF RIGHT(@Sum, 1) = ‘,’
SET @Sum = STUFF(@Sum, LEN(@Sum), 1, ”)

SET @Sql = ‘SELECT StudentId, ‘ + @Sum + ‘ FROM (SELECT StudentId, ‘ + @Select + ‘) s GROUP BY StudentId’

EXEC sp_executesql @Sql

Using Pivot:

In SQL Server 2005, there is a new feature that does all of this in a single step: PIVOT

In fixed columns, here is how we use it:

SELECT StudentId, Physics, Chemistry, Math, English
FROM
(SELECT StudentId, Grade, Description_En
FROM LKUP_Subject
INNER JOIN Student_Subject
ON LKUP_Subject.Id = Student_Subject.SubjectId) S
PIVOT
(
SUM (Grade)
FOR Description_En IN
(Physics, Chemistry, Math, English)) AS pvt

Note: that you should use an aggreate function like the SUM (for the same reason as you should use an aggreate function when using the query to transform Rows to Columns)

 

As for how to do it dynamically:

DECLARE Cur CURSOR FOR
SELECT DISTINCT Description_En
FROM LKUP_Subject

DECLARE @Temp NVARCHAR(MAX),
@AllSubjects NVARCHAR(MAX),
@SubjectQuery NVARCHAR(MAX)

SET @AllSubjects = ”

OPEN Cur
— Getting all the subjects
FETCH NEXT FROM Cur INTO @Temp
WHILE @@FETCH_STATUS = 0
BEGIN
SET @AllSubjects = @AllSubjects + ‘[‘ + @Temp + ‘],’
FETCH NEXT FROM Cur INTO @Temp
END

CLOSE Cur
DEALLOCATE Cur

SET @AllSubjects = SUBSTRING(@AllSubjects, 0, LEN(@AllSubjects))

— Building the pivot query
SET @SubjectQuery = ‘SELECT StudentId, ‘ + @AllSubjects + ‘
FROM
(SELECT StudentId, Grade, Description_En
FROM LKUP_Subject
INNER JOIN Student_Subject
ON LKUP_Subject.Id = Student_Subject.SubjectId) S
PIVOT
(
SUM (Grade)
FOR Description_En IN
(‘ + @AllSubjects + ‘)) AS pvt’

EXEC sp_executesql @SubjectQuery

Filed under: 

 

Top Secret! Keep Your E-Mail Private and Secure

E-mail is one of the most widely used forms of communication today. Estimates from May 2009 suggest that around 250 billion–with a “B”–e-mails are sent every day. That equates to more than 2.8 million e-mail messages per second, and some of them are not even spam.

E-mail is faster and cheaper than traditional postal mail, but at least when you seal that envelope and stick a stamp on it, you can have some confidence that only the intended recipient will open it. With e-mail, however, your message could be intercepted midstream, and you might never realize it.Copies and remnants of your message stored on your PC could be compromised as well. You have to take steps to secure and protect your e-mail messages.

Prying Eyes

Your PC provides easy access to your e-mail communications–both for you and for others. Anyone who happens to walk by your system–whether you’re in the middle of using it or have stepped away from your desk–could potentially see e-mail messages you are in the process of writing or have already sent, or your incoming e-mail messages. You need to take steps to minimize the opportunity for passing bystanders to snoop on your e-mail.

For starters, don’t leave your e-mail client open–or at least not maximized on screen. Whether you use a client application such as Microsoft Outlook, or a Web-based e-mail system like Google Gmail, you should minimize or close the e-mail window when you are not actively using it.

You also need to make sure that snooping eyes can’t see what’s on your screen when you walk away from your PC for an extended period of time. Many people know to lock or shut down the PC when leaving for the day, and perhaps even when going to lunch, but they might step out to discuss something with a coworker without thinking about it.

As an automatic security measure to protect your e-mail, as well as the PC in general, you should enable a screensaver (go to Control Panel/Appearance and Personalization). Set a delay before the screensaver kicks in–it shouldn’t be any less than five minutes because it is not uncommon to go five minutes without touching the mouse or keyboard while reviewing a document or reading a Web page, and having the screensaver come on would be an annoyance. Fifteen minutes is a reasonable timeframe. Make sure you check the box to display the logon screen and require credentials when resuming.

This should go without saying, but make sure you have a secure password. Using your dog’s name, or that of your favorite baseball team, won’t provide much protection. In fact, you should never use any word that can be found in a dictionary; guessing or cracking them is trivial.

Protecting Web-Based E-Mail

Web-based e-mail has the advantage of being available virtually anywhere, any time, and from any device that can get on the Web. It also comes with some additional security and privacy concerns, though.

On any PC, but particularly on a shared or public PC–such as one in a hotel or library–make sure you log out of the Web-mail client. Forgetting to actually sign out could allow the next user who comes along to access your e-mail account.

Web browsers maintain a history of visited sites, and a cache of browser data that help them load frequently visited pages more quickly. The history and cache may also inadvertently expose your e-mail messages. When you are done using your Web mail, you can go into the settings for the browser and clear out the cache.

Better yet, use private browsing. The most popular Web browsers–such as Internet Explorer, Firefox, and Chrome–have an option to surf the Web using a private or anonymous mode. When you use the private browsing mode, your entire Web session is more secure, since no data is retained in the history or cache.

Whether on a shared computer or your own PC, another suggestion is to use an alternate browser. For example, if the default browser for the PC is Internet Explorer, use Firefox, Chrome, or some other browser just for your Web mail. That way, if someone else uses the system, they will likely use the default Web browser, so using a different browser will reduce the chances of exposing or compromising your e-mail account.

Encrypt Your E-Mail

No matter how you lock down your PC, or what precautions you take to ensure that nobody can access your e-mail messages locally, the messages still have to travel from point A (the e-mail server) to point B (your PC). As the digital message traverses the Internet, those e-mails could potentially be intercepted by unauthorized users.

You can prevent your messages from being compromised by using encryption. As long as your messages are encrypted, an unauthorized user that intercepts a message would not be able to actually read it. Without the proper decryption, the content of the message would just be digital gibberish.

For Web-based e-mail like Gmail or Yahoo Mail, you can use SSL (Secure Sockets Layer) encryption. Most users recognize SSL-encrypted Web pages by the little padlock icon displayed on the browser page, or by the fact that the URL begins with “https” rather than “http”. For example, if you connect with Gmail via SSL, the connection between Google’s servers and your PC–and the message traffic over that connection–is encrypted and protected from being intercepted en route.

Microsoft Outlook can also send encrypted e-mail messages, but instead of using SSL, it relies on a system of public and private keys. The message is encrypted using your private key, and only recipients that have the associated public key will be able to view the e-mail. The public key can be shared with any recipient, whether they use Outlook or not.

Guidance on the Microsoft Office site explains, “Sending and viewing encrypted e-mail messages requires both sender and recipient to share their digital ID [digital ID: Contains a private key that stays on the sender’s computer and a certificate (with a public key). The certificate is sent with digitally signed messages. Recipients save the certificate and use the public key to encrypt messages to the sender.], or public key certificate. This means you and the recipient each must send the other a digitally signed message, which enables you to add the other person’s certificate to your Contacts. Once both parties have shared certificates, sending and viewing encrypted e-mail messages between them is the same as with any other e-mail messages.”

After You Hit Send

The precautions described above will help ensure that prying eyes don’t view or access the e-mail on your PC, and protect your messages from being intercepted en route, but what about protecting the privacy of your e-mail even after you send it? Perhaps you have something of a sensitive nature to communicate, and you want to make sure that the recipient doesn’t forward or share the message.

Microsoft Outlook has information rights management (IRM) features that let you exercise some control over your messages even after you hit Send. When you are composing an e-mail in Outlook 2010, select Options on the menu bar, then click the arrow under Permission, and check the Do Not Forward option. Recipients who are not using an e-mail client that supports Microsoft’s IRM must download the Rights Management Add-on for Internet Explorer to view restricted messages.

Some businesses manage the IRM features from their own servers, but for individuals or businesses that don’t, Microsoft can manage IRM credentials and authentication for you. The first time that you use the IRM features, Microsoft will automatically prompt you to register to use the service (to see the IRM screen, click the thumbnail image below).

 

Click for full-size image.

Microsoft’s Information Rights Management service.

Selecting the Do Not Forward option for your e-mail message makes the message private between you and the intended recipient. It lets the recipient receive and view the e-mail, but it prevents the message from being forwarded, printed, or copied.

Another way to restrict the use of your e-mail message and protect your privacy is to set the message to expire. You can define an expiration date and time for the message, after which the recipient will no longer be able to open or view it. However, this functionality only works in business settings built around Exchange Server and Group Policy. Setting an expiration for an e-mail sent to an external Yahoo mail account will have no effect.

Be careful never to assume that anything you send digitally is one hundred percent private. There is a saying that you should never say anything in an e-mail–no matter how private you might think it is–that you wouldn’t want plastered on a public Website. But, if you follow the guidance outlined here, you can take proactive steps to safeguard your privacy and at least minimize the chances that unauthorized prying eyes will see your messages.