More in this section
Categories
Bloggers
Blogs RSS feed

Hook OWIN middleware into Sitefinity

by Peter Filipov

OWIN stands for Open Web Interface for .NET. It is a specification that gives guidelines for how a web application and web server should decouple their communication. The implementation by Microsoft of this standard is called project Katana. Basically, it allows you to decouple your web application from IIS. To learn more about it I recommend you read this article, which summarizes the info very well.

Why it is important?

Using OWIN concepts allows you to handle requests in a different way than the traditional handler/module approach in ASP.NET. It makes everything faster and lightweight. By referencing the OWIN assemblies to your project, you will be able to plug many middlewares into your pipeline.

How to use it in Sitefinity?

The next question is “How to use OWIN middlewares in my Sitefinity project?” since this is a standard for an ASP.NET projects. Starting from version 10.2, Sitefinity supports easy OWIN pluggability (yes, this is a real word). The first step is to create a class and name it Startup. Second, create a method called Configuration and pass the IAppBuilder parameter. At the beginning of the method you must register the default Sitefinity middlewares. After this you can configure and register any middleware that you want, e.g. SignalR, Nancy etc. This example illustrates all of this in the best possible way:

using Owin;
using Telerik.Sitefinity.Owin;
 
namespace SitefinityWebApp
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Register default Sitefinity middlewares in the pipeline
            app.UseSitefinityMiddleware();
            
            app.MapSignalR();
            app.UseNancy();
 
        }
    }
}

 

The last step to notify the Sitefinity app that it has to consider your class definition as a plug point. Add this setting in your web.config file. Its value contains the full namespace of the class.

<add key="owin:appStartup" value="SitefinityWebApp.Startup" />

Use SignalR in Sitefinity

With the following example, I want to show you how a SignalR OWIN implementation could be used in a Sitefinity web application. The demo is based on the tutorial, Getting Started with SignalR 2 and MVC.

Installing SignalR from NuGet will replace the already referenced OWIN assemblies with lower versions and this will break your website. The solution is simple: reference only Microsoft.AspNet.SignalR.Core.dll and Microsoft.AspNet.SignalR.SystemWeb.dll. Also, add the SignalR JS file (jquery.signalR-2.2.2.js in addition with jquery 1.6.4). This is the initial setup and you are ready for the next steps.

Initial Setup

Plug the SignalR middleware into the Sitefinity pipeline and add the required setting in the web.config file. Define the Startup class and configure the SignalR:

using Owin;
using Telerik.Sitefinity.Owin;
 
namespace SitefinityWebApp
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Register default Sitefinity middlewares in the pipeline
            app.UseSitefinityMiddleware();
            // Configure SignalR middlewares
            app.MapSignalR();
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
 
        }
    }
}

Once you are done, go and create a ChatHub class that will take care of the execution of the clients’ updates.

using Microsoft.AspNet.SignalR;
 
namespace SitefinityWebApp.Hubs
{
    public class ChatHub : Hub
    {
        public void Hello()
        {
            Clients.All.hello();
        }
        public void Send(string name, string message)
        {
            // Call the addNewMessageToPage method to update clients.
            Clients.All.addNewMessageToPage(name, message);
        }
    }
}

 

Now the foundation of our sample is laid, and the last step is to create a Sitefinity Chat widget that encapsulates the logic and essence of SignalR.

Model:

namespace SitefinityWebApp.Mvc.Models
{
    /// <summary>
    /// The chat message.
    /// </summary>
    public class Room
    {
        /// <summary>
        /// Gets or sets the sender of the message.
        /// </summary>
        /// <value>
        /// From.
        /// </value>
        public string Title { get; set; }
    }
}

 

Controller:

using System.Web.Mvc;
using Telerik.Sitefinity.Mvc;
 
namespace SitefinityWebApp.Mvc.Controllers
{
    [ControllerToolboxItem(Name = "Chat", Title = "Chat client", SectionName = "MVC")]
    public class ChatController : Controller
    {
        public ActionResult Index()
        {
            var room = new SitefinityWebApp.Mvc.Models.Room() { Title = "Common" };
            return View("Index", room);
        }
    }
}

 

View: 

@model SitefinityWebApp.Mvc.Models.Room
<style type="text/css">
    .container {
        background-color: #99CCFF;
        border: thick solid #808080;
        padding: 20px;
        margin: 20px;
    }
</style>
<div class="container">
    <div>Room: @Model.Title</div>
    <input type="text" id="message" />
    <input type="button" id="sendmessage" value="Send" />
    <input type="hidden" id="displayname" />
    <ul id="discussion"></ul>
</div>
<!--Script references. -->
<!--Reference the jQuery library. -->
<script src="~/Scripts/jquery-1.6.4.min.js"></script>
<!--Reference the SignalR library. -->
<script src="~/Scripts/jquery.signalR-2.2.2.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="~/signalr/hubs"></script>
<!--Add script to update the page and send messages.-->
<script type="text/javascript">
 
    var jq164 = jQuery.noConflict(true);
 
    (function ($) {
        $(document).ready(function () {
            //Set the hubs URL for the connection
            $.connection.hub.url = "http://your.site.address/signalr";
            // Declare a proxy to reference the hub.
            var chat = $.connection.chatHub;
            // Create a function that the hub can call to broadcast messages.
            chat.client.addNewMessageToPage = function (name, message) {
                // Html encode display name and message.
                var encodedName = $('<div />').text(name).html();
                var encodedMsg = $('<div />').text(message).html();
                // Add the message to the page.
                $('#discussion').append('<li><strong>' + encodedName
                + '</strong>:  ' + encodedMsg + '</li>');
            };
            // Get the user name and store it to prepend to messages.
            $('#displayname').val(prompt('Enter your name:', ''));
            // Set initial focus to message input box.
            $('#message').focus();
            // Start the connection.
            $.connection.hub.start().done(function () {
                $('#sendmessage').click(function () {
                    // Call the Send method on the hub.
                    chat.server.send($('#displayname').val(), $('#message').val());
                    // Clear text box and reset focus for next comment.
                    $('#message').val('').focus();
                });
            });
        });
    }(jq164));
 
</script>

 

The widget will appear in your toolbox and will be ready for usage. Here is how it looks in action:

Chat

Outcome

With Sitefinity 10.2 you can register 3rd party OWIN middleware in an easy and clean way. There are thousands of packages that could be found on NuGet with millions of downloads, e.g. SignalR, Firewall, LESS, Compression etc. Try to find the appropriate solution your problem and plug it into Sitefinity. I hope that this functionality will make your daily jobs easier.

If you have interesting examples, I would like to encourage you to share them with the community. Happy extending and coding!

Leave a comment