Thursday, June 23, 2016

Setting up Hangfire in an ASP.NET Web API Application

If you want to run some background tasks inside your ASP.NET Web API application, I strongly suggest you have a look at Hangfire. You don’t need a separate Windows Service or anything, you can just spawn the task within the Web API. Having said that, Hangfire gives you extended functionality to run your background task as a Console Application or as a Windows Service. For the persistence storage for the tasks, Hangfire uses SQL Server, MySQL, Redis etc.

In this post let’s see how you can setup Hangfire with an ASP.NET Web API application. For that let’s start off by creating a ASP.NET Web API project.

After the project is created install Hangfire using Package Manager Console by simply running the Install-Package Hangfire command. Alternatively you can use Nuget Packet Manager to install Hangfire.
image
Install-Package Hangfire
Now you have all the necessary dependencies installed. Let’s jump into configuring Hangfire. Open up Startup.cs and modify the code as follows.
using Hangfire;
using Microsoft.Owin;
using Owin;
using System.Configuration;
 
[assembly: OwinStartup(typeof(HangfireDemo.Startup))]
 
namespace HangfireDemo
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
 
            GlobalConfiguration.Configuration.UseSqlServerStorage(ConfigurationManager.ConnectionStrings["HangfirePersistence"].ConnectionString);
            app.UseHangfireDashboard();
            app.UseHangfireServer();
        }
    }
}
Here you must specify the Hangfire persistence connection string. Here I have specified the connection string in the web.config and I have created a blank database as in the connection string in my SQL Server instance. app.UseHangfireDashboard() will setup a dashboard in http://<rootsiteurl>/hangfire for you to have a look at your jobs. app.UseHangfireServer() will setup a new instance of BackgroundJobServer. Now let’s just run the application.

You will see that a set of tables has been created in the Database which you have mentioned in the persistence connection string.
image
Hangfire Persistence Related Tables
Now let’s navigate to http://<rootsiteurl>/hangfire in the browser.

image
Hangfire Dashboard
As you can see, you will be provided with a nice little Dashboard where you can find important things such as Jobs, Retries etc.

Hangfire basically provide the ability to create following three types of tasks.
  • Fire-and-forget tasks
  • Delayed tasks
  • Recurring tasks
For the demonstration purposes, let’s just create a Recurring Task which will print something to output window every minute. What you need to do is just modify the Startup.cs adding the following line just below the app.UseHangfireServer().
RecurringJob.AddOrUpdate(() => Debug.WriteLine("Minutely Job"), Cron.Minutely);
And if you run the Web API application now, you can see the following in output window. “Minutely Job” will be written to output window every minute.

image
Debug Output
Now If we have a look at the dashboard, we can see important information related to the job we just created.
image
Hangfire Dashboard - Recurring Jobs
image
Hangfire Dashboard - Succeeded Jobs
So that’s it. You can find a rich documentation about Hangfire from their site. Do explore and high five to all the developers in Hangfire.

Happy Coding.

Regards,
Jaliya

Wednesday, June 22, 2016

ASP.NET Core 1.0 RC2 Status Code Handling

[Please note that this post discusses the topic in the context of ASP.NET Core 1.0 RC2]

In this post let’s see how we can easily handle Status Codes (for instance 404: Not Found) in an ASP.NET Core 1.0 web application.

By the framework we are given with 3 options.
  • app.UseStatusCodePages();
  • app.UseStatusCodePagesWithRedirects()
  • app.UseStatusCodePagesWithReExecute()

Let’s go through each of these by creating a sample application. From Visual Studio, create a new project and select ASP.NET Core Web Application (.NET Core) and from the next page select Web Application.
image
ASP.NET Core Web Application (.NET Core)
Once the project is created, open up Startup.cs and navigate to Configure method where you configure the Middleware for your ASP.NET Core Web Application.

There on the IApplicationBuilder, you can see the following three extension methods for handling status codes.
image
Extension Methods for Handling Status Codes
The easy way to generate 404 error is after running the application, navigate to a view which doesn’t exist. Now let’s see how we can handle 404 with each of these extension methods.


1. UseStatusCodePages



This is the most simple among all three options. Just modify the Configure method adding the following.
app.UseStatusCodePages();

Now if you generate a 404 by running the application, this is what you will get.

image
404
You can specify couple of options over there like modifying the response.
app.UseStatusCodePages("text/plain", "It's a : {0}");

image
404

2. UseStatusCodePagesWithRedirects



You can  use this method to specify a separate page (with either relative or absolute URL) as follows.
app.UseStatusCodePagesWithRedirects("/errorpages/{0}.html");
And here you need to add 404.html page inside a folder named “errorpages” under “wwwroot”.

404.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <h1> Not found. </h1>
</body>
</html>
And now if you generate a 404, this is the output.

image
404

And here if you take a closer look at the URL, you can see that it has been changed because the request is redirected to that particular page.


3. UseStatusCodePagesWithReExecute



When you use this approach what will happen is the request will be re executed (what ever the middleware which is defined after this line) and that’s using the given path.
app.UseStatusCodePagesWithReExecute("/statuscode/{0}");
For instance here the request will try to navigate to StatusCode controller and invoke the specified action. We don’t have a MVC controller named StatusCodeController and let’s just add it inside Controllers folder.
public class StatusCodeController : Controller
{
    [HttpGet("statuscode/{code}")]
    public IActionResult Index(int code)
    {
        return View(code);
    }
}
And let’s add the respective View for this action. For that let’s create a folder named StatusCode inside Views folder. There let’s add a MVC View Page named Index.cshtml.
<h1>@Model</h1>
Now let’s run the application and generate a 404.

image
404
Here you can notice that there was no URL redirection has been done.

So that's about it. Do explore ASP.NET Core 1.0.

Happy Coding.

Regards,
Jaliya

Tuesday, June 21, 2016

Integrating SignalR with ASP.NET Web API

In this post let’s see how we can integrate and trigger SignalR with ASP.NET Web API. Let’s start off by creating a solution and adding a ASP.NET Web API project and empty ASP.NET project. Let’s set the API project’s Project URL to {web_app_project_url}/api, so it will run under the Web App Project URL. And we need to modify the DefaultApi route to remove explicit “api” part as follows.
config.Routes.MapHttpRoute(
   name: "DefaultApi",
   routeTemplate: "{controller}/{id}",
   defaults: new { id = RouteParameter.Optional }
);
Now let’s install SignalR nuget package to the ASP.NET Web API project. You can use either Nuget Package Manager and Package Manager Console. I prefer using Package Manager Console by running Install-Package Microsoft.AspNet.SignalR.

image
Install-Package Microsoft.AspNet.SignalR
Now open up the Startup.cs in the Web API project and bootstrap SignalR as follows.
using Microsoft.Owin;
using Owin;
 
[assembly: OwinStartup(typeof(AspNetWebApiSignalRDemo.WebApi.Startup))]
 
namespace AspNetWebApiSignalRDemo.WebApi
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
            app.MapSignalR();
        }
    }
}
Now let’s create a folder inside Web API project named “Hubs” and add a SignalR Hub Class. I am naming it as “NotificationHub”.
image
SignalR Hub Class
The created file will contain a Hello() method, and I am just leaving it as it is.

Now let’s move into the empty web app project. For the sake of demonstration, I am using AngularJS to bootstrap the web app project. For that I am installing following dependencies using  bower.
image
bower dependencies
index.html
<!DOCTYPE html>
<html ng-app="AspNetWebApiSignalRDemo">
 
<head>
    <script src="bower_components/jquery/dist/jquery.min.js"></script>
    <script src="bower_components/signalr/jquery.signalR.min.js"></script>
    <script src="bower_components/angular/angular.min.js"></script>
    <script src="api/signalr/hubs"></script>
    <script src="app.js"></script>
 
    <title>ASP.NET Web API and SignalR Demo</title>
    <meta charset="utf-8" />
</head>
<body>
    <div ng-controller="AppController">
        
    </div>
</body>
</html>
app.js
'use strict';
 
angular.module("AspNetWebApiSignalRDemo", [])
 
.service("SignalrService", function () {
    var notificationHubProxy = null;
 
    this.initialize = function () {
        $.connection.hub.logging = true;
        notificationHubProxy = $.connection.notificationHub;
 
        notificationHubProxy.client.hello = function () {
            console.log("Hello from ASP.NET Web API");
        };
 
        $.connection.hub.start().done(function () {
            console.log("started");
        }).fail(function (result) {
            console.log(result);
        });
    };
})
 
.controller("AppController", ["SignalrService", function (SignalrService) {
    SignalrService.initialize();
}]);
Now if you run the solution, you will see that SignalR is making a successful connection with my NotificationHub in the ASP.NET Web API project.
image
SignalR connected successfully
To make sure whether we can invoke client side methods from the Web API project, let’s use the NotificationHub from a API action. For that I am modifying the NotificationHub class adding a static method as follows.
using Microsoft.AspNet.SignalR;
 
namespace AspNetWebApiSignalRDemo.WebApi.Hubs
{
    public class NotificationHub : Hub
    {
        private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>(); 

        public void Hello()
        {
            Clients.All.hello();
        }
 
        public static void SayHello()
        {
            hubContext.Clients.All.hello();
        }
    }
}
And let’s just modify Get() action in ValuesController as follows. Please note that I am attributing it with [AllowAnonymous], so I can access directly from the browser without authenticating.
[AllowAnonymous]
public IEnumerable<string> Get()
{
    NotificationHub.SayHello();
 
    return new string[] { "value1", "value2" };
}
And now if you invoke the /api/values from the browser, you will see that Web API is triggering client hub event "hello".
image
Web API + SignalR
I have made the sample code available in GitHub.
   AspNetWebApiSignalRDemo

Happy Coding.

Regards,
Jaliya

Wednesday, June 15, 2016

Wrote a post on Wiki Life at Official Blog of TechNet Wiki

Wrote a post in Wiki Ninjas - Official Blog of TechNet Wiki. The title of the post is Wiki Life: Wikis vs. Blog Posts.
image
Wiki Life: Wikis vs. Blog Posts
Read the rest on,
Wiki Life: Wikis vs. Blog Posts

Happy Coding.

Regards,
Jaliya

Sunday, May 22, 2016

Visual C# Technical Guru - April 2016

Another month as a judge in Microsoft TechNet Guru Awards under Visual C# category. The TechNet Guru Awards celebrate the technical articles on Microsoft TechNet.

Post in WikiNinjas Official Blog,
image
Visual C# Technical Guru - April 2016
Happy Coding.

Regards,
Jaliya

Tuesday, May 17, 2016

AngularJS : Passing Object as a State Parameter

In this post let’s see how we can pass Object to another state as a state parameter.

When defining the state, you need to specify that the state is expecting a state parameter. Here it's named as “myobjectparameter”.
.state("app.somestate.someotherstate", {
    url: "/someotherstate/:myobjectparameter",
    templateUrl: "sometemplate.tpl.html",
    controller: "SomeTemlateController",
})
And when you are navigating to “app.somestate.someotherstate” and specifying the value for “myobjectparameter”, you need to convert your object to a JSON string.
$state.go("app.somestate.someotherstate", {
  "myobjectparameter": JSON.stringify({
      "property1": "Property Value1",
      "property2": "Property Value2"
  })
});
And from “app.somestate.someotherstate” state, you need to  parse "$stateParams.myobjectparameter" which was passed as a string to a JSON object.
var myObjectParameter = JSON.parse($stateParams.myobjectparameter);
Happy Coding.

Regards,
Jaliya