Integrate Bing Maps With Geonames Database And ASP.NET

8. February 2011 03:11

API ASP.NET Microsoft Utils 

After Microsoft launched Bing Maps, there are few things which lead me not to use Google Maps:

  • Bing Maps are more accurate than Google Maps.
  • Bing Maps looks more pretty than Google Maps.
  • And the main reason I am using Bing Maps is because I am a Microsoft fan Cool

To locate a place on maps (Bing or Google), the best thing is to get the latitude and longitude of the location, this ensures that the place we are pinning on the map is accurate. But the big question is to where to get the latitude and longitude of the location. There might be a web service for getting the latitude and longitude of a location, but wouldn't it be nice if you just have to query a local database?

Get the Geonames data dump

Apart from providing free web services and API Geonames.org also provides their data dumps which gets updated regularly. the best things about the data dumps are that they are distributed country-wise, city-wise etc. If you wish to download the data country wise, then you can download the file(s) which are named according to the countries IATA codes. The one I am using for this example is the allCountries files from the dumps. Download this dump only if you want to have ALL the Geoname data.

 

Import data in SQL Server

The dump can be imported in the database using the Data import-Export wizard present in the SQL Server or you can write a custom tool to import the whole dump. The dump is in a TAB delimited format. Just in case if you are not aware, the file you downloaded is in UTF-8 encoding and therefore you need it to convert it to UTF-16 encoding before you actually import it into the database. There is a command line tool which will help you to convert the database dump to UTF-16 which I got from the Geoname forums.

 

This tool will convert the format of the dump file from UTF-8 to UTF-16. After the successfull conversion of the file, now comes the time to import the data in the database.

Create a database table:

CREATE TABLE GeoNames( 
geonameid int NOT NULL, 
name nvarchar(200) NULL, 
asciiname nvarchar(200) NULL, 
alternatenames nvarchar(max) NULL, 
latitude float NULL, 
longitude float NULL, 
feature_class char(2) NULL, 
feature_code nvarchar(10) NULL, 
country_code char(3) NULL, 
cc2 char(60) NULL, 
admin1_code nvarchar(20) NULL, 
admin2_code nvarchar(80) NULL, 
admin3_code nvarchar(20) NULL, 
admin4_code nvarchar(20) NULL, 
population bigint NULL, 
elevation int NULL, 
gtopo30 int NULL, 
timezone char(31) NULL, 
modification_date date NULL 
)

To import millions of records you can write a custom tool or you can use the SQL Server Data Import/Export Data wizard. I have wrote a custom tool to import, but you can use the T-SQL's BULK INSERT (because it is simple and easy) to import the dump.

BULK 
INSERT GeoNames 
FROM 'I:\Database\Dump.txt' 
WITH( 
DATAFILETYPE = 'widechar', 
FIELDTERMINATOR = '\t', 
ROWTERMINATOR = '\n' 
)

The parameters in the above SQL statement is self-explanatory and therefore I am not going to brief them. But before you can start locating places with ASP.NET make sure you have indexed the table, if not then you will receive a SQL Server timed-out error.

Working with Bing Maps

Our database is now ready and now we can start locating the places on the Bing maps. We have two pages in the project, one which we will be using to get the locations and their details on the basis of city name enter by the user and the other which will show the map with a push pin.

Default.aspx page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="BingMap._Default" EnableViewState="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <title>Bing Maps with ASP.NET and GeoNames Database</title>
    <link href="Style/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server" enableviewstate="true">
    Enter Place Name:  <asp:TextBox ID="txtPlaceName" runat="server" />
    <asp:Button ID="btnPlaceName" runat="server" Text="Get GeoData!" OnClick="btnPlaceName_Click" />
     <br />
    <br />
        <table id="GeoData" style="width: 55%;" enableviewstate="true">
            <tr>
                <td class="tdheader">
                      City Name
                </td>
                <td class="tdheader">
                      Lat./Log.
                </td>
                <td class="tdheader">
                     Country
                </td>
                <td>
                </td>
            </tr>
            <%for (int i = 0; i < RecCount; i++)
              {%>
            <tr>
                <td>
                     
                    <%=CityName[i]%>
                </td>
                <td>
                     
                    <%=Lat[i]%>
                    /
                    <%=Log[i]%>
                </td>
                <td class="country">
                     
                    <%=Country[i]%>
                </td>
                <td>
                    <a href="BingMap.aspx?lat=<%=Lat[i]%>&log=<%=Log[i]%>&place=<%=CityName[i]%>" target="_blank">Show on Map</a>
                </td>
            </tr>
            <%}%>
        </table>
    <br />
   <asp:Label ID="RecFound" Text="" runat="server" />
    </form>
</body>
</html>

The above page will get and show the details of the place. Click the Show on Map link to view the map.

 

Code Behind: Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BingMap.DBModel;


namespace BingMap
{
    public partial class _Default : System.Web.UI.Page
    {
        WorldEntities world = new WorldEntities();
        public List<string> CityName = new List<string>();
        public List<string> Country = new List<string>();
        public List<string> Lat = new List<string>();
        public List<string> Log = new List<string>();
        public int RecCount = 0;

        private void GetLocation(string CName)
        {
            try
            {
                var WorldLoc = from l in world.Geonames
                               where l.name == CName
                               select l;

                foreach (var item in WorldLoc)
                {
                    CityName.Add(item.name);
                    Country.Add(item.country_code);
                    Lat.Add(Convert.ToSingle(item.latitude));
                    Log.Add(Convert.ToSingle(item.longitude));
                    RecCount = RecCount + 1;
                }

                if (RecCount == 0)
                {
                    RecFound.Text = "No Record(s) Found!";
                }

                else
                {
                    RecFound.Text = Convert.ToString(RecCount) + " Record(s) Found!";
                }
            }
            catch (Exception x)
            {
                Response.Write(x.ToString());
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btnPlaceName_Click(object sender, EventArgs e)
        {
            if (Page.IsPostBack)
            {
                GetLocation(txtPlaceName.Text);
            }
        }
    }
}

There could be many places with the same name in different geographical locations. For example, if you query the database with San Francisco, you'll find out it is not the only place on the planet in U.S. The same is with the city in India called Hyderabad, one is in India and the other is in Pakistan. But the geographical location is different and thus we can place a push pin on the maps.

I have used a different web page for the map. From the page Default.aspx page I will pass the information (latitude, longitude and place name) in query string to pin the location on the map.

BingMap.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="BingMap.aspx.cs" Inherits="BingMap.BingMap" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Bing Map</title>
    <script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.3"></script>

    <script type="text/javascript">
        function LoadMap() {
            map = new VEMap('BingMap');
            var Latitude = '<%= LocLat %>';
            var Longitude = '<%= LocLog%>';
            var PlaceName = '<%=Place %>';
            if (Latitude.length == 0 || Longitude.length == 0) {
                var latlong = new VELatLong(28.63576, 77.22445);

                map.SetDashboardSize(VEDashboardSize.Large);
                map.LoadMap(latlong, 9, VEMapStyle.Road);

                //Add pushpin
                var pin = new VEShape(VEShapeType.Pushpin, latlong);
                pin.SetCustomIcon(null);
                pin.SetTitle("New Delhi");
                pin.SetDescription("Capital City Of India");
                map.AddShape(pin);
                map.ShowDashboard();
            }
            else {
                var latlong = new VELatLong(Latitude, Longitude);

                map.SetDashboardSize(VEDashboardSize.Large);
                map.LoadMap(latlong, 9, VEMapStyle.Road);

                //Add pushpin
                var pin = new VEShape(VEShapeType.Pushpin, latlong);
                pin.SetCustomIcon(null);
                pin.SetTitle(PlaceName);
                pin.SetDescription("<br/>" + "<strong>Latitude:</strong>" + '<%=LocLat%>' + "<br/>" + "<strong>Longitude:</strong>" + '<%=LocLog%>');
                map.AddShape(pin);
                map.ShowDashboard();
            }
        }
    </script>

</head>
<body onload="LoadMap();">
    <form id="BingForm" runat="server">
    <div id='BingMap' style="position: relative; width: 800px; height: 600px;">
    
    </div>
    </form>
</body>
</html>

The client-side script is used to load the map. I have used the version 6.3 of the Bing Maps but you can also use the version 7.0. Though you need some additional parameters to use the latest one like the Bing Maps developer API key. The map can be set in the script tag.

<script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.3"></script>

A funtion named LoadMap() will doing the rest of the job, like setting the latitude, longitude, adding push pin to the location on the map and customizing other details on the map.

var latlong = new VELatLong(28.63576, 77.22445);
map.SetDashboardSize(VEDashboardSize.Large);
map.LoadMap(latlong, 9, VEMapStyle.Road);

The first line in the above script will set the latitude and longitude. The LoadMap method should always be called after SetDashboardSize. I have set the VEDashboardSize enumeration to Large you can also use Small if you want the navigation controls of the map to appear small. LoadMap method will take 3 parameters, the first is the reference of the latitude and longitude of the location, second is the Zoom Level, which is 9 in my case, you can adjust this value according to your requirement and the third option VEMapStyle enumeration will let you set the style for the map. It can be Road, Aerial, BirdEye etc (Click on the links to know more about these enumerations). And this is it, this will load the map in the browser showing the place of your choice with specified latitude and longitude.

To be more precise an beautify the Bing Map, we can also add a push pin at the specified location and that too can also be done with the help of the client-side script.

var pin = new VEShape(VEShapeType.Pushpin, latlong);
pin.SetCustomIcon(null);
pin.SetTitle(PlaceName);
pin.SetDescription("<br/>" + "<strong>Latitude:</strong>" + '<%=LocLat%>' + "<br/>" + "<strong>Longitude:</strong>" + '<%=LocLog%>');
map.AddShape(pin);

To add a new push pin to our location we need to use VEShape class. SetCustomIcon method allows to set the custom icon for your push pin. SetTitle method will set the description for you push pin. SetDescription method sets the description of the push pin, here in the description I have set the other information like location's latitide and longitude. To add the push pin to the location the AddShape method of the map class will take pin as a parameter and set the push pin on the map.

For showing map I have used a different web page named BingMap.aspx which also includes the code behind (just a few lines) apart from client-side code:

BingMap.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace BingMap
{
    public partial class BingMap : System.Web.UI.Page
    {
        public string LocLat = "";
        public string LocLog = "";
        public string Place = "";

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString.AllKeys.Length > 0)
            {
                LocLat = Request.QueryString["lat"].ToString();
                LocLog = Request.QueryString["log"].ToString();
                Place = Request.QueryString["place"].ToString();
            }

            if (LocLat.Equals("") || LocLog.Equals(""))
            {

            }
        }
    }
}

In the code-behind I will check on page load if the count of the query string passed on to the page is greater than zero, if the condition is true then I will set the values in the public variables and set them on the client-side script which actually handles the loading, locating and adding push pin on the map. The URL on calling the BingMap.aspx page will look like this:

http://localhost:5543/BingMap.aspx?lat=28.35&log=79.41667&place=Bareilly

I have shown my home town on the map. You can also see a push pin and other details in a baloon.

 

And this is it, I can now locate any place on the Bing Maps which is present with me in Geonames database with the help of ASP.NET. The more can be done with the help of Geonames database like postcode lookup. I hope this tutorial will get you started with Bing Maps integrated with Geonames database with the help of ASP.NET.

Download: BingMap.zip (189.44 kb)

Download the UTF8ToUTF16 conversion tool

Related Links:

Currently rated 3.5 by 4 people

Windows 7 Development: Working With Task Dialog Class

24. January 2011 16:57

API C# Windows 

Last year, I blogged about few things related to Windows 7 development which includes Jump Lists and Glass Form. The Windows 7 API Code Pack comes with many other features which can be used while developing applications for Windows 7 platform. The Windows 7 API Code Pack comes with some sample applications which exposes the power of the API.

In one of my previous projects I used the Task Dialog class to use some cool looking message boxes like the one we see in Windows 7. If you see the sample code and and the executable, they are working fine but when you write the same code in the code in your application, this will not turn out to be as you would have expected. You will see a runtime error as the one below.

 

This problem can be resolved by adding a app.manifest file to your project and modifying some part of it. Move to the end of the file and un-comment the <dependency> section of the file.

<dependency>
    <dependentAssembly>
      <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="*"
          publicKeyToken="6595b64144ccf1df"
          language="*"
        />
    </dependentAssembly>
</dependency>

Hit F5 again and this will do the trick for you, this time you will be able to view the message box as you wanted to. The API sample contains code for all the possible / available task dialog for you to use. But the usage is bit difficult as this cannot be acaieved in a single line like we do with the MessageBox class. Therefore I suggest you to build a helper class / function to get this easy for you. As I used this in one of my projects I have two functions one for showing the information and error messages respectively. You can also have a overload method for this, but as I have used different method names instead as I will be using only two dialogs throughout my project.

For Error Messages:

public static void ShowErrorMessage(string ErrorTitle, string Instruction, string ErrorMessage, string ErrorTrace)
{
            TaskDialog tdError;
            tdError = new TaskDialog();
            tdError.DetailsExpanded = false;
            tdError.Cancelable = true;
            tdError.Icon = TaskDialogStandardIcon.Error;

            tdError.Caption = ErrorTitle;
            tdError.InstructionText = Instruction;
            tdError.Text = ErrorMessage;
            tdError.DetailsExpandedLabel = "Hide details";
            tdError.DetailsCollapsedLabel = "Show details";
            tdError.DetailsExpandedText = ErrorTrace;

            tdError.Show();
}

All the properties in the above function is self-explainatory. The code at line:12 will have a expander in the dialog box which will contain more details of the exception.

Function for showing information is also the same but with few things "missing":

public static void ShowInfoMessage(string InfoTitle, string Information, string Message)
{
            TaskDialog tdInfo;
            tdInfo = new TaskDialog();
            tdInfo.DetailsExpanded = false;
            tdInfo.Cancelable = true;
            tdInfo.Icon = TaskDialogStandardIcon.Information;

            tdInfo.Caption = InfoTitle;
            tdInfo.InstructionText = Information;
            tdInfo.Text = Message;
            tdInfo.Show();
}

Sample Usage

//For Error Dialog
ShowErrorMessage("Application Error", "There was an error in creating XML file", ex.Message, ex.StackTrace);

//For Information Dialog
ShowInfoMessage("Application Name", "Image more than 32x32 pixels will be rejected", "Please check the image pixel before you use choose a package icon");

 Error Dialog Box

 Click the Show Details expander icon to view the complete error stack trace.

 Information Dialog Box  

This is just the two types of dialogs I have used for my project, but there are more supported in the API. So to get started see the sample project accompanying the API Code Pack including the one you see while running programs as Administrator while UAC is turned on, a dialog box with a progress bar and lots of more to check. The samples above would get you started.

 If you are a Visual Studio 2010 user with NuGet installed, then you can add the API reference to your project with the below command.
Install-Package Windows7APICodePack
 No Rating

Using jQuery To Get Your Tweets

27. December 2010 16:10

API Jquery 

If you are a blogger and using Twitter, then you must want to show some of your latest tweets on your blog space. I do have a custom widget for my blog which can display 3 of my latest tweets and I can customize it show more of my tweets. But the widgets cannot be used in every scenario and this is why some people find it difficult to use the widget provided by Twitter to display their tweets. What if they want to show their last tweet on the top of the page inside a DIV? A friend of mine set up his new WordPress blog and want to have a DIV on the top of the page which displays his last post and that he can customize. By customize I mean that he can set the number of tweets he wants to display, can show his profile picture and get his last tweet. The script file contains only three methods at this moment. I will add some other functions later on.

How does this work?

It is just a javascript file and there is nothing new about it. What you need to do is to have a DIV or any HTML element or ASP.NET server control with id as 'tweet-div'. For this example I am using a DIV to show my tweets. I choose DIV because I can set it position to absolute and set on the image to show my latest tweet on an image I got from Iconsinder. It is a pretty twitter imageand there are other images also which you can use, but for non-commercial purpose only. First, take a look at the jQuery script I wrote to do all the stuff:

function GetLastTweet(UserName) {
    url = 'http://api.twitter.com/1/statuses/user_timeline/' + UserName + '.json?callback=?';
    $.getJSON(url, function (tweet) {
        $("#tweet-div").html(tweet[0].text);
    });
}

function GetTweets(UserName, NoOfTweets) {
    url = 'http://api.twitter.com/1/statuses/user_timeline/' + UserName + '.json?callback=?';
    $.getJSON(url, function (tweets) {
        for (var i = 0; i < NoOfTweets; i++) {
            $("#tweet-div").append(tweets[i].text + "<br/>");
        }
    });
}

function GetProfileImage(UserName) {
    url = 'http://api.twitter.com/1/statuses/user_timeline/' + UserName + '.json?callback=?';
    $.getJSON(url, function (image) {
        $("#ProfileImage").attr('src', image[0].user.profile_image_url);
    });
}

To communicate with the Twitter API, I am using JSON. Plan to go for XML only if you are using it on the server side code. As you can see it is pretty easy to work with JSON in jQuery. The methods:

  • GetLastTweet(UserName) will get the last tweet of any user. Pass the twitter user name as a parameter.
  • GetTweets(UserName, NoOfTweets) will get the specified number of tweets for the user. the first parameter will be the twitter user name and the second parameter will be the number of tweets you want to display.
  • GetProfileImage(UserName) will get the profle image of the user.

Note: Please change the element ID in the script file according to your element id on the page.

And just in case if you are feeling lazy to write the the HTML markup:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>@prashantmx on Twitter!</title>
    <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
    <script src="Scripts/Tweet.js" type="text/javascript"></script>
    <link href="style/style.css" rel="stylesheet" type="text/css" />
</head>
<body onload="GetLastTweet('prashantmx');">
<img src="images/1293447412_bird_sign.png" alt="twitterbird" />
<div id ="tweet-div">
</div>
</body>
</html>

I am using an image of twitter bird to show my last tweet. Check it out here. And here is what my last tweet looks like:

If you want to use the below image or other images like this then go to Iconfinder. There is a good collection of twitter birds images as shown below and choose which best suites your requirement.

P.S. I will be adding more functions to the script file at the later stage.

Demo: http://demo.midnightprogrammer.net/jquery/twitter/twitter.htm

Download: Twitter.zip (159.92 kb)

Currently rated 1.4 by 5 people

Adding CAPTCHA In ASP.NET Application

26. December 2010 01:44

API ASP.NET 

Using CAPTCHA was never easy for me before I got a class from an unknown user on a community forum post. I have just re-used the class to get my work done. The class is extremely easy to use and let you incorporate the CAPTCHA into your application in just few lines of code.

You can set the height and width of the CAPTCHA image while initializing the CAPTCHA class. The CAPTCHA image generated from the class can be set to the image control directly or it can be save to the local path and then set to the image control. For this example I am saving it to the local path and then set to the image control. And the CAPTCHA image code generated by the class is automatically set to the session variable named CaptchaCode.

Time to get some hand on it

On the page get an image control to display CAPTCHA image, a textbox where user will enter the CAPTCHA text and a button when clicked, we can check and validate if the code entered is correct or not. Plug the DLL in your ASP.NET project and go to the Page_Load event. Here we will generate the image of the height and width we wish to have for out CAPTCHA image and then save the image to the CaptchaImages folder with the random image code generated. The code on the Page_Load event goes like this:

 protected void Page_Load(object sender, EventArgs e)
{
        if (!Page.IsPostBack)
        {
            CaptchaImage cImage = new CaptchaImage(CaptchaImage.generateRandomCode(), 140, 40);
            cImage.Image.Save(Server.MapPath("~\\CaptchaImages\\" + Convert.ToString(Session["CaptchaCode"]) + ".jpg"), ImageFormat.Jpeg);
            CaptachaImage.ImageUrl = "~\\CaptchaImages\\" + Convert.ToString(Session["CaptchaCode"]) + ".jpg";
            cImage.Dispose();
        }
        CaptchaCode = Convert.ToString(Session["CaptchaCode"]);
}

Before you can use the above code, declare a public variable which I have used to hold the value of the CAPTCHA code. I named it CaptchaCode. You can name it whatever you like it. We will be using this variable later to check it against the user input. Hit F5 to start and test your application. If everything is in place and you will be able to see the below output.

To check if the user enters the correct CAPTCHA code, we must have an event on button click which will validate the user input and prompt the user if CAPTCHA code is correct or incorrect. The code on the button click is:

protected void btn_Validate(object sender, EventArgs e)
{
        if (CaptchaCode == txt_ccode.Text)
        {
            ClientScript.RegisterClientScriptBlock(typeof(Page), "ValidateMsg", "<script>alert('You entered Correct CAPTCHA Code!');</script>");
        }
        else
        {
            ClientScript.RegisterClientScriptBlock(typeof(Page), "ValidateMsg", "<script>alert('You entered INCORRECT CAPTCHA Code!');</script>");
        }
}

The above code will check the CAPTCHA code entered by the user and check against the CAPTCHA code we previously saved in the session variable (CaptchaCode). If the validation is a success, user will get the message notifying him that he enters correct CAPTCHA code or the error message otherwise.

And that's it, we have successfully implement a CAPTCHA in our ASP.NET application. So, here are few things we can do with this CAPTCHA library:

  • Set image height and width.
  • Saves the image to the local path.
  • Automatically sets the generated CAPTCHA code to the application session.

I have build the sample project in ASP.NET 4.0, if you wanted to use the library in ASP.NET 3.x, then compile the project with lower version of ASP.NET and it will work perfectly. The below zip file contains both the projects.

Download: Captcha.NET.zip (377.63 kb)

Currently rated 3.8 by 19 people

Extending OpenID Implementation With ASP.NET: User Information / Roles and Membership

25. September 2010 22:21

API ASP.NET 

Last month I have blogged on how you can integrate OpenID login support in your ASP.NET aplication. Some of the reader requested me that it would be better if I could show how you can implement membership and roles with OpenID authentication. It doesn't seems easy in the first place, because you will require a bit more informaton from the user like his name and e-mail address. So, what I am trying to show you here is how you can gather information of the user who has logged in with OpenID and then you can use that information to set roles and membership for your website. I am just extending the old sample project from my previous post to show you how you can get some of the basic information of the user including their e-mail address.

I assume you have downloaded the complete solution from my previous post with OpenID login support, download here if you haven't yet. There is nothing new to be added in the application, instead we just need to change some properties of the OpenID control we have used. Click the control and press F4 to get the properties up. Set the properties to "Request" to make sure that whenever a user sign-in with OpenID the API also makes a request to the service provider to get the information of the user signing in. I have request some of the basic information of the user by making them "Request". It all depends on the author of the code what information he wants to see/require when the user gets logged in.

Now as you have set the properties, it's time to make a request to the provider and get the infromation. You need to do something special to get the details, sign-in as normally you would have done, but notice while re-directing the page URL will be something like this (only for a while):

.............&openid.sreg.required=&openid.sreg.optional=nickname%2Cfullname%2Cdob%2Cgender%2Ccountry

Notice the last few options in the query string is requesting the parameters we have "Requested". But you should also know that the values will be null if the user has not filled up his Persona (Personal Details). If you try to fetch the details of the user, you will get a null value. So, it's pretty necessary that the user who has logged in using the OpenID should have his personal details filled up at the provider's end. This is how my personal details look like at OpenID (website) login.

 

Personas are actually the information of the user which will be delivered to the site or application where the user has logged in using OpenID. You can add/modify/delete a personas. Once you have the persona of the logged in user you can:

  • Set the OpenID control to request the details of the users instead of providing the user to fill out a long registration form.
  • Save the values to the database for future use.
  • Use the information for setting Roles and Membership for your application.

I've already demonstrate in the above steps on how to set the OpenID user control to request the user details or personas.

What else I need to do

In Visual Studio, select the OpenID control and press F4 to get the properties. Under method section double-click the LoggedIn method (The method name describes itself).

 

In this method, read the response and set it to the session variable. Give a name to the sesison variable.

protected void OpenIdLogin1_LoggedIn(object sender, DotNetOpenAuth.OpenId.RelyingParty.OpenIdEventArgs e)
{
        Session["OpenID"] = e.Response;
}

When the user is successfully authenticated by the provider, user is re-directed to the default home page. Therefore, we need to handle the response on the home page. Add these two namespaces on the page code-behind.

using DotNetOpenAuth.OpenId.RelyingParty;
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;

I am using the page load method so as to get the details and display it front of the user, you can also set the same details to fill up a registration form. To read the response from the session variable use the IAuthenticationResponse to read store the session value and then read it with GetResponse<ClaimResponse> method. Below is the complete code for your default.aspx page or the page you want the user to be re-directed. I have store the values in the public variables as I want to show the user details on the default page.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DotNetOpenAuth.OpenId.RelyingParty;
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
namespace DOTNETOAUTH
{
    public partial class _Default : System.Web.UI.Page    
    {
        IAuthenticationResponse OResponse;
        public string UserName = string.Empty;
        public string Gender = "No Gender Specified";
        public string Country = string.Empty;
        public string Nick = string.Empty;
        public string Bday = string.Empty;

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                OResponse = (IAuthenticationResponse)Session["OpenID"];
                var details = OResponse.GetExtension<ClaimsResponse>();
                UserName = details.FullName;
                //email = details.Email;
                Gender = details.Gender.ToString();
                Country = details.Country;
                Nick = details.Nickname;
                Bday = details.BirthDate.ToString();
            }
            catch { }
        }
    }
}

If any of the above values are not present in the user persona , it will result in an error, so make sure you have handle the exceptions properly. This is it, once you have the details you can use to store the details in the database, set roles and membership to the user logins. I have skip the part to set user roles and membership, once we have the user information we can use that information to set roles or just save the information in the database.

 

Download: DOTNETOAUTH - UserData.zip (552.20 kb)

Currently rated 5.0 by 1 person