Integrate OpenAuth/OpenID with your existing ASP.NET MVC4 application

In this blog I am going to talk about how to integrate OpenAuth/OpenId with your existing asp.net mvc4 application in Visual studio 2012

Step 1: Create a new project

Go to File –> New Project –> Web –> Empty Asp.Net MVC 4 Application

Step 2: Add the following libraries

  • Use Nuget to get the following packages
    • DotNetOpenAuth.AspNet
      • This package is the core package for OAuth/OpenID protocol communication
    • Microsoft.AspNet.Providers.Core
      • This package brings in Universal Providers
    • Microsoft.AspNet.Providers.LocalDb
      • This package sets the connectionstring for the Universal Providers
    • Microsoft.AspNet.Membership.OpenAuth
      • This package provides the extension to integrate OAuth/OpenID with Membership providers

Step 3: Change web.config to use formsauthentication

<authentication mode="Forms">
   <forms loginUrl="~/Auth/Logon" timeout="2880" />
</authentication>

Step 4: Adding AuthConfig

Add a new class called AuthConfig.cs to folder App_Start that class will contains the register functions for all services that we will integrate

Add the following code to AuthConfig.cs and don’t forget to get services Api keys from each service website

public static void RegisterAuth()
        {
            // To let users of this site log in using their accounts from other sites such as Microsoft, Facebook, and Twitter,
            // you must update this site. For more information visit http://go.microsoft.com/fwlink/?LinkID=252166

            OAuthWebSecurity.RegisterMicrosoftClient(
                clientId: "",
                clientSecret: "");

            OAuthWebSecurity.RegisterTwitterClient(
                consumerKey: "",
                consumerSecret: "");

            OAuthWebSecurity.RegisterFacebookClient(
                appId: "",
                appSecret: "");

            OAuthWebSecurity.RegisterGoogleClient();

            OAuthWebSecurity.RegisterLinkedInClient(
                consumerKey: "",
                consumerSecret: "");

      OAuthWebSecurity.RegisterYahooClient();
}

Register AuthConfig to application start Go to Global.asax and add the following line to Application_Start function

AuthConfig.RegisterAuth();

Step 5: Adding Login functionality

Add a new controller for Authentication functionality called it AuthController.cs
add Logon Action for login page

public ActionResult Logon()
        {
            return View(OAuthWebSecurity.RegisteredClientData);
        }

as you can notice that we user OAuthWebSecurity.RegisteredClientData as a model that object will contain all registered services that we put at AuthConfig class. Add a markup for login page

@using Microsoft.Web.WebPages.OAuth;
@model ICollection<AuthenticationClientData>

//Add this inside body
<div>
        @using (Html.BeginForm("ExternalLogin", "Auth", new { ReturnUrl = ViewBag.ReturnUrl }))
        {
            @Html.AntiForgeryToken()
            <p>
                @foreach (AuthenticationClientData p in Model)
                {
                    <button type="submit" name="provider" value="@p.AuthenticationClient.ProviderName" title="Log in using your @p.DisplayName account">@p.DisplayName</button>
                }
            </p>
        }
    </div>

as you can notice that we are looping against the services that we already registered in a previous step each AuthenticationClientData represent a service so we create a button to call that service we are adding all the buttons inside single form that calling ExternalLogin action method

add ActionMethod ExternalLogin

 [HttpPost]
 [AllowAnonymous]
 [ValidateAntiForgeryToken]
 public void ExternalLogin(string provider, string returnUrl)
 {
   OAuthWebSecurity.RequestAuthentication(provider, Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
 }

as you can notice its a void action. we are using OAuthWebSecurity.RequestAuthentication this function is requesting the authentication from the requested provider service “Facebook – Twitter – etc.” then it returned to The URL to return to when authentication is successful. we are mentioned “ExternalLoginCallback” as a returned back action

  [AllowAnonymous]
        public ActionResult ExternalLoginCallback(string returnUrl = "")
        {
            AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
            if (!result.IsSuccessful)
            {
                return RedirectToAction("ExternalLoginFailure");
            }

            //if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
            //{
            //    return RedirectToLocal(returnUrl);
            //}

            if (User.Identity.IsAuthenticated)
            {
                // If the current user is logged in add the new account
                OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name);
                return RedirectToLocal(returnUrl);
            }
            else
            {
                // User is new, ask for their desired membership name
                string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);
                ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
                ViewBag.ReturnUrl = returnUrl;
                OAuthAccount oAuthAccount = new OAuthAccount(result.Provider, result.ProviderUserId);

                return View("ExternalLoginConfirmation", new RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData });
            }
        }
 private ActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }

First: we have to verify authentication to ensure that the account is successfully authenticated if not redirect users to ExternalLoginFailure action if user is authenticated then we are going to login user to the system using simple membership we are going to talk about that in later posts then check if the current user is logged in add the new account else user is new, ask for their desired membership name then redirect to ExternalLoginConfirmation action with user information at RegisterExternalLoginModel class

 public ActionResult ExternalLoginConfirmation(RegisterExternalLoginModel model)
        {
            return View(model);
        }

RegisterExternalLoginModel

public class RegisterExternalLoginModel
    {
        [Required]
        [Display(Name = "User name")]
        public string UserName { get; set; }

        public string ExternalLoginData { get; set; }
    }

Finally: your application is ready to give it a test

You can download a sample from here

Google Charts with MVC3

In this blog I am going to talk about how to add the powerfull Google Charts to your asp.net MVC 3 Application. Google Chart Tools provide a perfect way to visualize data on your website. From simple line charts to complex hierarchical tree maps, the chart galley provides a large number of well-designed chart types. Populating your data is easy using the provided client- and server-side tools.

Step 1: Create a new project

Go to File –> New Project –> Web –> Asp.Net MVC 3 Application

Step 2:Javascript files and libraries

add the following javascript files to head of your page

<script type="text/javascript" src="/Scripts/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>

Step 3: Add Client Javascript and Html

 <script type="text/javascript">
        google.load("visualization", "1", { packages: ["corechart"] });
        google.setOnLoadCallback(drawChart);
        function drawChart() {
            $.get('/Home/GetData', {},
    function (data) {
        var tdata = new google.visualization.DataTable();

        tdata.addColumn('string', 'Year');
        tdata.addColumn('number', 'Salary');
        tdata.addColumn('number', 'Expense');

        for (var i = 0; i < data.length; i++) {
            tdata.addRow([data[i].Year, data[i].Salary, data[i].Expense]);
        }

        var options = {
            title: "Expenses, Salary For the current year"
        };

        var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
        chart.draw(tdata, options);
    });
        }
    </script>
  <div id="chart_div" style="width: 900px; height: 500px;">
        </div>

Note here we are making an ajax request to “/Home/GetData” to get data from server and assign data to google chart api

Step 4: Add ServerSide

  public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult GetData()
        {
            return Json(CreateCompaniesList(), JsonRequestBehavior.AllowGet);
        }

        private IEnumerable<Company> CreateCompaniesList()
        {
            List<Company> companies = new List<Company>();

            Company company = new Company() {  Expense = 200, Salary = 1000, Year = new DateTime(2012, 1, 1).ToString("yyyy/MM") };
            Company company1 = new Company() {  Expense = 300, Salary = 1100, Year = new DateTime(2012, 2, 1).ToString("yyyy/MM") };
            Company company2 = new Company() {  Expense = 240, Salary = 1200, Year = new DateTime(2012, 3, 1).ToString("yyyy/MM") };
            Company company3 = new Company() {  Expense = 100, Salary = 1300, Year = new DateTime(2012, 4, 1).ToString("yyyy/MM") };
            Company company4 = new Company() {  Expense = 40, Salary = 1100, Year = new DateTime(2012, 5, 1).ToString("yyyy/MM") };
            Company company5 = new Company() { Expense = 500, Salary = 1300, Year = new DateTime(2012, 6, 1).ToString("yyyy/MM") };

            companies.Add(company);
            companies.Add(company1);
            companies.Add(company2);
            companies.Add(company3);
            companies.Add(company4);
            companies.Add(company5);

            return companies;
        }
    }

That’s all. You can download the sample from here

Working examples using Signalr and asp.net MVC3

In this tutorial  I am going to talk about a real examples that we need to implement in most of projects.

Step 1: Create Application

Go to File –> New Project –> Web –> Asp.Net MVC 3 Application “Internet Application” (Make sure it’s .Net Framework 4).

Step 2: Add SignalR Package

Right click on references and click Manage NuGet Packages. Search for SignalR and click install. Or use NuGet package manager concole and install the SignalR package using

Install-Package SignalR

Step 3: Add Hub

Create a new Class named Chat in a new folder in the solution “Name it as u want”

 [HubName("chat")]
 public class Chat : Hub
 {
 }

Note the attribute HubName above the class name, that attribute is for naming the hub during calls as we going to see later

Step 4: Add Sending Functions

[HubName("chat")]
public class Chat : Hub, IDisconnect
{
  public void Send(string message, string clientId = "", string group = "")
  {
     if (!string.IsNullOrWhiteSpace(group))
     {
           //All clients in that group
           Clients[group].addMessage(message);
      }
      else if (string.IsNullOrWhiteSpace(clientId))
      {
           //All Clients
           Clients.addMessage(message);
      }
      else if (!string.IsNullOrWhiteSpace(clientId))
      {
           //The current caller
           Caller.addMessage(message);
           //The client with the clientId
           Clients[clientId].addMessage(message);
       }
   }
}

You can notice that the function has three parameters a required parameter message,two optional parameters clientId and group so if we need to send message to all users live in the application we can send only message to send function and leave, if we need to send message to only one user all we have to do is to add client id with message if we want to send a message to a specific group send group name with message only

Step 5: Change user Id

the main problem for us now is the client id, Because it is changeable with each single request to the page so we need to identify users so we can add to helpers the following helper class that will help us to resetting the connection id in hub

 public class UserIdClientIdFactory : IConnectionIdGenerator
    {
        public string GenerateConnectionId(IRequest request)
        {
            //Generates user GUID Id to identify each user with a unique id
            return Membership.GetUser().ProviderUserKey.ToString();
        }
    }

because i am using membership to login and security i used membership.GetUser function to get user id. Remember id here is a Guid so if you are using your own implementation and not using membership you have to generate a unique Guid id for each person.

Step 6: Register new user id to Application

Now we have to register the newly generated user id to the application we are going to add the following code in Global.asax

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

// register user id to SignalR Global Host
GlobalHost.DependencyResolver.Register(typeof(IConnectionIdGenerator), () => new UserIdClientIdFactory());
        }

Now in application start and while user opened a new session to your application the new Id we just made will be assigned to him and we can ue it to identify each user and send.

Step 7: Adding user to group

To add user to group i used action method in my HomeController to do that work

 public void AddToGroup(string groupName)
        {
            var context = GlobalHost.ConnectionManager.GetHubContext<Chat>();
            context.Groups.Add(Membership.GetUser().ProviderUserKey.ToString(), groupName);
        }

Step 8: Add client code

Append javascript references to the head of the page as follows

<script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR-0.5.2.min.js" type="text/javascript"></script>
<script src="/signalr/hubs" type="text/javascript"></script>

As you can notice there is a /signalr/hubs file included but its not in the project because its dynamically generated file in run time

Append the following javascript

<script type="text/javascript">

    $(function () {
        // Create connection with name chat. chat is hub name that we declared in Hub
        var connection = $.connection.chat;

        // Declare a function on the chat hub so the server can invoke it. Add message method is responsible for adding messages to the client
        connection.addMessage = function (message) {
            $('#messages').append('<li>' + message + '</li>');
        };

        // Send message
        $("#broadcast").click(function () {
            // Call the chat method on the server
            connection.send($('#msg').val(), $('#userId').val(), $('#group').val());
        });

        var timeout = null;
        var interval = 5000;

        // Event that will fire when server state changed
        $.connection.hub.stateChanged(function (change) {
            if (change.newState === $.signalR.connectionState.reconnecting) {
                timeout = setTimeout(function () {
                    $('#state').css('backgroundColor', 'red')
                    .html('The server is unreachable...');
                }, interval);
            }
            else if (timeout && change.newState === $.signalR.connectionState.connected) {
                $('#state').css('backgroundColor', 'green')
                        .html('The server is online');

                clearTimeout(timeout);
                timeout = null;
            }
        });

        // Start the connection
        $.connection.hub.start().done(function () {
            // Fetch client id and display
            var myClientId = $.connection.hub.id;

            $('#my-id').html(myClientId);
        });

    })
</script>

I added commented lines above each line to declare how it works.

Append the following Html to your page

<div>
    User ID
    <div id="my-id">
        0
    </div>
</div>
<div>
    Message:
    <input type="text" id="msg" />
    User Id:
    <input type="text" id="userId" />
    Group:
    <input type="text" id="group" />
    <input type="button" id="broadcast" value="broadcast" />
    <ul id="messages">
    </ul>
</div>

You can download the sample code from here

Creating RSS feed in ASP.net mvc3

In this toturial we are going through steps to create rss feed from a list of items using .NET’s built in SyndicatedFeed and SyndicatedItem class for content and two classes (Rss20FeedFormatter and Atom10FeedFormatter )  to handle XML generation with correct encoding, formatting and optional fields.

  1. Create an empty mvc3 application and name it “RSSFeed.Website” then add Home controller.
  2. Create a class and name it NewsItem  this class we will be used as a model for retrieving feed data from the database “i will fill it manually in a the next step ”
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace RSSFeed.Website.Models
    {
        public class NewsItem
        {
            public string Title { get; set; }
            public string Body { get; set; }
            public string ImageUrl { get; set; }
            public string Author { get; set; }
            public DateTime PublishedDate { get; set; }
            public string Url { get; set; }
        }
    }
  3. Optional step, Fill in NewsItem list if you have items in database so there is no need to fill the list like that you can get the data from the database and return it in a list of items
    public class NewsManager
        {
            public List<NewsItem> GenerateNews()
            {
                List<NewsItem> newsItems = new List<NewsItem>();
    
                NewsItem newsItem1 = new NewsItem()
                {
                    Author = "Mohamed Salah",
                    Body = "Clashes have broken out in several areas of Lebanon following Sunday's funeral of the senior intelligence official, Wissam al-Hassan.The most serious confrontations were in the northern city of Tripoli, where at least three people were killed as Sunni and Shia gunmen exchanged fire.In Beirut, there were clashes between soldiers and armed men in the Sunni Tariq al-Jadida district.Gen Hassan, a Sunni, was killed by a car bomb in the capital on Friday.He was the head of the intelligence branch of the Internal Security Forces and an outspoken critic of Syrian President Bashar al-Assad, a member of the Shia-based Alawite sect.",
                    Title = "Lebanon sees sectarian clashes after Hassan killing",
                    PublishedDate = DateTime.Today.AddDays(-5),
                    ImageUrl = "http://news.bbcimg.co.uk/media/images/63629000/jpg/_63629530_tripoli_reuters.jpg",
                    Url = "http://www.bbc.co.uk/news/world-middle-east-20025095"
                };
                newsItems.Add(newsItem1);
    
                NewsItem newsItem2 = new NewsItem()
                {
                    Author = "Mohamed Salah",
                    Body = "Cuba's revolutionary former leader Fidel Castro has written a strongly-worded article condemning persistent rumours that he is on his death bed.The 86-year-old attacked international media \"lies\", and published photos of himself in Cuba's state media.He said he was in good health, and could not even remember the last time he had a headache.Venezuelan politician Elias Jaua said on Sunday he had a five-hour meeting with Mr Castro the previous day.He presented a photo of the encounter, and said the former Cuban leader was \"very well, very lucid\".",
                    Title = "Cuba's Fidel Castro attacks 'lies' about his health",
                    PublishedDate = DateTime.Today.AddDays(-4),
                    ImageUrl = "http://news.bbcimg.co.uk/media/images/63628000/jpg/_63628162_63628161.jpg",
                    Url = "http://www.bbc.co.uk/news/world-latin-america-20025624"
                };
                newsItems.Add(newsItem2);
    
                return newsItems;
            }
        }
  4. We have to build our FeedResult class
    using System;
    using System.ServiceModel.Syndication;
    using System.Text;
    using System.Web;
    using System.Web.Mvc;
    using System.Xml;
    
    namespace RSSFeed.Website.Models
    {
        public class FeedResult : ActionResult
        {
            public Encoding ContentEncoding { get; set; }
            public string ContentType { get; set; }
    
            private readonly SyndicationFeedFormatter feed;
            public SyndicationFeedFormatter Feed
            {
                get { return feed; }
            }
    
            public FeedResult(SyndicationFeedFormatter feed)
            {
                this.feed = feed;
            }
    
            public override void ExecuteResult(ControllerContext context)
            {
                if (context == null)
                    throw new ArgumentNullException("context");
    
                HttpResponseBase response = context.HttpContext.Response;
                response.ContentType = !string.IsNullOrEmpty(ContentType) ? ContentType : "application/rss+xml";
    
                if (ContentEncoding != null)
                    response.ContentEncoding = ContentEncoding;
    
                if (feed != null)
                    using (var xmlWriter = new XmlTextWriter(response.Output))
                    {
                        xmlWriter.Formatting = Formatting.Indented;
                        feed.WriteTo(xmlWriter);
                    }
            }
        }
    }
  5. We almost done we have to create our rss page so we are going to create an ActionResult called NewsRss in HomeController
    public ActionResult NewsRss()
            {
                NewsManager newsManager = new NewsManager ();
                var postItems = newsManager.GenerateNews().OrderBy(p => p.PublishedDate).Take(25)
                    .Select(p => new SyndicationItem(p.Title, p.Body, new Uri(p.Url)));
    
                var feed = new SyndicationFeed("New Title", "New Description", new Uri("http://www.yahoo.com"), postItems)
                {
                    Copyright = new TextSyndicationContent("© 2010 copyrights reserved"),
                    Language = "en-US"
                };
    
                return new FeedResult(new Rss20FeedFormatter(feed));
            }
  6. we are done now except just putting a link to home to open up our RSS
    @Html.ActionLink("RSS", "NewsRss", "Home", null, new { target = "_blank" })

You can download a sample from here

 

nopcommerce: How to get Role Name from applied discount coupon?

- Create a discount from the cms admin

- Add  a requirement for that discount and select “Must be assigned to customer role” and choose a role.

The next steps can be done anywhere in the website, I will use the CommonController to show the role name inside the website header beside the user email

-  Go to CommonController  and inside the HeaderLinks method add these lines:

// Added by treenodes 10 Oct 2012
            string discountRoleName = string.Empty;
            if (discount !=null && discount.DiscountRequirements != null)
            {
                var requ = discount.DiscountRequirements.FirstOrDefault();
                foreach (var customerRole in customer.CustomerRoles.Where(cr => cr.Active).ToList())
                    if (requ != null && requ.RestrictedToCustomerRoleId == customerRole.Id)
                        discountRoleName = customerRole.Name;
            }

So the method will look like this

 

- You will need to declare the _discountService, so declare it in the Fields region

and then initialize it in the controller constructor:

- Add DiscountRoleName property inside the HeaderLinksModel

- Inside the HeaderLinks view, inside the IsAuthinticated check, add this:

<li><a href="#">@Model.DiscountRoleName</a></li>

- Login to the store and apply a coupon code you just created, you will see the role name of this applied discount coupon in the header. 

Quartz.net Schedulling Jobs

Introduction:

Sometimes when you develop an application, you are going to face some tasks needs to perform a certain action at a given time without any user interaction, example for that a User wants to set an alert in specific time to remind him with a date Or something else like updating records in database periodically. All this tasks needs non-human interaction, so how could you tell the machine to do this job ? that’s the question. Cron Job is the solution for this tasks. Quartz.net has presented an excellent open source job scheduler that can be used for these purposes.

What is Quartz ?

Quartz is a job scheduling system that can be integrated with, or used along side virtually any other software system. The term “job scheduler” seems to conjure different ideas for different people. As you read this tutorial, you should be able to get a firm idea of what we mean when we use this term, but in short, a job scheduler is a system that is responsible for executing (or notifying) other software components when a pre-determined (scheduled) time arrives.

Job , Schedule & Trigger:

At the beginning we have to recognize how the Quartz works. Jobs are Scheduled to run when a given Trigger occurs. Triggers can be created with nearly any combination of the following directives:

  • at a certain time of day (to the millisecond)
  • on certain days of the week
  • on certain days of the month
  • on certain days of the year
  • not on certain days listed within a registered Calendar (such as business holidays)
  • repeated a specific number of times
  • repeated until a specific time/date
  • repeated indefinitely
  • repeated with a delay interval

Quartz in Action:

Let’s go inside the code and see how Quartz works. First we will create a new Console application and get Quartz.net from Nuget Packages.

Now create a new class let’s name it MyJob, this class will be the job that we want it to be done in specific time, as we mention above it has to inherit from IJob interface.

public class MyJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            Console.WriteLine("My Job is working");
        }
    }

Back to the Program.cs class in the Main method we are going to Schedule our Job with a Trigger as we said above.

static void Main(string[] args)
        {
            // First we must get a reference to a scheduler
            ISchedulerFactory sf = new StdSchedulerFactory();
            IScheduler sched = sf.GetScheduler();

            Console.WriteLine("------- Initialization Complete -----------");

            // computer a time that is on the next round minute
            DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.UtcNow);

            Console.WriteLine("------- Scheduling Job  -------------------");

            // define the job and tie it to our HelloJob class
            IJobDetail job = JobBuilder.Create<MyJob>()
                .WithIdentity("job1", "group1")
                .Build();

            // Trigger the job to run on the next round minute
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("trigger1", "group1")
                .StartAt(runTime)
                .Build();

            // Tell quartz to schedule the job using our trigger
            sched.ScheduleJob(job, trigger);
            Console.WriteLine(string.Format("{0} will run at: {1}", job.Key, runTime.ToString("r")));

            // Start up the scheduler (nothing can actually run until the
            // scheduler has been started)
            sched.Start();
            Console.WriteLine("------- Started Scheduler -----------------");

            // wait long enough so that the scheduler as an opportunity to
            // run the job!
            Console.WriteLine("------- Waiting 65 seconds... -------------");

            // wait 65 seconds to show jobs
            Thread.Sleep(TimeSpan.FromSeconds(65));

            // shut down the scheduler
            Console.WriteLine("------- Shutting Down ---------------------");
            sched.Shutdown(true);
            Console.WriteLine("------- Shutdown Complete -----------------");

        }

Let’s explain our code. in the first two lines of code we are instantiating the Schedule which will going to register our job in it.

ISchedulerFactory sf = new StdSchedulerFactory();
IScheduler sched = sf.GetScheduler();

After that we will specify what time we want this job to run. The DateBuilder class is responsible to create our DateTimeOffset which will meet our need.

DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.Now);

This line means that we want our Job to run at the beginning of the next minute. And now we have to build our Job by using JobBuilder class.

IJobDetail job = JobBuilder.Create<MyJob>()
                .WithIdentity("job1", "group1")
                .Build();

Here we are building a job and specify a name for this job – “job1- ” and group name – “group1″.

JJobs and Triggers are given identifying names as they are registered with the Quartz.NET scheduler. Jobs and triggers can also be placed into ‘groups’ which can be useful for organizing your jobs and triggers into categories for later maintenance. The name of a job or trigger must be unique within its group – or in other words, the true identifier of a job or trigger is its name + group. If you leave the group of the Job or Trigger ‘null’, it is equivalent to having specified SchedulerConstants.DefaultGroup.

After that we have to create Trigger for this job by using TriggerBuilder class.

ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("trigger1", "group1")
                .StartAt(runTime)
                .Build();

Here we are saying to the trigger to start this job at the time which we were specifying before.

And then just we will schedule our job and start it. Notice that there is a line of code

Thread.Sleep(TimeSpan.FromSeconds(65));

this line is just to ensure that a minute will pass, because in our example we want the job to run at the beginning of the next minute. So this line is related to our example not always required.

At last we shut down the schedule. This was a simple example for Quartz.net, I’ll let you discover the whole features in this great library.

References

Quartz.net

FAQs

Download Sample

 

Using Signalr with Asp.net MVC to create simple chat application part II

As we mentioned in the previous example here, we can create a simple asynchronous actions with the signalr library like chat, real-time streaming and so on. in this blog i am going to go with another library from signalr its PersistentConnection. A PersistentConnection is the base class that has an api for exposing a SignalR service over http.

we are going to complete in the the previous application we created

Step 1:Add AdvChatController

we are going to create a new controller called AdvChatController with two action methods Index and Adv. then add index view

Step 2: Create Signalr PersistentConnection

Create a class the derives from PersistentConnection

using System.Threading.Tasks;
using SignalR;

public class MyConnection : PersistentConnection
{

}

Step 3:Setup Routing

Make a route for your connection in Global.asax

 public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapConnection<MyConnection>("AdvChat", "AdvChat/Adv/{*operation}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );
        }

If you are setting up other routes, the SignalR mapping needs to be done before the other ones.

Step 4: Adding receiving functionality in MyConnection

Add the following functions to MyConnection class

protected override Task OnConnectedAsync(IRequest request, string connectionId)
        {
            // add the user to group on connect
            return Groups.Add(connectionId, "SignalrGroup");
        }

        protected override Task OnReceivedAsync(IRequest request, string connectionId, string data)
        {
            // Messages are sent with the following format
            // group:message
            string[] decoded = data.Split(':');
            string groupName = decoded[0];
            string message = decoded[1];

            // Send a message to the specified
            return Groups.Send(groupName, message);
        }

        protected override Task OnDisconnectAsync(string connectionId)
        {
            // removes the user from group on disconnect
            return Groups.Remove(connectionId, "SignalrGroup");
        }

here as you notice we can manage the users that are connected to server first on connect action that action will be called when the user connects to the application so we can add the user to a certain group also on disconnect action that action will be called when user leaves the page so we can remove the user from group. also on received function to perform the sending action to certain group

step 5: Adding Client code

Append javascript references to the head of the page as follows

<script src="http://code.jquery.com/jquery-1.7.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR-0.5.2.min.js" type="text/javascript"></script>

Append the following javascript

<script type="text/javascript">
  $(function () {
            var connection = $.connection('AdvChat/Adv');

            connection.received(function (data) {
                $('#messages').append('<li>' + data + '</li>');
            });

            connection.start();

            $("#broadcast").click(function () {
                connection.send("SignalrGroup:"$('#msg').val());
            });
        });
  </script>

Append the following Html to your page

 <input type="text" id="msg" />
  <input type="button" id="broadcast" value="broadcast" />

  <ul id="messages">
  </ul>

that’s all you can now run the application now in multiple browsers and test it

You can download the sample from here

 

Using Signalr with Asp.net MVC to create simple chat application

In this tutorial I am going to talk about creating a simple chat application using signalr library with asp.net MVC. If we are trying to do a chat application or any asynchronous actions with client so we have a lot of work to do using ajax and javascript. Now with signalr it’s so simple and easy.

Step 1: Create an Empty Asp.Net MVC 3 Application

Go to File –> New Project –> Web –> Asp.Net MVC 3 Application (Make sure it’s .Net Framework 4).

Step 2: Add SignalR Package

Right click on references and click Manage NuGet Packages. Search for SignalR and click install. Or use NuGet package manager concole and install the SignalR package using

Install-Package SignalR

Step 3: Add HomeController

Right click on Controllers folder and click Add –> Controller. Then add index view to index action result by right click on index action method –> add view.

Step 4: Create Signalr Hub

Create a class that derives from Hub

public class Chat : Hub
  {
      public void Send(string message)
      {
          //Save to database if you want

          // Call the addMessage method on all clients
          Clients.addMessage(message);
      }
  }

Step 5: Adding Client

Append javascript references to the head of the page as follows

<script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR-0.5.2.min.js" type="text/javascript"></script>
<script src="/signalr/hubs" type="text/javascript"></script>

As you can notice there is a /signalr/hubs file included but its not in the project because its dynamically generated file in run time

Append the following javascript

<script type="text/javascript">
        $(function () {
            // Proxy created on the fly
            var chat = $.connection.chat;

            // Declare a function on the chat hub so the server can invoke it
            chat.addMessage = function (message) {
                $('#messages').append('<li>' + message + '</li>');
            };

            $("#broadcast").click(function () {
                // Call the chat method on the server
                chat.send($('#msg').val());
            });

            // Start the connection
            $.connection.hub.start();
        });
  </script>

I added commented lines above each line to declare how it works.

Append the following Html to your page

<input type="text" id="msg" />
        <input type="button" id="broadcast" value="broadcast" />
        <ul id="messages">
        </ul>

And that’s it you can run the application now in multiple browsers and all magic starts

You can download a sample from here

 

Login via Twitter inside your application step by step

In this blog post i am going to explain how to login via twitter inside your web application step by step

Introduction:

  • Twitter uses OAuth to provide authorized access to its information and data which gives
    • Secure – Users are not required to share their passwords with 3rd party applications, increasing account security.
    • Standard – A wealth of client libraries and example code are compatible with Twitter’s OAuth implementation.

Implementation:

  1. Create twitter application in order to connect to twitter with
    1. Go to Create a new application in twitter
    2. After creation completed successfully twitter will redirected to the main application page the most important information is “Consumer key”,”Consumer secret”
  2. Create a new MVC application “if you have already existing application skip this step”.
  3. Open Application Web.config file and add to appSettings section the following
    <add key ="TwitterConsumerKey" value="YOUR_CONSUMER_KEY"/>
    <add key ="TwitterConsumerSecret" value="YOUR_CONSUMER_SECRET"/>
    <add key="TwitterCallbackAddress" value="http://localhost:1644/Auth/LoginWithTwitter"/>
  4. Make sure that Authentication section is configured like that
    <authentication mode="Forms">
      <forms loginUrl="~/Auth/Login" cookieless="UseUri" timeout="2880" />
    </authentication>
  5. I’ve created three controllers “if you have already existing application just add the code in the appropriate place in your application”
    1. AuthController: To perform all authentication actions including normal login and login via twitter.
    2. HomeController: Landing page for the application with no Authentication
    3. AccountController:include pages that requires authorization
  6. At AuthController we will create all twitter login functionality
    1. First we need to create loginToTwitter() method which check if the current request is coming from twitter callback or its calling the authentication
        public OAuthTokenResponse LoginToTwitter()
              {
                  OAuthTokenResponse oAuthToken = new OAuthTokenResponse();
      
                  if (!string.IsNullOrWhiteSpace(Request["oauth_token"]) && !string.IsNullOrWhiteSpace(Request["oauth_verifier"]))
                  {
                      oAuthToken = GetAccessTokenForFirstTime(Request["oauth_token"], Request["oauth_verifier"]);
                  }
                  else
                  {
                      RedirectToTwitterAuthorization();
                  }
                  return oAuthToken;
              }
    2. if user is authenticated we have to get AccessTokenForTheFirstTime
       public OAuthTokenResponse GetAccessTokenForFirstTime(string authToken, string authVerifier)
              {
                  if (string.IsNullOrWhiteSpace(authToken)) throw new ArgumentNullException("authToken", "AuthToken musn't be null or empty");
                  if (string.IsNullOrWhiteSpace(authVerifier)) throw new ArgumentNullException("authVerifier", "AuthVerifier musn't be null or empty");
      
                  // Obtain the access token for this user for the fist time
                  OAuthTokenResponse response = OAuthUtility.GetAccessToken(consumerKey, consumerSecret, authToken, authVerifier);
                  return response;
              }
    3. if user request authorization so we have to redirect user to authorization page in twitter
      public void RedirectToTwitterAuthorization()
              {
                  string callbackAddress = ConfigurationManager.AppSettings["TwitterCallbackAddress"];
                  OAuthTokenResponse requestToken = OAuthUtility.GetRequestToken(consumerKey, consumerSecret, callbackAddress);
      
                  // Direct or instruct the user to the following address
                  Uri authorizationUri = OAuthUtility.BuildAuthorizationUri(requestToken.Token);
                  System.Web.HttpContext.Current.Response.Redirect(authorizationUri.OriginalString);
              }
    4. make sure that after Authorization you have to redirect user again using TwitterCallbackAddress that we specified before in web.config here i am redirecting the user to Auth/LoginWithTwitter action method
      public ActionResult LoginWithTwitter(string oauth_token, string oauth_verifier)
              {
                  OAuthTokenResponse oAuthTokenRes = LoginToTwitter();
                  if (!string.IsNullOrWhiteSpace(oauth_token) && !string.IsNullOrWhiteSpace(oauth_verifier))
                  {
                      if (!string.IsNullOrWhiteSpace(oAuthTokenRes.Token) && !string.IsNullOrWhiteSpace(oAuthTokenRes.TokenSecret))
                      {
                          TwitterUser user = GetsTwitterUser(oAuthTokenRes.Token, oAuthTokenRes.TokenSecret, oAuthTokenRes.UserId);
                          FormsAuthentication.SetAuthCookie(user.ScreenName, false);
      
                          return RedirectToAction("Index", "Account", new { screenName = user.ScreenName });
                      }
                  }
                  return RedirectToAction("Login", "Auth");
              }
    5. then we link that action method with a button in our view
      Explanation: first the user will go to action method LoginWithTwitter for the first time with no “oauth_token”,”oauth_verifier” so user will redirected to twitter login page according to LoginToTwitter function then returns again to the same action method LoginWithTwitter according to the link we specifie in web.config but this time with “oauth_token” and “oauth_verifier” so user will be authenticated according to LoginToTwitter function through getting GetAccessToken function if user authenticated successfully Twitter API will return OAuthTokenResponse in this step we can set user as authenticated user and with getting user information from twitter using GetsTwitterUser function and redirect to AccountController
  7. At AccountController make sure that the controller is Authorized to allow only authorized users to see its content
    [Authorize]
        public class AccountController : Controller
        {
            //
            // GET: /Account/
    
            public ActionResult Index(string screenName)
            {
                ViewBag.ScreenName = screenName;
                return View();
            }
        }
  8. at Index page in Account use ViewBag To view user Twitter Screen Name
    @{
        ViewBag.Title = "Index";
    }
    <h2>
        Account [Authorized Area]</h2>
    Welcome <span>@ViewBag.ScreenName </span>

You can download the full sample from here

 

 

Understanding Lazy Loading , Eager Loading and Explicit Loading with Entity Framework Implementation

In this article we are going to understand and differentiate between Lazy Loading, Eager Loading and Explicit Loading, first of all let’s define what are those.

Lazy Loading :

Lazy loading is a design pattern commonly used in computer programming to defer initialization of an object until the point at which it is needed. It can contribute to efficiency in the program’s operation if properly and appropriately used. In other words when objects are returned by a query, related objects are not loaded at the same time. Instead they are loaded automatically when the navigation property is accessed.

Eager Loading :

Eager loading is the opposite of Lazy loading which is : The process of loading a specific set of related objects along with the objects that were explicitly requested in the query.

Explicit Loading :

Explicit loading is defined as : when objects are returned by a query, related objects are not loaded at the same time. By default, they are not loaded until explicitly requested using the Load method on a navigation property.

Let’s try those three ways practically.

First create a project and use preferred tool to generate your DbContext , in my example I will use Northwind as a database , ADO.NET Entity Data Model and for class generator EF 4.x  DbContext Class Generator.

Add a MVC3 website project to your solution and start typing on HomeController the Index method :

using (var ctx = new NorthwindEntities())
            {
                var query = ctx.Categories.Take(3);
                foreach (var category in query)
                {
                    Response.Write(category.CategoryName);
                    Response.Write("</br>");
                    foreach (var product in category.Products)
                    {
                        Response.Write(product.ProductName);
                        Response.Write("</br>");
                    }

                }
            }

start your SqlProfiler and notice in this case we have 4 queries which means calling the database 4 times , one for the categories and three times for the products associated to the categories

First query

SELECT TOP (3)
[c].[CategoryID] AS [CategoryID],
[c].[CategoryName] AS [CategoryName],
[c].[Description] AS [Description],
[c].[Picture] AS [Picture]
FROM [dbo].[Categories] AS [c]

Second query

exec sp_executesql N’SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent1].[SupplierID] AS [SupplierID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[UnitsInStock] AS [UnitsInStock],
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent1].[ReorderLevel] AS [ReorderLevel],
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[CategoryID] = @EntityKeyValue1′,N’@EntityKeyValue1 int’,@EntityKeyValue1=1

Third query

exec sp_executesql N’SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent1].[SupplierID] AS [SupplierID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[UnitsInStock] AS [UnitsInStock],
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent1].[ReorderLevel] AS [ReorderLevel],
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[CategoryID] = @EntityKeyValue1′,N’@EntityKeyValue1 int’,@EntityKeyValue1=2

Fourth query

exec sp_executesql N’SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent1].[SupplierID] AS [SupplierID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[UnitsInStock] AS [UnitsInStock],
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent1].[ReorderLevel] AS [ReorderLevel],
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[CategoryID] = @EntityKeyValue1′,N’@EntityKeyValue1 int’,@EntityKeyValue1=3

So in Lazy Loading pattern the Object comes with its associated/related Objects.

Now let’s turn off Lazy Loading and try Eager Loading in our example and notice what will happen. By default Lazy Loading is enabled in Entity Framework, so just add this line before our code and do the same process.

using (var ctx = new NorthwindEntities())
            {
                ctx.Configuration.LazyLoadingEnabled = false;

Notice in SqlProfiler that the query was just One , which means it ignored the Object related Objects

SELECT TOP (3)
[c].[CategoryID] AS [CategoryID],
[c].[CategoryName] AS [CategoryName],
[c].[Description] AS [Description],
[c].[Picture] AS [Picture]
FROM [dbo].[Categories] AS [c]

Now we are going to use  Include() method and notice what will happen. just change your code to be :

var query = ctx.Categories.Include("Products").Take(3);

Notice in SqlProfiler that there is just one query looks like :

SELECT
[Project1].[CategoryID] AS [CategoryID],
[Project1].[CategoryName] AS [CategoryName],
[Project1].[Description] AS [Description],
[Project1].[Picture] AS [Picture],
[Project1].[C1] AS [C1],
[Project1].[ProductID] AS [ProductID],
[Project1].[ProductName] AS [ProductName],
[Project1].[SupplierID] AS [SupplierID],
[Project1].[CategoryID1] AS [CategoryID1],
[Project1].[QuantityPerUnit] AS [QuantityPerUnit],
[Project1].[UnitPrice] AS [UnitPrice],
[Project1].[UnitsInStock] AS [UnitsInStock],
[Project1].[UnitsOnOrder] AS [UnitsOnOrder],
[Project1].[ReorderLevel] AS [ReorderLevel],
[Project1].[Discontinued] AS [Discontinued]
FROM ( SELECT
[Limit1].[CategoryID] AS [CategoryID],
[Limit1].[CategoryName] AS [CategoryName],
[Limit1].[Description] AS [Description],
[Limit1].[Picture] AS [Picture],
[Extent2].[ProductID] AS [ProductID],
[Extent2].[ProductName] AS [ProductName],
[Extent2].[SupplierID] AS [SupplierID],
[Extent2].[CategoryID] AS [CategoryID1],
[Extent2].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent2].[UnitPrice] AS [UnitPrice],
[Extent2].[UnitsInStock] AS [UnitsInStock],
[Extent2].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent2].[ReorderLevel] AS [ReorderLevel],
[Extent2].[Discontinued] AS [Discontinued],
CASE WHEN ([Extent2].[ProductID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM   (SELECT TOP (3) [c].[CategoryID] AS [CategoryID], [c].[CategoryName] AS [CategoryName], [c].[Description] AS [Description], [c].[Picture] AS [Picture]
FROM [dbo].[Categories] AS [c] ) AS [Limit1]
LEFT OUTER JOIN [dbo].[Products] AS [Extent2] ON [Limit1].[CategoryID] = [Extent2].[CategoryID]
)  AS [Project1]
ORDER BY [Project1].[CategoryID] ASC, [Project1].[C1] ASC

This query shows the Object Category and its related Objects Projects in One query.

Finally we will try the Explicit Loading , just change your code to be like this :

using (var ctx = new NorthwindEntities())
            {
                ctx.Configuration.LazyLoadingEnabled = false;
                var query = ctx.Categories.Take(3);
                foreach (var category in query)
                {
                    Response.Write(category.CategoryName);
                    Response.Write("</br>");
                    ctx.Entry(category).Collection(c => c.Products).Load();
                    foreach (var product in category.Products)
                    {
                        Response.Write(product.ProductName);
                        Response.Write("</br>");
                    }

                }
            }

Notice in SqlProfiler it looks like the Lazy Loading result , there are 4 queries to the database.

I hope you can differentiate between the three patterns.

Ref:

Wiki

http://blogs.msdn.com

http://weblogs.asp.net

Code Sample:

LoadingsExample