Category Archives: ASP.NET

SignalR with MVC 5

I had some difficulty getting SignalR set up with a recent web application being developeed for a client. Some of the documentation found online were geared towards older versions of SignalR, while others didn’t seem to work with my setup.

I am creating additional functionality for a web client that allows a server to push information to a client when certain events trigger. Being a MVC and HTML5 application I decided to utilize Web Sockets.

  • With Visual Studio 2012 I installed the SignalR nuget package to speed up the installation.
  • I created a Startup.cs file in the project’s App_Start folder placing the following code inside of it:
using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Owin;
using Desking.SignalR;

[assembly: OwinStartup(typeof(Desking.Startup))]
namespace Desking
   {
      public class Startup
      {
         public void Configuration(IAppBuilder app)
         {
            app.MapSignalR();
         }
      }
   }
  • SignalR has the ability to dynamically generate the hub js file found at signalr/hub at the applications root used for talking to the server, but the generated file was not minified and I couldn’t find a way to integrate it with MVC’s script bundles I use across the application. I decided instead to take the dynamically generated file and place into a normal js file.
  • At the end of the hub.js file I needed to modify the relative path url
signalR.hub = $.hubConnection("/applicationPath/signalr", { useDefaultPath: false });
  • I created the following hub file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using Desking.Models;

namespace Desking.SignalR
{
    [HubName("deskingHub")]
    public class DeskingHub : Hub
    {
        public void sendNotification(String Name, String Message)
        {
            Clients.Client(Context.ConnectionId).addMessage(Name + ": " + Message);
        }

        public void registerClient(long DeskingDraftRevisionID)
        {
            DealMethods.RegisterClient(DeskingDraftRevisionID, Guid.Parse(Context.ConnectionId));
        }

        public enum Statuses
        {
            FinancingConfirmed = 0,
            NeedManager,
            ReadyForDocuments,
        }
    }
}
  • The registerClient method is used when the client first loads the application by registering and linking the draft id they have opened to the connection ID generated by SignalR. This allows the server to send notifications based on the draft id needing to be notified
  • The following js is included on the initial page load:
function SetupFinancingNotifications() {
    // Declare a proxy to reference the hub. 
    var chat = $.connection.deskingHub;

    // Create a function that the hub can call to broadcast messages.
    chat.client.addMessage = function (message) {
        alert(message);
    };

    // Start the connection.
    $.connection.hub.start().done(function () {
        chat.server.registerClient($('#labelDealStatusQuoteNumber').text());
        $('#sendmessage').click(function () {
            // Call the Send method on the hub. 
            chat.server.sendNotification($('#displayname').val(), $('#message').val());
            // Clear text box and reset focus for next comment. 
            $('#message').val('').focus();
        });
    });
}
  • The js registers itself with the server given the revision id currently opened. The SignalR’s client instance ID is taken from the request context on the server side and isn’t needed to be pass in manually.
  • After the client is set up all that is left to do is create a method that will signal the web client:
public static void NotifyClient(long DealID, DeskingHub.Statuses DealStatus, String Message)
{
   using (CRMEntities db = new CRMEntities())
   {
       DeskingDraftFinancingNotification notification = db.DeskingDraftFinancingNotifications.Where(x => x.DealID == DealID).FirstOrDefault();

       if (notification != null)
       {
           try
           {
               IHubContext notificationHub = GlobalHost.ConnectionManager.GetHubContext<DeskingHub>();

               notificationHub.Clients.Client(notification.ConnectionID.ToString()).addMessage(DealStatus, Message);
           }
           catch (Exception ex)
           {
               ex.LogToElmah();
           }
       }
   }
}

In the future I will need to add more functionality to allow client -> server communication, as well as getting SignalR to function behind a load balancer across 3 servers using the SQL backplane.

Sending Emails with ZOHO

Since Google Apps stopped being free of charge I needed an alternative service to hook a newly registered domain to in order to receive an authorization request when creating a new SSL certificate for the domain. Most CAs require an email address with the domain name to verify ownership. If you are just spinning up a domain without an email server this can cause issues. Zoho mail offers a free email service to suite this need, as long as you are only using it for one domain that is.

Creating a new account and setting up your domain with it is simple, Add a CNAME record to your domain with their information to verify ownership and you’re good to go!

I decided to write a simple subscription service to test out their email functionality. The only snag I ran into here was needing to enable incoming SMTP in the settings. The code required to write an email through the Zoho server is simple:

 SmtpClient client = new SmtpClient
 {
    Host = "smtp.zoho.com",
    Port = 587,
    EnableSsl = true,
    DeliveryMethod = SmtpDeliveryMethod.Network,
    UseDefaultCredentials = false,
    Credentials = new NetworkCredential("from@address.com", "password")
 };

 using (MailMessage notificationMessage = new MailMessage())
 {
    notificationMessage.From = new MailAddress("from@address.com", "Display Name");

    notificationMessage.To.Add("to@address.com");

    notificationMessage.Subject = "You've been subscribed to cat facts!";
    notificationMessage.Body = "Welcome to the club!";

    client.Send(notificationMessage);
 }

Some limitations of Zoho are sending oh behalf of another email address. Unless the email you are sending is from an address of an account on Zoho the message will not send.