ASP.NET Core 5.0 – Bearer Authentication


ASP.NET Core supports several authentication methods which are Basic, Bearer, Digest, OAuth and others. This article will show you how to build a Bearer authentication to your Web API using IAsyncAuthorizationFilter and IPolicyEvaluator interfaces.

Prerequisites

Bearer Authentication

Bearer authentication is an HTTP authentication scheme also called token authentication that involves security tokens called bearer tokens. Bearer Token is set in the Authorization header of HTTP Request.

Authorization: Bearer API Token

Why not use built in [Authorize]?

ASP.NET core official documentation does not talk about how to implement a custom Bearer Authentication. I have seen ton of samples explaining either [Authorize] or IDENTITY providers or OAUTH type authentications. However, this approach does not work on WEB API 2.0 apps which is written in .NET Full Framework.
NOTE: I’ve used IAuthenticationFilter interface to implement authentication in WEB API 2.0.

Creating ASP.NET 5.0 WEB API Project

Fire up your favorite IDE and create a brand new ASP.NET CORE Web API project template. The default template is pretty good to get started to implement Bearer token authentication method.

Project edit view

After successfully creating API project, click on edit project file and you should be able to see TargetFramework is netcoreapp5.0 and LangVersion is C# 9.0 which is in preview mode.

<PropertyGroup>
  <TargetFramework>netcoreapp5.0</TargetFramework>
  <LangVersion>Preview</LangVersion>
</PropertyGroup>

IAsyncAuthorizationFilter & IPolicyEvaluator

IAsyncAuthorizationFilter Interface – A filter that asynchronously confirms request authorization. Read more

IPolicyEvaluator Interface – Base class for authorization handlers that need to be called for a specific requirement type. Read more

Let’s implement IPolicyEvaluator interface first. The interface has two methods called AuthenticateAsync and AuthorizeAsync,

1) AuthenticateAsync method checks for Authorization header and read Bearer token from the request header.

  • Check Authorization header present in the request.
  • Read Bearer token and compare against the stored token.
  • Once token match successfully, set some Claims thus, you want to identity the request later.

2) AuthorizeAsync method does check whether the request has been already evaluated by IPolicyEvaluator and looks Succeeded or Challenged status and return Policy Authorization Result.

Below, you can find complete code for PolicyEvaluator class.


public sealed class BearerPolicyEvaluator : IPolicyEvaluator
{
private const string Scheme = "Bearer";
public Task<AuthenticateResult> AuthenticateAsync(AuthorizationPolicy _, HttpContext context)
{
if (!context.Request.Headers.ContainsKey("Authorization"))
return Task.FromResult(AuthenticateResult.Fail("No Authorization header found!"));
string authHeader = context.Request.Headers["Authorization"];
string bearerToken = authHeader?.Replace("Bearer ", string.Empty);
if (!string.Equals(bearerToken, "authToken", StringComparison.Ordinal))
{
return Task.FromResult(AuthenticateResult.Fail("Invalid token"));
}
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, "1000"),
new Claim(ClaimTypes.Name, "Deepu Madhusoodanan")
};
var identity = new ClaimsIdentity(claims, Scheme);
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, Scheme);
var authenticateResult = AuthenticateResult.Success(ticket);
return Task.FromResult(authenticateResult);
}
public Task<PolicyAuthorizationResult> AuthorizeAsync(AuthorizationPolicy _,
AuthenticateResult authenticationResult, HttpContext context,
object resource)
{
var authorizeResult = authenticationResult.Succeeded
? PolicyAuthorizationResult.Success()
: PolicyAuthorizationResult.Challenge();
return Task.FromResult(authorizeResult);
}
}

Next, implement IAsyncAuthorizationFilter interface.

OnAuthorizationAsync method calls above PolicyEvaluator API to get authentication and authorization result.


public sealed class BearerAuthorizeFilter : IAsyncAuthorizationFilter
{
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
if (context?.HttpContext?.Request?.Headers == null) throw new ArgumentNullException(nameof(context));
if (!context.HttpContext.Request.Headers.ContainsKey("Authorization"))
context.Result = CreateUnauthorized();
var policyEvaluator = context.HttpContext.RequestServices.GetRequiredService<IPolicyEvaluator>();
var authenticateResult = await policyEvaluator.AuthenticateAsync(default, context.HttpContext);
var authorizeResult = await policyEvaluator.AuthorizeAsync(default, authenticateResult, context.HttpContext, context);
if (authorizeResult.Challenged)
{
context.Result = CreateUnauthorized();
return;
}
context.HttpContext.User = authenticateResult.Principal;
static IActionResult CreateUnauthorized() => new UnauthorizedObjectResult(new ErrorMessage("Unauthorized", 401));
}
}

Configure services

Final step would be registering authentication interface in Startup.cs class

public void ConfigureServices(IServiceCollection services)
{
   services.AddControllers(o => o.Filters.Add(new BearerAuthorizeFilter()));
}

NOTE: Using this approach, you wouldn’t need to use any middleware like use.Authentication() or [Authorize] attribute on API controllers.

Source repository

Github – https://github.com/deepumi/aspnet-5-bearer-authentication/

Summary

In this post I described how to implement custom Bearer token in ASP.NET Core projects with out using built in Authorize mechanism.

A big thank you to Microsoft MVP Steve Gordon who recommended to use JWT tokens and built in [Authorize] mechanism for APS.NET core projects!

Hope you enjoy reading the article and please feel free to give this a try and let me know your thoughts and suggestions.

Asp.Net MVC5 Authorization


The sample application will walk you through how to create Claim based Authorization Middleware with Owin and Katana libraries using .Net 4.5.2 framework.

Github source – https://github.com/deepumi/AspNetMVC5Authorization

Step1

  • File -> New Project -> Asp.Net Web Application -> Asp.Net 4.5.2 Templates
  • Choose empty MVC project template

Step2

  • Install following nuget packages
    • Microsoft.AspNet.Identity.Core
    • Microsoft.AspNet.Identity.Owin
    • Microsoft.Owin
    • Microsoft.Owin.Host.SystemWeb
    • Microsoft.Owin.Security
    • Microsoft.Owin.Security.Cookies
    • Microsoft.Owin.Security.OAuth
    • Owin

Step3

  • Create a Owin Startup class and decorate with assembly attribute OwinStartup.
    using Microsoft.AspNet.Identity;
    using Microsoft.Owin;
    using Microsoft.Owin.Security.Cookies;
    using Owin;
    
    [assembly: OwinStartup(typeof(AspNetMVC5Authorization.Startup))]
    
    namespace AspNetMVC5Authorization
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                ConfigureAuthentication(app);
            }
    
            private void ConfigureAuthentication(IAppBuilder app)
            {
                app.UseCookieAuthentication(new CookieAuthenticationOptions
                {
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                    LoginPath = new PathString("/Auth/Login"), //sign page
                    CookieName = "AuthCookie",
                    CookieHttpOnly = true,
                    ExpireTimeSpan = System.TimeSpan.FromHours(1),
                    LogoutPath = new PathString("/Auth/Signout"), //sign out page
                    ReturnUrlParameter = "ReturnUrl",
                    CookieSecure = CookieSecureOption.SameAsRequest, //Use CookieSecureOption.Always if you intend to serve cookie in SSL/TLS (Https)
                    SlidingExpiration = true,
                });
            }
        }
    }
    

    Step4

  • Create list of claims for the specific user with roles and other information
    internal class AuthenticationHelper
    {
       internal static List<Claim> CreateClaim(UserSessionModel userSessionModel,params string[] roles) //Single or multiple roles
       {
          var claims = new List<Claim>
          {
              new Claim(ClaimTypes.NameIdentifier, userSessionModel.UserId.ToString()),  //User ideitifer
              new Claim(ClaimTypes.Name, userSessionModel.DisplayName),  //Username
              new Claim(Constants.UserSession, userSessionModel.ToJson()) //Custom entity with user info
          };
    
          foreach (var role in roles) //custom roles goes here
          {
              claims.Add(new Claim(ClaimTypes.Role, role, ClaimValueTypes.String, Constants.Issuer));
          }
          return claims;
       }
    }

Step5

  • Create Authentication controller and process of the rest of the Authentication
    using Microsoft.AspNet.Identity;
    using Microsoft.Owin.Security;
    using System.Security.Claims;

    public class AuthController : BaseController
    {
      private IAuthenticationManager AuthenticationManager
      {
          get { return HttpContext.GetOwinContext().Authentication; }
      }

      [HttpPost,ValidateAntiForgeryToken]
      public ActionResult SignIn(SignInViewModel vm,string returnUrl = default(string))
      {
          try
          {
              if (!ModelState.IsValid)
              {
                  vm.ErrorMessage = "Email address and Password are required fields";
                  return View(vm);
              }

              var userSession = Authenticate(vm); // Validate authentication from db or other source.

              if (userSession != null) //create claim with user info.
              {
                  var identity = new ClaimsIdentity(AuthenticationHelper.CreateClaim(userSession, 
                                                      Helpers.Constants.UserRoles.Admin, 
                                                      Helpers.Constants.UserRoles.User),
                                                      DefaultAuthenticationTypes.ApplicationCookie
                                                      );
                  AuthenticationManager.SignIn(new AuthenticationProperties()
                  {
                      AllowRefresh = true,
                      IsPersistent = true,
                      ExpiresUtc = DateTime.UtcNow.AddHours(1)
                  }, identity);

                  if (!string.IsNullOrWhiteSpace(returnUrl) && Url.IsLocalUrl(returnUrl)) return Redirect(returnUrl);

                  return RedirectToAction("index", "home");
              }
          }
          catch (AuthenticationException e)
          {
              vm.ErrorMessage = e.Message;
          }
          return View(vm);
      }

      private UserSessionModel Authenticate(SignInViewModel vm)
      {
          if (vm.Email != "email@email.com" || vm.Password != "password") throw new AuthenticationException("Login failed. Incorrect email address or password");

          return new UserSessionModel
          {
              UserId = Guid.NewGuid(),
              DisplayName = "Deepu Madhusoodanan"
          };
      }

      public ActionResult Signout()
      {
          AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie,DefaultAuthenticationTypes.ExternalCookie);
          return Redirect("~/");
      }
    }

Step6

  • Get the custom ojbect obect from Claim
public class BaseController : Controller
{
    protected internal UserSessionModel UserSessionModel { get; private set; }

    protected override void Initialize(RequestContext requestContext)
    {
        base.Initialize(requestContext);
        var user = User as ClaimsPrincipal;
        if (user != null)
        {
            var claims = user.Claims.ToList();
            var sessionClaim = claims.FirstOrDefault(o => o.Type == Constants.UserSession);
            if (sessionClaim != null)
            {
                UserSessionModel = sessionClaim.Value.ToObject<UserSessionModel>();
            }
        }
    }
}

Step7

[Authorize(ClaimType = ClaimTypes.Role, ClaimValue = "Contributor,User")]
public ActionResult Secure()
{
    var userSessionModel = UserSessionModel; //Get custom object from Security claim.
    return View();
}

Finally Custom Authorize attribute code

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    public string ClaimType { get; set; }
    public string ClaimValue { get; set; }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
        var principal = filterContext.RequestContext.HttpContext.User as ClaimsPrincipal;

        if (!principal.Identity.IsAuthenticated)
        {
            filterContext.Result = new RedirectResult("~/auth/signin");
            return;
        }

        var claimValue = ClaimValue.Split(','); //Split custom roles and validate custom cliams, issuer and vlaue.
        if (!(principal.HasClaim(x => x.Type == ClaimType && claimValue.Any(v => v == x.Value) && x.Issuer == Constants.Issuer)))
        {
            filterContext.Result = new RedirectResult("~/Unauthorize.html");
        }
    }
}

MadMimi.Net Integration


I have been playing around with Transaction Email Services for a while and came across the tool named MadMimi, A email marketing tool lets you to send email from a different server so that you can track whether the email delivered or bounce.

MadMimi already have a C# version API and its quite old. The reason I wrote my own version is to prevent less code change to my current project so that if I want to switch to a different provider in the feature it would be easy.

A typical email sending code

using (var message = new MailMessage())
{
    message.To.Add("receiver");
    message.From = new MailAddress("from");
    message.Subject = "Subject";
    message.Body = "This is test";
    using (var client = new SmtpClient())
    {
      client.Send(message);
    }
}

Using Library

  var mailer = new Mailer("username", "apikey");
  using (var message = new MailMessage())
  {
      message.From = new MailAddress("from email", "display name");
      message.To.Add("sender email");
      message.Subject = "Test";
      message.Body = "Email body";
      await mailer.SendAsync("Promotion Name", message);
  }
  var status = mailer.TrackStatus; //URL to track the email
  var mailTransactionId = mailer.TransactionId; //Transaction Id.

When you compare the above code snippets you should see additional two liner code which integrate the library (Mailer class) and that is the only change you should make your existing project and apps if you would like to integrate this.

Pros
SPF (
Sender Policy Framework) – MadMimi does not care if you have set up a SPF record in DNS. While most of the competitors, this is a mandatory requirement if you want to use your own “FROM” email address other than your DOMAIN.

Cons
1) Delivery speed – Some time the email take 5-6 minutes to deliver.
2) No SMTP relay support.
3) Attachment does not support via API.

Feel free to play around and fork it if you would like to make any change to this. The GitHub link is provided below for the sample project and library.

Repository – https://github.com/deepumi/MadMimi.Net

jQuery Autocomplete with multiple fileds in Asp.Net C#


This  article explains jQuery autocomplete with  multiple fields using Asp.Net C#.

Scenario :  Listing business titles for a specific city/state location.

Initially I used AJAX CONTROL TOOLKIT (ACT) but I ran in to many issues and finally decided to use jQuery approach which really saved my time.

You can Download the complete source code from here

Add jQuery assets on your page.

<link href="styles/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="scripts/jquery.min.js"></script>
<script type="text/javascript" src="scripts/jquery-ui.min.js"></script>

jQuery Code for consuming web service.

<script type="text/javascript">
$(function () {
var search = $("#<%=txtSearch.ClientID%>");
var location = $("#<%=txtLocation.ClientID %>");
search.autocomplete({
    source: function (request, response) {
        $.ajax({
            url: '<%=ResolveUrl("~/") %>AutoCompleteService.asmx/GetKeyWords',
            data: "{ 'keyword': '" + search.val() + "', 'location' : '" + location.val() + "'}",
            dataType: "json",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataFilter: function (data) { return data; },
            success: function (data) {
                if (data.d != null) {
                    response($.map(data.d, function (item) {
                        return {
                            value: item
                        }
                    }))
                }
            },
            error: function (XMLHttpRequest, textStatus, error) {
                //alert(textStatus);
            }
        });
    },
    minLength: 1
});

location.autocomplete({
    source: function (request, response) {
        $.ajax({
            url: '<%=ResolveUrl("~/") %>AutoCompleteService.asmx/GetLocations',
            data: "{ 'location': '" + location.val() + "'}",
            dataType: "json",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataFilter: function (data) { return data; },
            success: function (data) {
                if (data.d != null) {
                    response($.map(data.d, function (item) {
                        return {
                            value: item
                        }
                    }))
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                // alert(textStatus);
            }
        });
    },
    minLength: 1
});

});
</script>

Code-behind for ASMX class (don’t forget to uncomment  System.Web.Script.Services.ScriptService)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Services;
using System.Collections;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class AutoCompleteService : System.Web.Services.WebService {

public AutoCompleteService () {
}

IDictionary<string, string[]> LoadItems()
{
    IDictionary<string, string[]> items = new Dictionary<string, string[]>();

    items.Add("Newyork", new string[]
                                        {
                                            "Applebee's", "Apiary", "Brenda's French Soul Food","TGI Friday's","Cafe Venue"
                                        });

    items.Add("Los Angeles", new string[]
                                        {
                                            "Los 1", "Los 2", "Los 3","TGI Friday's","Cafe Venue"
                                        });

    items.Add("Las Vegas", new string[]
                                        {
                                            "Los 1", "Los 2", "Los 3","TGI Friday's","Cafe Venue"
                                        });

    return items;
}

[WebMethod]
public string[] GetKeyWords(string keyword, string location)
{
    var items = LoadItems();
    if (items != null && items.Count > 0)
    {
        //Get all items for a specific location
        var result = (from item in items
                        where item.Key.Equals(location, StringComparison.OrdinalIgnoreCase)
                        select item.Value)
                    .FirstOrDefault();

        //check whether the items start with the keyword
        return result.Where
                            (
                                o => o.StartsWith(keyword, StringComparison.OrdinalIgnoreCase)
                            ).ToArray<string>();
    }
    return null;
}

[WebMethod]
public string[] GetLocations(string location)
{
    var items = LoadItems();
    if (items != null && items.Count > 0)
    {
        //check whether the items start with the location
        return (from item in items
                        where item.Key.StartsWith(location, StringComparison.OrdinalIgnoreCase)
                        select item.Key).ToArray<string>();

    }
    return null;
}
}

You can Download the complete source code from here

Hope this help and If you have any comments, please feel free to write your feedback.

Thanks
Deepu

 

jQuery reorder list & saving in to database from Asp.Net C#


I have faced lot of challenges while using Ajax Toolkit control for re-ordering a list and saving to database.. After doing some R&D I’ve  found some nice samples which uses jQuery which is very light weight.The good part of jQuery is we can control the rendering marking.. with CSS and from the backed we don’t need any ViewState or any kind of mechanism..

You can Download the complete source code from here


To begin with reorder stuff add jQuery scripts to your aspx page.

<link rel="stylesheet" type="text/css" href="list-reorder.css" />
<script type="text/javascript" src="jquery-1.2.6.pack.js"></script>
<script type="text/javascript" src="jquery.disable.text.select.pack.js">
</script>
<script type="text/javascript" src="json2.js"></script>
<script type="text/javascript" src="jquery.listreorder.js"></script>

The sample code uses Unordered list and list view control.. Add a List view control in to asp.net page..inside UL markup use class name as “lists“.

Next is adding a attribute to <li> tag which help to identify the exact element you are ordering,  so I am adding attribute name as id and setting value as ItemId which fetching from DB column identity value.

<li id='<%# DataBinder.Eval(Container.DataItem, “ItemId“)%>’>

<ul class="lists">
<asp:ListView ID="lvNews" runat="server">
<LayoutTemplate>
<asp:Panel ID="itemPlaceHolder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<li id='<%# DataBinder.Eval(Container.DataItem, "ItemId")%>'>
<%# DataBinder.Eval(Container.DataItem, "Title")%></li>
</ItemTemplate>
<ItemSeparatorTemplate>
</ItemSeparatorTemplate>
</asp:ListView>
</ul>

Add following code in codebehind class for binding the data to list view control

using System;
using System.Collections.Generic;

public class News
{

public int ItemId { get; set; }
public string Title { get; set; }

internal static IList<News> GetNews()  //replace this method call with your db logic
{
return new List<News>
{
new News{ItemId=1,Title="News Title 1"},
new News{ItemId=2,Title="News Title 2"},
};
}

internal static void SaveReorderList(List<string> items) //replace this method call with your db logic
{
int order = 1;
string sql = string.Empty;
foreach (string item in items)
{
//replace with your sql statement.
sql = "update news set display_order = " + order + " where news_id = '" + item + "'";
order += 1;
sql = string.Empty;
}
}
}

public partial class jQueryReorder_Net_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindNews();
}
}

private void BindNews()
{
var news = News.GetNews();
lvNews.DataSource = news;
lvNews.DataBind();
}

[System.Web.Services.WebMethod]
public static string SaveReOrder(List<String> items)
{
try
{
News.SaveReorderList(items);
return string.Empty;
}
catch (Exception exp)
{
return exp.ToString();
}
}
}

Finally I am adding jQuery re-order script in to the page.

<script type="text/javascript">
$(document).ready(function() {
var options = {
itemHoverClass: 'itemHover',
dragTargetClass: 'dragTarget',
dropTargetClass: 'dropTarget',
useDefaultDragHandle: true
};

var lists = $('.lists').ListReorder(options);
var items = [];
lists.bind('listorderchanged', function(evt, jqList, listOrder) {
for (var i = 0; i < listOrder.length; i++) {
items[i] = $("ul li:eq(" + i + ")").attr('id');
}
});

$('#btnSave').click(function() {
if (items.length > 0) {
var jsonText = JSON.stringify({ items: items });
$.ajax({
type: "POST",
url: '<%=ResolveUrl("~/jQueryReorder.Net/")%>Default.aspx/SaveReOrder',
data: jsonText,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function() { $("#result").html("Reorder items saved successfully"); },
failure: function(msg) { alert(msg); }
});
}
else {
alert("Sorry you have not reorder any items");
}
});
});
</script>

When ever the list order changed the event get fired and loop through the entire list items and sets the attribute id value in to a array which will be converted later to JSON format and pass it to a web method for saving into database. Don’t forget to add method attribute as System.Web.Services.WebMethod in the reorder save method.

You can Download the complete source code from here

Hope this helps and If you have any comments, please feel free to write your feedback.

Thanks
Deepu

Twitter Tweets in Asp.Net C#


I’ve been working on the twitter feed in one of my recent project where tweets getting updated on a regular interval time (say for every 30 minutes or 1 hr). I am creating this as a ASCX control so that I can reuse for multiple projects.

You can Download the complete source code from here

I am dropping a ListView control in the ASCX page which render the Twitter Profile name along with  Title, Description and Published date for the latest tweets.

Couple of properties need to configure to use this control

TwitterProfileName – Your twitter profile name or screen name

TweetsCount – No of tweets you want to return (default is 10).

<asp:ListView ID="lvTweets" runat="server">
<LayoutTemplate>
<table border="0" cellpadding="2" cellspacing="0">
<tr>
<td height="30" runat="server">
<a href="http://twitter.com/<%=<span class=&quot;hiddenSpellError&quot; pre=&quot;&quot;>TwitterProfileName</span>%>" target="_new"></a>
<%= TwitterProfileName%>
</td>
</tr>
<tr>
<td>
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</td>
</tr>
<tr>
77B5D2;">
</td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
<a target="_new" href='<%# DataBinder.Eval(Container.DataItem, "Link")%>'>
<%# DataBinder.Eval(Container.DataItem, "Title")%></a>
<br />
<div>
<%# DataBinder.Eval(Container.DataItem, "PublishedDate", "{0:h:mm  tt MMM d}")%>
</td>
</tr>
</ItemTemplate>
<EmptyDataTemplate>
<div>
<h3>
No tweets available.</h3>
</div>
</EmptyDataTemplate>
<ItemSeparatorTemplate>
<tr>
1px solid lightgrey;">
</td>
</tr>
</ItemSeparatorTemplate>
</asp:ListView>
using System;
using System.Linq;
using System.Xml.Linq;
using System.Collections;
using System.Collections.Generic;

public partial class TweetsControl : System.Web.UI.UserControl
{
private static DateTime? lastUpdated = null; //holds last updated time

private static XDocument xDoc = null; //static variable to store the result xml.

//Updates latest Tweets for every 10 minutes in page refresh.
private static Double Interval = 10;

//Determine its time to get the new tweets
private static Boolean IsTimeForUpdate
{
get
{
if (lastUpdated.HasValue && DateTime.Now > lastUpdated.Value.AddMinutes(Interval))
{
return true;
}
return false;
}
}

//Hold no of tweets default set it as 10.
public Int32? TweetsCount { get; set; }

//Twitter profile name or screen name.
public String TwitterProfileName { get; set; }

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GetTweets();
}
}

private void GetTweets()
{
var xml = LoadXML();
IEnumerable query = null;
if (xml != null)
{
query = from e in xml.Descendants("item")
select new
{
Title = e.Element("title").Value,
Link = e.Element("link").Value,
PublishedDate = Convert.ToDateTime((e.Descendants("pubDate").First().Value)),
};
}
lvTweets.DataSource = query;
lvTweets.DataBind();
}

private XDocument LoadXML()
{
if (xDoc != null && !IsTimeForUpdate)
{
return xDoc;
}
else
{
try
{
TweetsCount = TweetsCount.HasValue ? TweetsCount : 10;
var url = string.Format("http://api.twitter.com/statuses/user_timeline.rss?screen_name={0}&count={1}", TwitterProfileName, TweetsCount);
xDoc = XDocument.Load(url);
lastUpdated = DateTime.Now;
return xDoc;
}
catch
{
return null;
}
}
}

}

Refer more api information on Twitter API

You can Download the complete source code from here

Hope this helps

Thanks
Deepu

using System; using System.Linq; using System.Xml.Linq; using System.Collections; using System.Collections.Generic; public partial class TweetsControl : System.Web.UI.UserControl { private static DateTime? lastUpdated = null; private static XDocument xDoc = null; private static Double Interval = 10; private static Boolean IsTimeForUpdate { get { if (lastUpdated.HasValue && DateTime.Now > lastUpdated.Value.AddMinutes(Interval)) { return true; } return false; } } public Int32? TweetsCount { get; set; } public String TwitterProfileName { get; set; } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { GetTweets(); } } private void GetTweets() { var xml = LoadXML(); IEnumerable query = null; if (xml != null) { query = from e in xml.Descendants(“item”) select new { Title = e.Element(“title”).Value, Link = e.Element(“link”).Value, PublishedDate = Convert.ToDateTime((e.Descendants(“pubDate”).First().Value)), }; } lvTweets.DataSource = query; lvTweets.DataBind(); } private XDocument LoadXML() { if (xDoc != null && !IsTimeForUpdate) { return xDoc; } else { try { TweetsCount = TweetsCount.HasValue ? TweetsCount : 10; var url = string.Format(“http://api.twitter.com/1/statuses/user_timeline.rss?screen_name={0}&count={1}”, TwitterProfileName, TweetsCount); xDoc = XDocument.Load(url); lastUpdated = DateTime.Now; return xDoc; } catch { return null; } } } }

Google Spell Checker Api Asp.Net C#


In this article you will learn how to use the Google Spell Checker API in Asp.Net C# apps

Download the complete source code from here

The API is very simple,  spell checking is done through a XML http post to the following url

https://www.google.com/tbproxy/spell?lang=en:

Request XML structure

<?xml version=”1.0encoding=”utf-8?>
<spellrequest textalreadyclipped=”0ignoredups=”0ignoredigits=”1ignoreallcaps=”1>
<text>Hotal</text>
</spellrequest
>

The folloing are the Response XML from Google API

<?xml version=”1.0encoding=”UTF-8?>
<spellresult error=”0clipped=”0charschecked=”12>
<c o=”0l=”5s=”0″>
Hotel Hotly Total Ital Hots</c>
<
/spellresult
>

Tag Description
o The offset from the start of the text of the word
l Length of misspelled word
s Confidence of the suggestion
text Tab delimited list of suggestions

See the complete code here

using System;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

public static class SpellChecker
{
 public static String DidYouMean(string word)
 {
 string retValue = string.Empty;
 try
 {
 string uri = "https://www.google.com/tbproxy/spell?lang=en:";
 using (WebClient webclient = new WebClient())
 {
 string postData = string.Format("<?xml version=\"1.0\" encoding=\"utf-8\" ?><spellrequest textalreadyclipped=\"0\" ignoredups=\"0\" ignoredigits=\"1\" "
 + "ignoreallcaps=\"1\"><text>{0}</text></spellrequest>",word);

 webclient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
 byte[] bytes = Encoding.ASCII.GetBytes(postData);
 byte[] response = webclient.UploadData(uri, "POST", bytes);
 string data = Encoding.ASCII.GetString(response);
 if (data != string.Empty)
 {
    retValue = Regex.Replace(data, @"<(.|\n)*?>", string.Empty).Split('\t')[0];
 }
 }
 }
 catch (Exception exp)
 {

 }
 return retValue;
 }
 }

protected void Page_Load(object sender, EventArgs e)
{
    string word = SpellChecker.DidYouMean("Hotal");
    if(word != string.Empty)
    {
         labMessage.Text = "<font style='font-size:12px;color:red;'>Did you mean </font><b>" + retValue + "</b>";
    }
}

You can Download the complete source code from here

Hope this help and If you have any comments, please feel free to write your feedback.

Thanks
Deepu

Asp.Net 4.0 URL Routing


It’s been  really easy  in Asp.Net 4.0 for building SEO friendly URL applications with VS 2010. In one my previous article I have explained how we can achieve the same in Asp.Net 3.5  (check it out).  In Asp.Net 3.5 we need to implement the IRouteHandler interface in custom route handler class and bla bla….but now in Asp.Net 4.0 we do not need all extra code.  I am following the same example in my previous article here.  In the Global.asax file I am registering the routes some thing like below

You can download the entire article from here

Global.asax file Configuration

Add Import directive to Import System.Web.Routing name space

<%@ Import Namespace=”System.Web.Routing” %>

void RegisterRoutes(RouteCollection routes)
 {
 routes.MapPageRoute(
 "member-list",
 "member/{name}",
 "~/member-list.aspx"
 );
 }

 void Application_Start(object sender, EventArgs e)
 {
RegisterRoutes(RouteTable.Routes);
}

The first parameter member/{name} which denote the url structure, here the url which starts /member/{name} (ex : /member/deepu/) will point physically to the following path ~/member/member-list.aspx

Create a aspx page called default.aspx

This page will have a list of Members in Tabular format. I am going to use asp.net List view control to achieve this.

<asp:ListView ID=”lvUserList” runat=”server”>
<LayoutTemplate>
<table width=”50%” style=”background-color: lightgrey;” cellpadding=”2″ cellspacing=”1″
border=”0″>
<tr style=”background-color: white”>
<td width=”100″ align=”center”>
Member ID
</td>
<td align=”center”>
Name
</td>
<td width=”75″ align=”center”>
Blog
</td>
<td width=”50″>
</td>
</tr>
<asp:PlaceHolder ID=”itemPlaceholder” runat=”server” />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr style=”background-color: white”>
<td align=”center”>
<asp:Label ID=”lab” Text='<%# DataBinder.Eval(Container.DataItem, “MemberID”)%>’
runat=”server” />
</td>
<td>
<asp:Label ID=”Label1″ Text='<%# DataBinder.Eval(Container.DataItem, “Name”)%>’ runat=”server” />
</td>
<td align=”center”>
<a target=”_blank” href='<%# DataBinder.Eval(Container.DataItem, “BlogURL”)%>’>Blog</a>
</td>
<td align=”center”>
<a href=”<%= ResolveUrl(“~/member/”)%><%# DataBinder.Eval(Container.DataItem, “Name”)%>”>
Detail</a>
</td>
</tr>
</ItemTemplate>
<ItemSeparatorTemplate>
<br />
</ItemSeparatorTemplate>
</asp:ListView>

Default.aspx.cs code behind

public partial class Memeber
{
 public int MemberID { get; set; }
 public string Name { get; set; }
 public string BlogURL { get; set; }
}


public partial class _Default : System.Web.UI.Page
{
 protected void Page_Load(object sender, EventArgs e)
 {
 if (!IsPostBack)
 {
 BindUsers();
 }
 }

 void BindUsers()
 {
 var items = new List<Memeber>()
 {
 new Memeber {MemberID = 1,Name = "Deepu", BlogURL = "https://deepumi.wordpress.com"},
 new Memeber {MemberID = 2,Name = "Scott", BlogURL = "http://weblogs.asp.net/scottgu/"},
 new Memeber {MemberID = 3,Name = "Joe", BlogURL = "http://misfitgeek.com"},
 };


 lvUserList.DataSource = items.ToList();
 lvUserList.DataBind();
 }
}

We have completed the listing page. The next page will be the detail page which will be rendering the member name for the URL routing.

Member-List.aspx Page

<asp:Content ID=”BodyContent” runat=”server” ContentPlaceHolderID=”MainContent”>
Member Name : <asp:Label ID=”labMemberName” runat=”server” />
</asp:Content>

Member-List.aspx code behind Page

var name = Page.RouteData.Values["name"];
 if (name != null)
 {
 Page.Title = name.ToString();
 labMemberName.Text = name.ToString();
 }

You can download the entire article from here

Hope this help and If you have any comments, please feel free to write your feedback.

Thanks
Deepu

Google Map 3 with Multiple locations in Asp.Net C#


Google Map Version 3 API is especially designed to be faster and more applicable to mobile devices, as well as traditional desktop browser applications ….read more from google map api document.

Click here to download the article

If you find the Google Map 3 code library useful, please consider donating

(No more API registration key needed for Version 3.0)

In this article I am going to explain how we can show multiple locations binding from code behind dynamically (database or any data source).  Couple of moths ago in Asp.Net forum I have posted an article using Google Map Version 2.0
(http://forums.asp.net/p/1507845/3584193.aspx#3584193). Version two was kind of messy Java Script code but now in Version 3.0 Google made it very simple.

Create a ASPX page and copy paste the following markup code..

<html>
<head runat=”server”>
<meta name=”viewport” content=”initial-scale=1.0, user-scalable=no” />
<meta http-equiv=”content-type” content=”text/html; charset=UTF-8″ />
<title>Google Map 3.0</title>
<style type=”text/css”>
.formatText{color:Green;font-size:11px;font-family:Arial;font-weight:bold;}
</style>
<script type=”text/javascript” src=”http://maps.google.com/maps/api/js?sensor=false“></script>
<script type=”text/javascript”>
var map;
function initialize() {
var myLatlng = new google.maps.LatLng(40.764015, -73.982797);
var myOptions = {
zoom: 8,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}

map = new google.maps.Map(document.getElementById(“map_canvas”), myOptions);

for (var i = 0; i < locationList.length; i++) {
var args = locationList[i].split(“,”);
var location = new google.maps.LatLng(args[0], args[1])
var marker = new google.maps.Marker({
position: location,
map: map
});
var j = i + 1;
marker.setTitle(message[i].replace(/(<([^>]+)>)/ig,””));
attachSecretMessage(marker, i);
}
}

function attachSecretMessage(marker, number) {
var infowindow = new google.maps.InfoWindow(
{ content: message[number],
size: new google.maps.Size(50, 50)
});
google.maps.event.addListener(marker, ‘click’, function() {
infowindow.open(map, marker);
});
}
</script>

</head>
<body style=”margin: 0px; padding: 0px;” onload=”initialize()”>
<form runat=”server”>
<div style=”padding-top: 10%;padding-left:20%”>
<div id=”map_canvas” style=”width: 50%; height: 50%”>
</div>
</div>
</form>
</body>
</html>

I have highlighted some of the lines from the above code

1)  The class formatText, simple css class for formating the info window text. You can replace your own css style here
.formatText{color:Green;font-size:11px;font-family:Arial;font-weight:bold;}

2) In the Java Script include statement I have mention sensor=false (because the sample app is targeting on web  page if you are using from Mobile application you should  set sensor=false. Read more about mobile app)

3) In the for loop I’ m using locationList.Length. Here locationList is Java Script array object which is getting generated from an Aspx code behind page and basically the locationList object has array of  Geo code information like Latitude and Longitude. In one my previous article I have explained how we can get the Geo-code location from an address using Yahoo API.

HTML out put

var locationList = new Array( ‘40.756012, -73.972614’ , ‘40.456012, -73.796087’ , ‘40.456012, -73.456807’ );

4) Splitting lattitude and longitude from the array object and assign it to Google function like below.

var args = locationList[i].split(“,”);

var location = new google.maps.LatLng(args[0], args[1])

5)   In marker we can able to set the title value and since I am using html tags and css class I’m replacing the html tags using the following syntax

marker.setTitle(message[i].replace(/(<([^>]+)>)/ig,””));

The rest of the mark up tags are same as mentioned in the Google doc.
So now we need to create the array from code behind. Copy paste the below code in to you code behind page load method
protected void Page_Load(object sender, EventArgs e)
 {
 List<String> oGeocodeList = new List<String>
 {
 " '40.756012, -73.972614' ",
 " '40.456012, -73.796087' ",
 " '40.456012, -73.456807' "
 };

 var geocodevalues = string.Join(",", oGeocodeList.ToArray());

 List<String> oMessageList = new List<String>
 {
 " '<span class=formatText >Google Map 3 Awesome !!!</span>' ",
 " '<span class=formatText>Made it very simple</span>' ",
 " '<span class=formatText>Google Rocks</span>' "
 };

 String message = string.Join(",", oMessageList.ToArray());

 ClientScript.RegisterArrayDeclaration("locationList", geocodevalues);

 ClientScript.RegisterArrayDeclaration("message", message);
 }

The above code List<String> oGeocodeList which creates a list of Geo-Code collection object. I have hard coded latitude and longitude (you can replace with your db procedure). Once you have created the list object we should convert in to Java Script array format like below

var geocodevalues = string.Join(“,”, oGeocodeList.ToArray()); and finally register the array

ClientScript.RegisterArrayDeclaration(“locationList”, geocodevalues); here locationList is the JS array object name.

Similarly I am creating the message array for the pop window (InfoWindow)

List oMessageList = new List
{
” ‘Google Map 3 Awesome !!!‘ “,
” ‘Made it very simple‘ “,
” ‘Google Rocks‘ ”
};

String message = string.Join(“,”, oMessageList.ToArray());   //convert list object to JS array format.

ClientScript.RegisterArrayDeclaration(“message“, message); //message = JS array object name.

Please refer the following links if you need to learn more about Map API 3.0

http://code.google.com/apis/maps/documentation/v3/introduction.html
http://code.google.com/apis/maps/documentation/v3/
http://code.google.com/apis/maps/documentation/v3/reference.html

Hope this help and If you have any comments, please feel free to write your feedback.

You can download the entire article from here or copy paste the URL

http://www.4shared.com/file/251039814/3e491cfc/GoogleMap3.html

If you find the Google Map 3 code library useful, please consider donating

Thanks
Deepu

Asp.Net 3.5 Ajax Modal Popup Extender with User Control Event Bubbling


I had a requirement to implement login control in a pop up window using Ajax Modal Popup extender. In this article I am discussing how to implement Usercontrol event bubbling (ie subscribe the user control event  in the parent page)  and the AjaxModal popup extender.

You can download the entire article from here

For more information about Ajax Model Popup Extender please visit http://www.asp.net/ajax/ajaxcontroltoolkit/Samples/ModalPopup/ModalPopup.aspx

If you find the Ajax Modal Popup code library useful, please consider donating



Scenario

Logged In users only can post the comment..
Login control is implemented in ASCX file.
Once the user logged in Successfully the user control event get fired in the Login Control ASCX page which is subscribed in the parent ASPX page.

Following are the screen shots for login control page and aspx page.

For more information about the user control event bubbling please visit the following links

http://asp.net-tutorials.com/user-controls/events/

http://codebetter.com/blogs/brendan.tompkins/archive/2004/10/06/Easily-Raise-Events-From-ASP.NET-ASCX-User-Controls.aspx

http://odetocode.com/code/94.aspx

Create a new ASCX  file called PopupLoginControl.ascx and copy paste the following markup tags.

<%@ Register Assembly=”AjaxControlToolkit” Namespace=”AjaxControlToolkit” TagPrefix=”ajaxtoolkit” %>

<asp:Button ID=”btnShowPopup” runat=”server” Style=”display: none” />

<ajaxtoolkit:ModalPopupExtender BackgroundCssClass=”modalBackground”
CancelControlID=”btnClose” runat=”server” PopupControlID=”Panel1″ ID=”ModalPopupExtender1″
TargetControlID=”btnShowPopup” />

<asp:Panel ID=”Panel1″ runat=”server” CssClass=”modalPopup” DefaultButton=”btnOk”>
<table width=”100%” border=”0″ cellpadding=”2″ cellspacing=”5″>
<tr>
<td style=”width:35%;padding-top:50px;”>
</td>
<td>
<asp:Label id=”labMsg” runat=”server” />
</td>
</tr>
<tr>
<td align=”right” valign=”middle”>
<strong>Email Id :</strong>
</td>
<td>
&nbsp;<asp:TextBox ID=”txtLogin” runat=”server”></asp:TextBox>
</td>
</tr>
<tr>
<td align=”right” valign=”middle”>
<strong>Password :</strong>
</td>
<td>
&nbsp;<asp:TextBox ID=”txtPassword” runat=”server” TextMode=”Password”></asp:TextBox>
</td>
</tr>
<tr>
<td>

</td>
<td>
<asp:Button ID=”btnOk” OnClick=”Login” runat=”server” Text=”Sign In” />
<asp:Button ID=”btnClose” runat=”server” Text=”Cancel” />

</td>
</tr>
</table>
</asp:Panel>

PopupLoginControl.ascx.Cs

 public event EventHandler LoginStatus;
 bool status;

 public Boolean IsLogin
 {
 get { return status; }
 }
 protected void Page_Load(object sender, EventArgs e)
 {

 }
 protected void Login(object sender, EventArgs e)
 {
 labMsg.Text = string.Empty;

 ModalPopupExtender1.Show(); //show pop up window

 if (LoginStatus != null)
 {
 if (txtLogin.Text.Equals("admin") && txtPassword.Text.Equals("admin"))
 {
 status = true;

 LoginStatus(this, EventArgs.Empty); //event get fired here.

 ModalPopupExtender1.Hide(); //hide pop up window once the user logged in successfully.
 }
 else
 {
 labMsg.Text = "<font color=red>Sorry user name and password could not find</font>";
 }
 }
 }
 public void EnableModelDialog(bool visibility)
 {
 if (visibility)
 {
 ModalPopupExtender1.Show();
 }
 else
 {
 ModalPopupExtender1.Hide();
 }
 }

LoginTest.aspx page(Markup)

<%@ Register Src=”PopupLoginControl.ascx” TagName=”PopupLoginControl” TagPrefix=”uc1″ %>

<style type=”text/css”>
.modalBackground
{
background-color: Gray;
filter: alpha(opacity=70);
opacity: 0.7;
}
.modalPopup
{
background-color: White;
height: 250px;
width:500px;
text-align:left;
}
</style>

<form id=”form1″ runat=”server”>

<asp:ScriptManager ID=”Scriptmanager1″ runat=”server” />

<asp:UpdatePanel ID=”UpdatePanel1″ runat=”server”>

<ContentTemplate>

<asp:LinkButton ID=”lnkWriteMessage” runat=”server” OnClick=”ShowMessage”>Write Comments</asp:LinkButton>

<uc1:PopupLoginControl ID=”PopupLoginControl1″  OnLoginStatus=”PopupLoginCntl_Completed”
Visible=”false” runat=”server” />

<asp:Panel ID=”divComments” Visible=”false” runat=”server”>

<table width=”50%”>
<tr>
<td>
<textarea id=”txtComments” rows=”10″ cols=”60″></textarea>
</td>
</tr>
<tr>
<td>
<asp:Button id=”btnSave” runat=”server” Text=” Save ” onclick=”btnSave_Click” />
</td>
</tr>
</table>

</asp:Panel>

</ContentTemplate>

</asp:UpdatePanel>

</form>

LoginTest.aspx page(CSharp)

protected void ShowMessage(object sender, EventArgs e)
 {
 PopupLoginControl1.Visible = true;
 PopupLoginControl1.EnableModelDialog(true);
 }

//method get called when the usercontrol event get fired
 protected void PopupLoginCntl_Completed(object sender, EventArgs e)
 {
 if (PopupLoginControl1.IsLogin)
 {
 divComments.Visible = true;
 }
 else
 {
 divComments.Visible = false;
 }
 }

 protected void btnSave_Click(object sender, EventArgs e)
 {
//save your comments here.
 }

For more information about the user control event bubbling please visit the following links

http://asp.net-tutorials.com/user-controls/events/

http://codebetter.com/blogs/brendan.tompkins/archive/2004/10/06/Easily-Raise-Events-From-ASP.NET-ASCX-User-Controls.aspx

http://odetocode.com/code/94.aspx

Hope this help and If you have any comments, please feel free to write your feedback.

You can download the entire article from here or copy paste the URL

http://www.4shared.com/file/245044652/c1777187/AjaxModelExtender.html

If you find the Ajax Modal Popup code library useful, please consider donating


Thanks
Deepu