Jquery Spellchecker for .NET

by Anthony 24. February 2013 08:08

Spell checkers on the web are dying.  Most modern browsers detect spelling mistakes for you, HOWEVER, there are some circumstances where it still makes sence to have them.  Take the following word:

 

  • pneumonoultramicroscopicsilicovolcanokoniosis
    • this is “a lung disease caused by the inhalation of very fine silica dust, causing inflammation in the lungs.” Another term for the same condition is silicosis.

 

Spell checkers are not going to pick that word up, sure you could add it to the dictionary, but what if you work in a field where those types of words come up all of the time.  That is where custom dictionaries come into play. 

Another issue is IE9, I know what your saying, "Why are you using IE?"  First, I am not, but my users are and they want spell check too.  I found a very nice implementation of a JQuery Spell checker, that even plugs into Tiny MCE (also in the example) written by Richard Willis at https://github.com/badsyntax/jquery-spellchecker.  

Unfortunately the backend is written in PHP.  So I found another port of the PHP code to .net written by Jack Yang https://github.com/jackmyang/jQuery-Spell-Checker-for-ASP.NET.  Unfortunately, this supported an older version of the spell check library but failed on the new version.  Also it only supported the google spell checker which had some limitations.

So long story short, I rewrote it to support .NET.  You can find it here:

https://github.com/AnthonyTerra/ASP.MVC-Jquery-Spellchecker

Hope it helps others looking for a spell checker.


EDIT AS OF  2/28

I have refactored the code to make it easier to add new spell check libraries.  You can still find it at the same location. 

Tags: , ,

jquery | MVC4 | Spellcheck

MSMQ and SignalR, real time client messaging

by Anthony 16. February 2013 09:48

First I would like to say thank you to David Fowler and all whom have contributed to the SignalR project.  They have really created a fantastic library for real time web communication.  I have been studying up on SignalR and have tinkered with it a bit in preparation for a up and coming project I have.  Long story short, I want to inform users asynchronously of there completed requests for parsing or OCRing a PDF file.  This posed a few issues.

Issue 1.  The server used to parse the PDF file is separate from the web server.

Issue 2. The PDF parser is a Windows Service 

Issue 3. Users do not want to receive e-mails.

Issue 4. Some users want to see all items processed

Okay, so it was a pretty easy decision what to use to send and receive messages.  MSMQ; its free on windows, it is easy to implement in .net, it is asynchronous and it will scale if needed.  That takes care of Issue 1 and 2 as I now have a Queue with which to send and receive messages.  I am not going to go into detail on the MSMQ product as it is well documented.  If you are interested in learning more about it I would suggest this MSDN article.

Now for issue 3; informing the user.  SignalR seemed like a perfect solution.  It uses a publisher/subscriber design pattern to allow multiple clients to connect to a hub and messages are pushed to the open client connections. The easiest way to begin using SignalR is to create an new MVC 4 template project in VisualStudio and add the SignalR NuGetPackage(Microsoft.AspNet.SignalR).  SignalR is still in pre-release so you will need to change your NuGet package manager to "Include Pre-release" or use the package manager console and type:

Install-Package Microsoft.AspNet.SignalR -pre

Either way will work.  Now the fun part. First we need to set up our MSMQ communication.  

MSMQ

MSMQ is a receiver/sender model so we will first need to get messages in the queue.  If you do not have MSMQ installed you will need add it as a windows feature (I am using Windows 7, Windows 8 has a similar interface):

Once installed you will need to open computer management expand the "Service and Applications" you should now see an "Message Queuing" section like the following:

 

Then create a new private queue for creating your messages (you can use a public queue but that requires an Active Directory connection):

The queue should not be transactional as transactions are not required.  (You can read more about transactions in the aforementioned article.)  I am just going to name it "test":

Now the queue is complete and you can added messages.  I've created some helper classes that will perform some of the basic MSMQ interations.  They will be included in the completed project.

Since we will not be creating an actual service we will need to create a page to add messages to the Queue.  The easiest way to do this is to add a new model class and add an action to your controller.  The model class will be something simple like the following:

[Serializable]
public class CompleteMessage
{
    public string CompletionMessage { get; set; }
    public bool Successful { get; set; }
    public string SessionId { get; set; }
    public string ErrorMessage { get; set; }
}

We will call the action CreateTestMessage:

public ActionResult CreateTestMesage()
{
    ViewBag.Message = "Create a message.";
    return View();
}

[HttpPost]
public ActionResult CreateTestMesage(CompleteMessage AddedMessage)
{
    AddedMessage.SessionId = System.Web.HttpContext.Current.Session.SessionID;
    MessageSender.SendMessage(AddedMessage, AddedMessage.SessionId);
    //redirect to a fresh page
    return RedirectToAction("CreateTestMesage");
}

Create a databound view for the action by right clicking inside the action and selecting "Add View...":

 

The selecting the CompleteMessage for the strongly typed view with a scaffold template of "Create":

You will need to remove the SessionId section from the generated cshtml as this will be populated in the action.  You can now run the application and add items to the MessageQueue.

SignalR

Now to inform the user.  First, we will need to add the appropriate hooks for SignalR (the Microsoft.AspNet.SignalR.Sample adds the hooks for you, but we wont be using that in this example. It is however on NuGet in PreReleases.)  I created the SignalR messaging classes in a separate NameSpace/folder.  First you will need to create the "Hub", the hub is how the server communicates back to the server (and visa versa in a WebSocket scenario).  SignalR has really made it easy to create a hub.  Depending on what the client needs to access, the hub can be very small.  I have added a GetAllMessages() method to my hub, but I am not currently using it.

In order for the hub path to be mapped you will need to make one minor change to the Register Routes:

//required for signalR activation.  This should come directly after the IgnoreRoutes
RouteTable.Routes.MapHubs();

This creates the default hub route "/signalr"  this can be changed if you would like.  This is the path used for Client/Server communication

The important part of the hub is the following:

[HubName("msmqHub")]
public class MsmqHub : Hub

The HubName attribute will be used to create a dynamic JavaScript/JQuery communication hub.  This is what you will call from you client.  If you run the application and look at the "hubs" generated JavaScript file, you will see how the communication is performed.  I have highlighted some of the code generated from the created MsmqHub class:

$.hubConnection.prototype.createHubProxies = function () {
        var proxies = {};
        this.starting(function () {
            // Register the hub proxies as subscribed
            // (instance, shouldSubscribe)
            registerHubProxies(proxies, true);

            this._registerSubscribedHubs();
        }).disconnected(function () {
            // Unsubscribe all hub proxies when we "disconnect".  This is to ensure that we do not re-add functional call backs.
            // (instance, shouldSubscribe)
            registerHubProxies(proxies, false);
        });

        proxies.msmqHub = this.createHubProxy('msmqHub'); 
        proxies.msmqHub.client = { };
        proxies.msmqHub.server = {
            getAllMessages: function () {
            /// <summary>Calls the GetAllMessages method on the server-side msmqHub hub.
Returns a jQuery.Deferred() promise.</summary>
                return proxies.msmqHub.invoke.apply(proxies.msmqHub, $.merge(["GetAllMessages"], $.makeArray(arguments)));
             }
        };

        return proxies;
    };

    signalR.hub = $.hubConnection("/signalr", { useDefaultPath: false });
    $.extend(signalR, signalR.hub.createHubProxies());

Now the hub is only the first part.  A class will need to be created to read from the MSMQ Private Queue.  I have written some helper classes for communication with MSMQ so the Watcher class only has a few key parts.

1.  Create the singleton for the class.

//this is the prefered method for setting up a singleton as of .net 4.0
private readonly static Lazy<MsmqWatcher> _instance = new Lazy<MsmqWatcher>(() => new MsmqWatcher());

2. Create the MSMQWatcher.

//create the message queue
private readonly MessageReceiver<CompleteMessage> _msmqReceiver = new MessageReceiver<CompleteMessage>(false);

3. Create the Hub Connection to the clients.

//create a connection to the SignalR hub clients
private readonly Lazy<IHubConnectionContext> _clientsInstance = new Lazy<IHubConnectionContext>(() => GlobalHost.ConnectionManager.GetHubContext<MsmqHub>().Clients);

4. Now that the hub and the watcher is created the last thing to setup is the client script

$(function () {
    //create the hub
    var msmqTicker = $.connection.msmqHub;

    $.extend(msmqTicker.client, {
        sendComplete: function (pdfComplete) {
            //on send complete add to a tag in the dom
            $("#messageRecieved").append(pdfComplete.CompletionMessage + "<br/>")
        }
    });
    //start the client hub
    $.connection.hub.start();
});

If you run the provided sample open 3 windows.  One window in IE 9, one in a recent version of Chrome, Firefox or Safari, and the last in a browser of your choosing.  The reason I wanted you to use IE9 is it uses a different method of server communication than the other browsers.  The non IE Browsers listed support SSE (or Server-Sent Events).  This is the prefered method of communication from server to client when there is no need to communicate from the client back to the server.  

If SSE was not available SignalR would try Web Sockets. If Web Sockets was unavailable (as in IE 9's case) it uses a Comet programming technique  called Forever Frame.  The short definition of "Forever Frame" is a hidden IFrame that maintains a constant open connection to the server, this allows the server to send data back whenever it wants as the connection is never closed (in theory, in practice it will timeout).  And finally, if all else fails, SignalR will default to Long Polling.  NOTE: Long Polling will be used by IE for Cross Domain Support as Forever Frame cannot be used in separate domains.

Luckily, SignalR does all of the heavy lifting.  You don't need to know how it is communicating with the client you just need to know that it is.  Take the following screen shot:

 

IE9 is using Forever Frame and Google Chrome is using SSE, but to the end user it looks exactly the same.  

Now, unfortunately, a few caveats.

  1. SignalR is still a pre-release and I have noticed on GitHub a few people are still having some issues with it, especially where Forever Frames is concerned.
  2. IE 10, Chrome, Safari and Firefox supports Web Sockets and Server Sent Events but IE 9 will need to use Forever Frame or Long Polling.
SignalR by default will use Server Sent Events which is the most efficient push technique but you can override the order in which the transports occur. SignalR s definitely a fantastic edition to the .Net library, and one that I am looking forward to using professionally once it is out of pre-release.
 
All of the code use to create this article can be found in the following download:

MSMQSignalRTest.zip (13.45 mb)

Tags: , , ,

jquery | Message Queuing | MSMQ | MVC4 | SignalR

Baby Steps for Refactoring Web Forms to MVC

by Anthony 26. January 2013 10:58

Refactoring... Uggh, the word that makes most developers cringe.  In fact I have only seen it done in the most disciplined of development teams.  Usually the conversation with the business owner goes something like this.  

Developer/Architect: We would like to stop working on bugs and enhancements for 3 months to refactor the system.

Business Owner: What does that mean?

Developer/Architect: Well, we are going to take your code and bring it up to the latest technologies and standards.

Business Owner: Why is something broken?

Developer/Architect: Umm, no everything is working fine.  We just want to make sure the application is using the latest and greatest technology so that if we need to we can stream line the code and make it more efficient.

Business Owner: Oh so you are going to make it run faster?

Developer/Architect: Not necessarily.

Business Owner: So why are we doing this again?

And so on and so on and so forth...  We don't even let the business know we are refactoring anymore.  We just call it "Maintenance Mode" and be done with it.  But, at most we can squeeze a 6 week release for Maintenance.   So what to do?

Well we usually do partial refactoring.  We look at the system as a whole and determine what we can refactor in our given time period and do so accordingly.  However, MVC introduces a new wrinkle.  It is a complete paradigm shift.  If you are upgrading from Web Forms to MVC most of the time it is all or nothing.  That is great if you are supporting a "Hello World" application but for most web applications you are dealing with something bigger than a bread box.

I am faced with this issue right now in my current position.  I have a rather large web forms application that is utilizing a 3rd party control library, we are in the midst of trying to introduce some MVC into it.  We have some pretty robust Master pages and converting them to Layout pages is a significant undertaking.

What to do?  Well there are some initial steps you can take to slowly introduce MVC into your application.  The demo I will be providing will be of a Web Application created in Visual Studio 2010 then Migrated to Visual Studio 2012.  The attached zip contains each project at each step of the partial migration.

Step 1

Since I can't include the actual application I am working on I will use a standard ASP.NET template application with the template master page.  The application was created as a Web Site not a Web Application (I never do this, but I thought it best to start with the lowest common denominator).

Here is a picture of my website in all of its glory:

Yes I know it is very impressive.  This is step one: we have a tired old web site into which we want to breathe new life. Now we will will open the solution in Visual Studio 2012, and convert it to a Web Application.

Step 2

Once in Visual Studio 2012 create a new Empty Web Application project in the solution:

Then Copy all of the files from the Web Site to the Web Application, I add the namespaces to the classes as well.  My solution now looks as follows:

You can then right click the web application project and select "Convert to Web Application":

This will add all of the designers needed for the application.  Click yes on the dialog:

This concludes step 2 as you have now refactored the 4.0 Web Site to a 4.5 Web Application.  The next step will deal with introducing the various MVC Components.

Step 3

Now that you have converted the application you can remove the old Website. Just right click website and select remove.  This will not delete the site just remove it from the Solution.  Now you can start adding the various items need to support MVC via NuGet:

For this simple project there are only a few that need to be added:

  • JQuery
  • JQuery UI (Combined)
  • Microsoft ASP.NET Razor 2
  • Knockout.js
  • Microsoft ASP.NET Web Pages 2
  • Microsoft ASP.NET MVC 4
  • Microsoft ASP.NET Web Api Core Libraries
  • System.Web.Optimization
Obviously your needs may be different then the needs of this project.  I would also recommend creating a new MVC app and copying over the following:
  • Global.asax
  • Global.asax.cs
  • App_Start (folder)
Once all of the items have been added make sure you add the following ignore routes in the Route Config:
routes.IgnoreRoute("{resource}.ashx/{*pathInfo}");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
 
Also change the default route to:
routes.MapRoute(
    name: "Default",
    url: "MVC/{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
 
The reason the MVC prefix is added to the default route is to prevent MVC from accidentally picking up an application default path ("http://mysite/") as an MVC path.  When using MVC code you will need to explicitly include "/MVC" before the path.
 
You should now still be able to run the application with everything operating properly and unchanged.  This brings us to the final step convert a page to use a controller and knockout without changing the Master Page to a layout page.

Step 4

Add a new folder called "Controllers" and Copy the Web.Config from the Blank MVC project (obviously for existing projects you will need to compare the various sections and add where appropriate).  Then add the following class to the Controller Folder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;


namespace MyNewWebApplication.Controllers
{
    public class DefaultController : Controller
    {
        
    }
}

Now, finally for the good part.  You can either rewrite the existing grid page or create a new one.  I am adding a new one so the pages can be compared. I refactor the page to use knockout.js and my new Default controller.  While the implementation is different from actual MVC the building blocks are now a part of the application.  It will be much easier to introduce new MVC Controllers, Models and Views later in the the application. Here is the new refactored grid:

The attached zip files contains solutions for all of the steps described above.

Step1.zip (150.41 kb)

Step2.zip (6.39 mb)

Step3.zip (14.11 mb)

Step4.zip (14.00 mb)

Tags:

ASP.NET | Knockout JS | MVC4 | nuGet

Please stop pushing JavaScript down my throat.

by Anthony 2. September 2012 09:45

I am primarily a web applications software engineer.  This has been my career path for last 12 of the 17 years I have been working.  That being said, I never overlook the merits of client applications in certain situations (graphically intense, constant connection or the need to integrate with other applications).  I have always found that any code that you have complete control over should keep in mind the following paradigms:

Standard OO principals:

  • Polymorphism: IAnimal -> Mammal -> Dog -> Basset Hound
  • Inheritance: Dog::Eats(){ return “Dog Food”}: Dog overrides Eat From Mammal where it is overridden from IAnimal.
  • Interfacing: IAnimal can be passed around regardless of the type of the inheriting animal.
  • Encapsulation: There is no reason to expose everything to everyone. Something’s should be exposed to the sub classes and (like in life) some things should just be private.

Other important constructs:

  • “Compiled” vs. “Interpreted”: This construct allows programming languages to be compiled down to a lower level language making them run as fast as possible on the target platform.
  • Type Safety (Strongly Typed): Increases performance and reduces runtime errors because the compiler catches issues and optimizes performance for the particular types. NOTE: I incorrectly stated performance is increased with type safety.  This is incorrect, it is a compile time construct and will not increase performance.

Now web applications by default are multiplatform targeted.  They should react the same way on one IE 9 running on Windows as on Chrome running on Mac (they don’t, but bear with me I am getting to the point).  This is where JavaScript excels. Since the actually code is pushed down to the compliant browsers the implementation of that code is left to the browser with guidance of ECMA standards.

I love JavaScript, I love JQuery, I think it is awesome.  But stop trying to make me run it on my servers or on my desktop FOR EVERYTHING.  .Net, Java, C++ all work great as compiled server side languages. Objective C and the previous also work awesome as compiled rich client applications (as long as you know the target system).  So why on earth would I want a language that breaks 3 of my core tenants of programming when I know the target system?

Yes for those that don’t know it let me reiterate JavaScript is not encapsulated, there is no way to mark a method as private. It is certainly not complied (sorry Closure you are an optimizer and calling yourself a compiler is an insult to anyone that has ever built a real compiler).  Finally it isn’t type safe.   I can do the following:

var something = 1; //something is an int
something =  "Ted"; //something is an string
something = function () { return "ted"; } //something is a method pointer
something = 1.34343; //something is a float
something = [1,2,3,4,5]; //something is an array

WOW, something can do anything, and I guarantee the above will run with no issues.  Yes I can do something similar with dynamic types, but there is a time and a place for dynamicity and all the time is not it.  

So when I read about Node.JS used in place of IIS/Apache and JSDB/TaffyDB used in place of Oracle/Sql Server or MySql I shudder a bit.  The only constant theme for why I should do this: is the same language is used client side and server side.  No performance gains (BTW scalability and performance are two completely different dynamics) and no additional features.  Sorry I just can't jump on the bandwagon.

I may sound like a bitter old programmer when I hear the terms "Bandwidth is cheap" or "Processors can handle a lot more these days" or "Just add some more memory/servers".  But why write less efficient code in the the first place.  Always weigh the benefits of performance vs. maintainability.  One should not completely override the other.

Learn PL/TSQL, learn an OO language, learn a server side scripting language(Perl, Python, Ruby), learn JavaScript and learn HTML.  But more importantly, learn when to use each and keep it where it belongs.  To quote my Grandfather, "Just because you can do something doesn’t mean you should."

Tags: , , ,

JavaScript | jquery | NodeJS | OOD | SQL Server

About the author

Family man, developer and gamer... In that order. 

Month List

Calendar

<<  May 2013  >>
MoTuWeThFrSaSu
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar