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.

Convert C# camel case json property to pascal case


I am pretty sure that many of them faced the same scenario where you would end up copy/paste some json data from a third party API sites And using one of the tools like Visual Studio IDE or json2csharp.com to generate POCO classes. However, these tools will not generate pascal case property’s automatically And if you want to maintain the coding standard you have to change the property’s to pascal case manually.

For example : Default camel case property’s generated based on Visual Studio IDE

public class Refunds
{
   public string @object { get; set; }
   public bool has_more { get; set; }
}

Since I had to convert many json property’s to pascal casing which is a tedious task so I have developed an app to convert camel case csharp json property to pascal case. http://deepumi.com/jsonproperty2TitleCase/

jsonProperty2TitleCase Core Features:

  • Convert property to Title case which is Pascal case
  • Add NewtonsoftJson property attribute to add the actual json property name for deserializing purpose.
  • Also, handles nested classes hierarchies.
  • Beautify your csharp code  (Remove all extra white spaces)

jsonProperty2TitleCase Output:

using Newtonsoft.Json;

public class Refunds
{
    [JsonProperty("object")]
    public string Object { get; set; }

    [JsonProperty("has_more")]
    public bool HasMore { get; set; }
}

http://deepumi.com/jsonproperty2TitleCase/

jsonproperty

Please feel free to give this a try and let me know your thoughts and suggestions.

http://deepumi.com/jsonproperty2TitleCase/

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

 

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

Yahoo Geocoding API Service in Asp.Net 3.5 C# using WebClient class (Asynchronously)


In this article I am going to explain how to consume yahoo Geocoding API service in Asp.Net C# using web client Asynchronous method.
If you are working with maps you may require latitude and longitude to show the address in map. Yahoo!s APIs is the awesome tool provides APIs for many of the services Maps, Music, Search, Search Marketing, Shopping, Travel etc…

Click here to download the entire article

Assume you have a list of locations in your database and need to pull Geo-coder (latitude and longitude) from yahoo API service  in Asynchronous manner.. (per day you can query 5000 request from a single ip address). Geocoding service is a free service you have to register in order to use it. http://developer.yahoo.com/maps/rest/V1/geocode.html

So lets create a simple class called Location with two properties LocationId,Address.

public class Location
{
public int LocationId { get; set; }
public string Address { get; set; }

public static List<Location> GetLocationList()
{
List<Location> oAddressList = new List<Location>
{
new Location{ LocationId = 1, Address = "1001 Emerald Heights Ct, Reston VA 20191"},
new Location{ LocationId = 2, Address = "1001 University Ave, West Des Moines, IA 50266"},
new Location{ LocationId = 3, Address = "701 First Ave Sunnyvale,CA"},
};
return oAddressList;
}
}

I have hard coded three different addresses you can change this with your database logic.  The next step is to create a new aspx page and make sure if you are using asynchronous call you have to add Async=”true” in the page header of the Aspx page.

Task List in the aspx page.

1) Add Async=”true”  in the page header.
2)
Get the locations list from the business object / database.
3) Initializing yahoo application id (http://developer.yahoo.com/maps/rest/V1/geocode.html).
4) Construct url for geocode service (make sure you are sending address in encode format using Server.UrlEncode method).
4) Consume Geo-code service using web client class with Asynchronous manner.
5) Send Address information along with a custom token, AddressId (so that I can update geocode information to database for the particular address).
5) Download result xml from yahoo api service.
6) Parse the xml content and get Latitude and longitude

In the Page_Load Method

protected void Page_Load(object sender, EventArgs e)
 {
string YAHOO_API_SIGNATURE = "YD-9G7bey8_JXxQP6rxl.fBFGgCdNjoDMACQA--";

 string YAHOO_API_URL = "http://local.yahooapis.com/MapsService/V1/geocode?appid=" + YAHOO_API_SIGNATURE + "&street=";

 string url = string.Empty;

 var oGeoCoderList = Location.GetLocationList();

 foreach (Location location in oGeoCoderList)
 {
 WebClient oWebClient = new WebClient();

 oWebClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(DownloadDataCompleted);

 url = string.Concat(YAHOO_API_URL, Server.UrlEncode(location.Address));

 oWebClient.DownloadDataAsync(new Uri(url), location.LocationId);
 }
}

Code Explanations

Initializing yahoo application id

string YAHOO_API_SIGNATURE = “YD-9G7bey8_JXxQP6rxl.fBFGgCdNjoDMACQA–“;

Initializing yahoo web service API URL.

string YAHOO_API_URL = “http://local.yahooapis.com/MapsService/V1/geocode?appid=&#8221; + YAHOO_API_SIGNATURE + “&street=”;

Get location list from business object or database.

var oGeoCoderList = Location.GetLocationList();

Create a webclient object

WebClient oWebClient = new WebClient();

Create event handler (DownloadDataCompleted) this event get fired when an asynchronous data download operation complete.

oWebClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(DownloadDataCompleted);

Append location address with yahoo api url.

url = string.Concat(YAHOO_API_URL, Server.UrlEncode(location.Address));

DownloadDataAsync method downloads resources as System byte array.

oWebClient.DownloadDataAsync(new Uri(url), location.LocationId);

Loop through the location list and send address information to yahoo service along with a custom token, AddressId (so that I can update laster to database for the particular address).

 void DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
 {
 try
 {
 if (e.Error == null) //make sure there is no error.
 {
 byte[] byteContent = e.Result;

 string result = System.Text.Encoding.ASCII.GetString(byteContent);

 if (!string.IsNullOrEmpty(result))
 {
 int addressId = (int)e.UserState;

 var xml = XElement.Parse(result);

 xml = StripXMLNameSpace(xml);

 if (xml != null)
 {
 XElement xelement = (XElement)xml;
 string latitude = (from geoCodeService in xelement.Descendants("Result").Descendants("Latitude")
 select geoCodeService.Value).Take(1).SingleOrDefault<String>();

 string longtitue = (from geoCodeService in xelement.Descendants("Result").Descendants("Longitude")
 select geoCodeService.Value).Take(1).SingleOrDefault<String>();

 UpdateLocation(addressId, latitude, longtitue);
 }
 }
 }
 else
 {
 //log your error information here.
 }
 }
 catch (Exception exp)
 {
 //log system exception here
 }
 }

 void UpdateLocation(int addressId, string latitude, string longtitue)
 {
 //implement your update logic here....
 }

 XElement StripXMLNameSpace(XElement root)
 {
 return new XElement(
 root.Name.LocalName,
 root.HasElements ?
 root.Elements().Select(el => StripXMLNameSpace(el)) :
 (object)root.Value
 );
 }

Once we retrieve the information from yahoo service the above method will convert the result system byte array to string using System.Text.Encoding.ASCII.GetString method and also get the user defined object which we already passed to the method and remove the xmlns:name space  from the XML result and getting the values of latitude and longitude from the nodes. In my upcoming articles  I would like to explain how to integrate Google (MAPS & Street View) and Virtual Earth (with multiple address location)

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 this URL

http://www.4shared.com/file/241083617/7919b1a7/YahooApiGeoCoder.html

Thanks
Deepu

Create RSS 2.0 and Atom 1.0 in Asp.Net 3.5 C#


In this article I am going to explain how we can create web syndications like RSS 2.0 and Atom 1.0 in Asp.Net and C# with very minimal code. (You can download the entire article from here ).

RSS 2.0
Really Simple Syndication (RSS) is one of the syndication feed formats which can get the frequently updated content from the web site. (Refer:  http://en.wikipedia.org/wiki/RSS).
The specification of RSS format http://cyber.law.harvard.edu/rss/rss.html.  RSS is most widely used syndication format.

Atom 1.0
Atom is a syndication format which is more flexible than RSS.  Atom came into existence out of a need to improve RSS. (Refer: http://en.wikipedia.org/wiki/Atom_standardard)

In Asp.Net 3.5 frame work we can create subscription feeds with very minimal code using System.ServiceModel.Syndication namespace which contains all of the classes that make up the Syndication Object Model.   For example below is a sample Blog class I am defining a public method and some properties to retrieve the blog items (I have hardcoded two items you can replace this from your database logic).

The next step I am going to create another class called Syndication Helper which converts our web content to syndication format.

Code Explanation

Uri uri = new Uri(“https://deepumi.wordpress.com&#8221;);

Configure your site url ( blog or news).

SyndicationFeed syndicationFeed = new SyndicationFeed();
Syndicaiton Feed class represent a top level of feed object, (you can add your blog name / site name with description and the last blog/site updated time).

List<SyndicationItem> items = new List<SyndicationItem>();
Syndication Item class represent a individual feed atom/rss.item object like item url, item description, item id, last updated etc. Here I am creating a syndicaiton item collection object which mapping from MyBlogList() method.

List<Blog> oBlogList = Blog.GetMyBlogList();
foreach (Blog oBlog in oBlogList)
{
SyndicationItem oItem = new SyndicationItem(oBlog.Title,
SyndicationContent.CreateHtmlContent(oBlog.Description),
new Uri(oBlog.Url),
oBlog.BlogId.ToString(),
oBlog.LastUpdated);
items.Add(oItem);
}

Finally you are return the SyndicationFeed object to the aspx pages.
Now we need to render the atom and rss content in the aspx pages.

Create a new aspx page called rss.aspx and make sure there is no html markup in the page(just a blank page)

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”rss.aspx.cs” Inherits=”rss” %>

Code behind (RSS page)


Create a new aspx page called rss.aspx and make sure there is no html markup in the page(just a blank page)

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”atom.aspx.cs” Inherits=”atom” %>

Code behind (Atom page)


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 this URL

http://www.4shared.com/file/240764190/b37e055d/Feeds.html

Thanks
Deepu

LINQ to XML CRUD Operations


CRUD (Create, Read, Update & Delete) four operations for adding, displaying, modifying and deleting data.  This articles explains how CRUD operation can be achieved using  LINQ to XML. (You can download the entire article from here).

For example you want to store  Members information in an XML file and you may need to implement  add /  edit / delete functionality through a  UI.

So I am going to create a XML file with four nodes like firstName,lastName,email and phone.

<?xml version="1.0" encoding="utf-8"?>
<Members>
 <member id="f02c78b4956f4b2f9ecfb7a5bfbcfbf6">
 <firstName>Deepu</firstName>
 <lastName>M.I</lastName>
 <email>me@gmail.com</email>
 <phone>123-456-7890</phone>
 </member>
</Members>

Screen shots for CRUD Operations (Create Screen)

Using the following method we can Create a new member information to the XML file.


XDocument doc = XDocument.Load(FilePath);  //load the xml file.
 IEnumerable<XElement> oMemberList = doc.Element("Members").Elements("member");
var oMember = new XElement("member",
 new XAttribute("id", Guid.NewGuid().ToString().Replace("-", "")),
 new XElement("firstName", txtFirstName.Value),
 new XElement("lastName", txtLastName.Value),
 new XElement("email", txtEmail.Value),
 new XElement("phone", txtPhone.Value)
 );
oMemberList.Last().AddAfterSelf(oMember);  //add node to the last element.
doc.Save(FilePath);

XDocument class will load the xml file and will find the last member node and save the information to the file.

The next screen will show all the members in the xml file in Grid format using ListView control.

XElement element = XElement.Load(FilePath);  //replace with xml file path
if (element != null)
{
var query = from member in element.Descendants("member")
select new
{
MemberId = (string)member.Attribute("id"),
FirstName = member.Element("firstName").Value,
LastName = member.Element("lastName").Value,
Email = member.Element("email").Value,
Phone = member.Element("phone").Value
};
if (query != null && query.Count() > 0)
{
lvMemberList.DataSource = query.ToList();
lvMemberList.DataBind();
}
}

Update method is similar to create method like load a xml file and find the corresponding member node by Id or email and finally it will update node values using SetElementValue method some thing like below.


XDocument doc = XDocument.Load(FilePath); //replace with xml file path
IEnumerable<XElement> oMemberList = doc.Element("Members").Elements("member"); //get the member node.
var oMember = (from member in oMemberList
 where
 member.Attribute("id").Value == 2
 select member).SingleOrDefault(); //replace memberId by querystring value.
 oMember.SetElementValue("firstName", firstName);
 oMember.SetElementValue("lastName", lastName);
 oMember.SetElementValue("email", email);
 oMember.SetElementValue("phone", phone);
 doc.Save(FilePath);

Finally the Delete will be deleteing a node element from the xml file.


XElement element = XElement.Load(FilePath);
 if (element != null)
 {
 var xml = (from member in element.Descendants("member")
 where
 member.Attribute("id").Value == 2
 select member).SingleOrDefault();

 if (xml != null)
 {
 xml.Remove();
 element.Save(FilePath);
 }
 }

Note : This post does not have the complete source code. please download the full working source code from the download link.

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

http://www.4shared.com/file/236175264/b5df239/CRUD.html

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

Thanks
Deepu