Use SignalR to Build Real-Time Connectivity into Your Software

You want to write software that works just like popular social networking sites do, with lively, immediate information. That means building real-time high-frequency updates into your software, because users want their data and they want it now. In some situations, moving data in real-time is essential to the success of the app as it gives an upper hand to the business that does so. Not just that, but let’s face it – it’s cool to be the developer who writes the high tech websites. If you want to build these modern websites and apps with live, two-way communication, then SignalR is something you should seriously consider.

What is SignalR and why should you use it?

SignalR is a set of libraries that facilitate easy development of these kind of real-time websites and apps. It is open source, and you can get it here: GitHub. It works across all the major platforms. SignalR the newest member of the ASP.NET family, that enables developers to write incredibly simple real-time, two-way websites and apps. Two-way communication means that both the server and client share an open channel in which they can initiate contact with each other.  This channel is high-speed and works both directions between server and client. Many kinds of software can benefit from the real-time, two-way, communication system of SignalR. They include high traffic finance and stock apps, auctions, voting, quizzes and polls, lotteries, games, and many more. If your app’s not in the list, you still might want to investigate Signal, as UXs with high-frequency updates tend to be the ones that the users prefer (and rate higher for those in app stores).

SignalR is built to the OWIN specification. OWIN, short for Open Web Interface for .NET, is a set of standards for constructing a pluggable, modular, Web server architectures. Fortunately as SignalR developers, we don’t really need to dig into the specs to write SignalR code, most of the time.

Conceptually, SignalR works like a hub and spoke, or hubs and clients, as we call them. This means that the client can call the server, like we normally see in a HTTP Request-Response model, but now the server can contact the client, and one client can contact other clients (through the server). This is not the kind of programming that web developers usually do. SignalR contains two primary components: Hubs and Clients. Hubs, as you might expect, are server side and they behave a lot like super fast switchboard operators (oxymoron?). Clients, on the other hand, behave the same, except that now they can also receive calls from the server. This is where SignalR differs from customary Web programming, in that both sides can initiate communications between each other once the client initially opens the pipeline.

SignalR uses Websockets technology everywhere that it possibly can, and when it’s not possible, it uses an algorithm to determine the best possible transport. It supports the following transports: WebSockets, Long Polling, Server Side Events, and Forever Frame. As developers, we barely need to know cursory information about these frameworks to benefit from SignalR.

Get Started With SignalR Development

Since SignalR is an ASP.NET product, we’ll need to create an ASP.NET project in Visual Studio (unless you self-host, but we’ll stick with ASP.NET here). You can go with either Web Forms or MVC, as SignalR is also ASP.NET, and it all works together. Then install the “Microsoft ASP.NET SignalR” package into the ASP.NET project, using either the GUI or the Package Manager console. When you install the generic “Microsoft ASP.NET SignalR” package, it installs a few dependencies. Those are both server and client side components that work in tandem so that SignalR can do its thing. You can verify the installation by checking for references to Owin under the project references and jquery.signalr-2.0.3.js and similar files under the Scripts node in Solution Explorer.

Every site needs a starting point, and for SignalR apps, we need to hook into the OWIN pipeline of modular architecture. That means that we need to run a quick bit of code during startup. To do so, put the following code in a class in App_Start. This tells ASP.NET that the SignalR OWIN modules will be part of the regular IIS pipeline. Below is sample startup code for a voting app. The app loads several images and allows users to vote on one or more items.

[assembly: OwinStartup(typeof(VoteR.App_Start.Startup))]

namespace VoteR.App_Start
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

Once we insert the startup code, we can move to our centerpiece of activity, the hub.

Hubs

Hubs enable developers to write code to accept calls from clients and call methods on clients. When many people are voting, the action happen incredibly fast, so it’s a perfect candidate for real-time connectivity. Not to mention that users want to see the vote total updating in real time. Let’s see this in action by examining the VoteHub class. The VoteHub class inherits from the Microsoft.AspNet.SignalR namespace. In this class is the Vote public method that that the clients can call, and when they do, it is syntactically similar to an ASMX Web Service call, meaning that it uses standard dot notation (see the Clients section of this post). The private AddVote method is just a method that public
or other private methods call. It accesses some static members to track which client has the highest bid.

public class VoteHub : Hub
{
    private static List<Item> VoteItems = new List<Item>();
    private static VoteRContext db = new VoteRContext();

    public void Vote(int id)
    {  
        // AddVote tabulates the vote        
        var votes = AddVote(id);
        // Clients.All.updateVoteResults notifies all clients that someone has voted and the page updates itself to relect that
        Clients.All.updateVoteResults(id, votes);
    }
    private static Item AddVote(int id) {

        // If the item is in VoteItems, we’re tracking it, so just increment and return
        var voteItem = VoteItems.Find(v => v.Id == id);       
        if (voteItem != null)
        {
            voteItem.Votes++;
            return voteItem;
        }
        // If the item wasn’t in VoteItems, it’s the first time someone voted for it.
        // Add it to VoteItems and increment from zero
        else
        {
            var item = db.Items.Find(id);
            item.Votes++;
            VoteItems.Add(item);
            return item;  
        }    &nb
sp;  

    }
    public override Task OnConnected()
    {       
        // Send voting history to caller only so they can see an updated view of the votes  
        Clients.Caller.joinVoting(VoteItems.ToList());
        return base.OnConnected();
    }
}

Any custom public method (not overrides) in that you add to your Hub class is callable via dot notation from the client, via a special property. Notice that in the above code sample that there is no need to write code to deal with concurrency or transport negotiation, SignalR does it all for you.

Something that is a bit different from standard web development are the calls to Clients.Caller.joinVoting and Clients.All.updateVoteResults. By accessing the Clients property of the Hub class, we can effectively use that open pipeline to call the joinVoting and updateVoteResults methods on the client using dot notation. You can pass simple or complex arguments, as shown in the code above. SignalR does all the serialization of objects such as the List<T> automatically. Let’s see how to define these methods on the client in JavaScript and how SignalR connects Hub and Client code. The Clients property of the Hub contains the following methods: All, AllExcept, Client, Caller, Group and a few other methods that you can use to send messages to specific clients or groups of clients through the Hub. This gives you a granular way to deal with client-client connectivity.

Clients

When using ASP.NET MVC, we can render some the data on the server in Razor views, and add JavaScript for rich client interactions. Below is a Razor view that loops through an IEnumerable<VoteR.Models.Item> object rendering the name, image, number of votes, and a voting button. After every 4th item, the loop moves to the next row. The <script> tags render at the end of the page. Default.js contains SignalR code that votes on behalf of the user and updates the screen with the current number of votes. Because SignalR is real-time, the current number of votes will be up to date. None of the ASP.NET MVC code is different than we normally write. This is a plain MVC view. We’ll use JavaScript to take data from the view and send to the server.

@model IEnumerable<VoteR.Models.Item>
<h2>Vote!</h2>
<table>
    <tr>
        @{var i = 1; }
            @foreach (var item in Model)
            {
                <td style=”border:1px solid #000; width=”200px”>
                    <h4>@item.Name</h4>< /span>
                    <div><img src=”@Url.Content(item.Image) width=”125″ height=”125″ /></div>
                    <h4>Votes: <span data-itemid=”@item.Id“>0</span></h4>
                    <button id=”@item.Id“>Vote For This</button>
                </td>
                if (i % 4 == 0)
                {
                    @:</tr><tr>
                }
                i++;
            }
        }
    </tr>
</table>

@section scripts {
    <script src=”~/Scripts/jquery-1.10.2.js”></script>
    <script src=”~/Scripts/jquery.signalR-2.0.3.js”></script>
    <script src=”~/signalr/hubs”></script>
    <script src=”~/Scripts/default.js”></script>
}

With script, we first must obtain a connection to the VoteHub and store it in the voteHub variable. Notice the syntax , $.connection, is a static reference. This is a proxy that SignalR automatically creates for us at the /signalr/hubs location. You need do nothing special for the proxy to work.

In the JavaScript below, in the assignment of voteHub property, the $.connection.voteHub part might look like a typo, but SignalR uses camelCasing on the client following popular JavaScript notations. This means that the default manner in which you reference the VoteHub class is voteHub. You can change this by adding the HubName attribute to the Hub class (server side) and specifying the exact name and case of the class, like this: HubName(“VoteHub”). The it changes the proxy to reflect the casing.

After obtaining a connection to the hub, we must start the hub if it isn’t already started. This is a good time to wire up any events such as click events where you’ll be calling hub methods. After wiring up calls to the hub, it’s time to declare methods that the server will call. In the example below, these methods are voteHub.client.joinVoting and voteHub.client.updateVoteResults. Notice their declaration uses the hub.client.method syntax, hanging the methods off of the client property of the reference to the hub. To call code on the server, just use the server property of the client side hub object. In this case, that is voteHub.server.vote. The code passes the value of this.id to the method. “This”, in this case is the button containing the ID of the item the user is voting for.

$(function () {
    var voteHub = $.connection.voteHub;
   
    $.connection.hub.start().done(function () {
        $(“button”).click(function () {
            voteHub.server.vote(this.id);
        });
    });

    voteHub.client.updateVoteResults = function (id, vote) {
        var voteFor = $(“span[data-itemid='” + vote.Id + “‘]”);
        voteFor[0].textContent = vote.Votes;
    }

    voteHub.client.joinVoting = function (votes) {    
        for (i = 0; i <= votes.length – 1; i++) {
            var voteFor = $(“span[data-itemid='” + votes[i].Id + “‘]”);
            voteFor[0].textContent = votes[i].Votes;
        }
    }
});

When a new user connects, the OnConnected method in the Hubs example calls the client side joinvoting and passes in voting history. This way the new voter is current, as joinVoting also displays all the information about all the votes in progress. Examining either the voteHub object or Hub class, you’ll see the server and Clients properties. These are the properties that enable the two-way real-time communication between the hub and the client. All you do is attach public methods to them and make the calls using the hub.server.method syntax. Finally The updateVoteResults method does the UI update, so each item’s <span> element displays how many votes it has.

Conclusion

There are many kinds of websites and apps that can benefit from SignalR’s real-time, two-way, communications model. Perhaps a stockbroker needs financial information to buy the right stock at the right time and get a promotion. Or maybe someone is building the next big thing in social networking and the “likes” need to happen right away. That high-action game that everyone is addicted to needs to be in real-time or people wouldn’t enjoy it as much. If it’s an app, enjoyment and a rich experience translate directly to ratings, which in turn translates to more visibility and revenue.

While in this article I’ve only mentioned Hubs and clients, there is lower level of abstraction that SignalR offers called a Persistent Connection. If you, for whatever reason, need to perform more of the lower level tasks regarding connection management, the PersistentConnection class is what you’d use. If you check out the members of the PersistentConnection class, they look a lot like the Hub class but with more members regarding connectivity. It gives you more gr
anular control, but for most scenarios, hubs and clients will work just fine.

Download sample code: https://github.com/rachelappel/VoteR 

Resources:

ASP.NET SignalR

SignalR.net

Scott Hanselman on SignalR

Upload and download files using ASP.NET MVC

Uploading and downloading files are common functions you’ll see in most websites and apps. Fortunately, it’s easy to write code to upload and download files using ASP.NET MVC. To start, we need a view and controller pair to upload a file. This is the same HTML and MVC code that you already know. However, there is no need for the model portion of the MVC pattern if you are only uploading files to disk and not working with a database. Otherwise, files can be a property of a model, for example, a profile picture.

The upload view

First, we must start in the view by creatingan HTML <form> element. You can create the form with the Html.BeginForm helper and pass in the following arguments, in the following order (for this particular overload signature):

  1. Action method name : Action method that processes uploaded file
  2. Controller name : Controller that belongs to above action method
  3. FormMethod : Any acceptable HTTP verb
  4. enctype : Appropriate encoding type

Using Helpers is a great way to take advantage of built in features of the ASP.NET MVC framework such as accessing routing information to create a link or using strongly typed objects to render HTML. In the case of the Html.BeginForm helper, we are rendering a <form> element. The Html.BeginForm helper expects an enctype attribute that designates that the form can send binary data as well as textual data in the HTTP POST request. Since the default encoding type is “text-plain” the HTTP Request will not send binary data (that means files!) to the server along with the usual textual form data, so you must set the enctype attribute to multipart/form data or it will not work!

Below is a complete sample of an MVC view containing a form with a file input and submit button:

@using (Html.BeginForm("Upload", "Home", FormMethod.Post,
    new { enctype = "multipart/form-data" } ))
 {
    @Html.AntiForgeryToken()

    <fieldset>
        <legend>Upload a file</legend>
        <div class="editor-field">
            @Html.TextBox("file", "", new { type = "file" })
        </div>
       <div class="editor-field">
            <input type="submit" value="Upload" />
        </div>
    </fieldset>
}

ASP.NET Web Forms has a FileUpload Control, but in ASP.NET MVC our options are either a plain HTML element such as <input type=”file” /> or the TextBox and TextBoxFor Html Helpers (or any helper that outputs a file field). Any Html Helper that outputs an <input type=”file”> tag works. In the example above, the type, id, and name attributes of this tag are all set to “file”. A quick look in the browser using the IE Developer Tools illustrates what the Html.BeginForm and TextBox helpers from the above code sample have rendered:

image_thumb2

When the user clicks the submit button, it causes an HTTP POST submission to /Home/Upload, which maps to the Home Controller’s Upload action method. The Upload action method receives the file and form data and from there you can perform the actual upload and save the file to disk or put in the cloud.

The upload action method

Action methods of MVC Controllers accept incoming HTTP requests for processing. Each HTTP request has a certain way, or method (POST GET PUT DELETE etc..) that it sends data to the server. The receiving action method must expect that type of request in order to process it. Since HTTP GET is the default, you must apply the HttpPost attribute to the Upload action method. This, of course, matches the method=”post” attribute of the HTML <form> element.

You can access uploaded files in the action method by querying the argument that is of type HttpPostedFileBase . The name of this argument, “file” in the below sample, must match the name of its corresponding file input in the HTML form (i.e., <input type=”file” name=”file”>). This allows ASP.NET MVC’s model binding to occur for file uploads. Ensuring the names match is using a concept called Convention over Configuration and leads to more readable code.

[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
    try
    {
        if (file.ContentLength > 0)
        {
            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(Server.MapPath("~/App_Data/Images"), fileName);
            file.SaveAs(path);
        }
        ViewBag.Message = "Upload successful";
        return RedirectToAction("Index");
    }
    catch
    {
        ViewBag.Message = "Upload failed";
        return RedirectToAction("Uploads");
    }
}

If you need to upload multiple files, use IEnumerable<HttpPostedFileBase> instead of a single HttpPostedFile and loop through the collection to access individual files. When completing an upload, be sure that you have the correct permissions to write to the directory you want, then use classes from System.IO to access the file system and save the file.

System.IO.Path.GetFileName retrieves a file name including its extension, and System.IO.Path.Combine combines two or more strings to create a complete path. Because we’re working with an uploaded file from HTTP, we need Server.MapPath to map a virtual path (HTTP) to a physical directory (C:\) . In this case the mapping is from the webroot, i.e., “~/” to the <project root>\App_Data\Images directory. I’m saving files to the App_Data directory to demonstrate concepts, but in real world sites it is unlikely that internet users would have privileges to save files there, so check with your sys admin or Web hoster as to where you should upload and download files

The sample code above also overwrites any existing files, so if that’s an issue you can generate a unique file name by spinning up a Guid and using that as the name, as shown here:

var guid = Guid.NewGuid();

If the file to upload is accompanying form data, the controller action method signature should contain the model type and an HttpPostedFileBase type for the file. For instance, if the file is a user’s profile picture and part of a Person model, the action method signature should look like the following:

public ActionResult Upload( Person Person, HttpPostedFileBase file ) {… }

If you are using Convention over Configuration then model binding will take care of everything and all you do is access the method’s arguments.

In order to download, we need the same MVC components – a view and a controller. We’ll start at the controller.

The Download Action Method

Usually the UI presents a list or grid of links or images in which the user can click to download an image or file. What we’ll use for this example is a simple list of links of images to download. We can do this by creating a List<string> to store the file names in hyperlinks for download. The code below shows obtaining the directory and file information and adding the file names to the list of strings. The method then returns the list of strings as a model to the view.

public FileActionResult Downloads()
{
    var dir = new System.IO.DirectoryInfo(Server.MapPath("~/App_Data/Images/"));
    System.IO.FileInfo[] fileNames = dir.GetFiles("*.*");
    List<string> items = new List<string>();

    foreach (var file in fileNames)
    {
        items.Add(file.Name);
    }

    return View(items);
}  

The view accepts the list of strings and displays them in the page.

The Download View

Notice that the model for this view is a List<string> type instead of a custom object as usual. Of course, this the view consists of a simple for loop that cycles through a list of strings containing the file names and displays them in <label> and <a> tags. The hyperlinks render so that they point to the Home controller’s Download action method, and pass in the name of the file as a URL parameter. Cycling through a list of strings means that you can use array syntax (i.e., @Model[i]) to access each member in the list.

@model List<string>

<h2>Downloads</h2>
<table>
    <tr>
        <th>File Name</th>
        <th>Link</th>
    </tr>
    @for (var i =0; i <= Model.Count -1; i++) {
        <tr>
            <td>
                @Model[i].ToString()
            </td>
            <td>
                @Html.ActionLink("Download", "Download", new  { ImageName=@Model[i].ToString() })
            </td>
        </tr>
    }
</table>

The image below is what the download view produces. The ActionLink Helper renders links that point to the Home controller’s Download action method, passing in the image name as a query string. I’m using the defaults but you might want to consider configuring Routing so that the URL looks friendlier.

image

As users click on the download link, the Download action method returns a FileResult:

 public FileResult Download(string ImageName)
{
   
return File(“<your path>” + ImageName, System.Net.Mime.MediaTypeNames.Application
.Octet);
}

However, you can also return a FileContentResult, FilePathResult, or  FileStreamResult (don’t forget to match the action method’s return type to the type you will use):

FileContentResult : Use this when want to use a byte array to access the file. In this scenario, you might have obtained the file as a byte array from a database call.

return new FileContentResult(byteArray, “image/jpeg”);

FilePathResult  : Returns a file on disk when you must access via a file path. In the FilePathResult you can return a File type or a FileStreamResult.

return new FilePathResult(“~/App_Data/Images/” + ImageName, System.Net.Mime.MediaTypeNames.Application.Octet);

FileStreamResult : Sends a stream out to the response.

return new FileStreamResult(new FileStream(“<your path>”, FileMode.Open), “image/jpeg”);

The various ways to return a file are very similar but allow sufficient customizations to meet the needs of most scenarios. Sometimes the file is from a stream or byte array, or sometimes you only have a simple file path. Media types as well as the System.Net.Mime.MediaTypeNames enum are available so you can designate the file type for download, as the above samples demonstrate.

Summary

Code for uploading and downloading files are mandatory tasks for Web developers at some point in time. We want to allow users to safely upload and download files to go along with other data, and using ASP.NET MVC means you can use Html Helpers as an easy way to provide this functionality.

More on the dev tools:

Profile & Tune Web Pages Using IE Developer Tools

Investigate Web Pages Using IE Developer Tools

More on the Razor view engine:

Introducing ASP.NET MVC development w/the Razor view engine

How data annotations for ASP.NET MVC validation work

Data validation is one of the most important aspects of developing applications for the web. However, validation is also something that can get messy pretty quickly, as developers often stick validation code anywhere and everywhere. However, if you keep a clear separation of concerns by using the MVC pattern and couple that with data annotations in the model, then your validation code becomes much simpler to write, maintain, and test. The added bonus: simple code that’s well written & tested is code that’s just going to work.

What are data annotations?

Data annotations are attribute classes that live in the System.ComponentModel.DataAnnotations namespace that you can use to apply to (decorate) classes or properties to enforce pre-defined validation rules. These annotations are available across various Visual Studio 2010 project types including ASP.NET MVC, Web Forms, ASP.NET Apps & Web Sites, Dynamic Data & even non ASP.NET projects like Silverlight & WPF. The same holds true for the data models; you can use these annotations with POCOs (plain old CLR objects), EF models, Linq2SQL models, etc… The bottom line is that you can use data annotations anywhere.

There are several out of the box data annotations to choose from:

  • Required
  • Regular Expression
  • Range
  • ZipCode
  • DisplayName
  • DisplayFormat
  • Scaffold
  • DataType
  • StringLength
  • A few more…

Although having this set of built in validations is great, it is a limited set. Since every business has lots of rules that don’t neatly fit into this pre-defined set of attributes, what do you do when you need to use your own logic? It’s quite easy, really – just derive from any of the inheritable (non sealed) attribute classes in the System.ComponentModel.DataAnnotations namespace, then code your business rules in the derived class methods.

Between the built-in validators and your own custom validation code, you’re all set with maintainable and clean validation. However, server side data sanitization & validation is also equally important. An upcoming blog post will cover creating custom & server side validation. In the meantime, Brad Wilson from the ASP.NET team has some great blog posts on unobtrusive validation along with a a great series of posts on MVC.

And it all starts in the data model…

Applying data annotations to the model.

Suppose a data entry clerk needs to frequently update baked products with baked and expiration dates, amounts, prices, etc… To accomplish this in code, start with a basic POCO class to represent a product and will serve as the data model to meet the needs of this scenario. You’ll need to do more than just create the class and its members though, and that’s where annotations come into play.

Data annotations serve as a way to enforce these common validation scenarios without having to write much code, and more importantly, without writing repetitive code. Annotations live in one place – the model, rather than a code behind, web page, controller, or view. This helps prevent data validation code from turning into Spaghetti# code[1] scattered about your project.

Take a look at the following Product class, complete with a few basic data annotations:

public class Product 
{
public int Id { get; set; }

[DisplayName("Delicious Treat")]
[Required(ErrorMessage = "The product name field is required.")]
public string Name { get; set; }

[Required(ErrorMessage = "The product description field is required.")]
public string Description { get; set; }

[DisplayName("Sale Price")]
[Required(ErrorMessage = "The Sale Price field is required.")]
public decimal Price { get; set; }

[DisplayName("Freshly Baked on")]
[Required(ErrorMessage = "The Freshly Baked On field is required.")]
public DateTime CreationDate { get; set; }

[DisplayName("Don't Sell After")]
[Required(ErrorMessage = "The Expiration Date field is required.")]
public DateTime ExpirationDate { get; set; }

[DisplayName("Qty Available")]
[Required(ErrorMessage = "The Qty Available field is required.")]
[Range(0,120)]
public int QtyOnHand { get; set; }

[DisplayName("Product Image")]
public string ImageName { get; set; }
}

The above properties are labeled with attributes that clearly state their intentions. The bulk of the validation is simply the Required attribute for this sample, along with a Range attribute on the QtyOnHand property. Some attributes such as the DisplayName attribute don’t necessarily validate but do affect the rendered output. As the above sample demonstrates, any combination of necessary attributes can decorate properties. Notice that all the model and validation code so far live in the same place, and will continue to do so when you create custom attributes and validators; meaning that you’ll continue to have a nice, clean separation of concerns in your app.

Once you’re done applying attributes to the model, you can move on to the controllers and views.

Where do views & controllers fit in?

Views:

Once you’ve setup validation on the model using data annotations, they’re automatically consumed by Html Helpers in views so the helpers can render the proper HTML output. For client side validation to work, you will need to ensure that these two <SCRIPT> tag references are in your view:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<
script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script
>

Note: If you’re using ASP.NET MVC 3 project templates, these script tags will be added in views automatically for you by selecting the “reference client script libraries” option in the Add View dialog.

The following code from an edit or insert view will make sure the DisplayName, Required, and Range attributes work at run time.

<div class="editor-field">
@Html.EditorFor(model => model.QtyOnHand)
@Html.ValidationMessageFor(model => model.QtyOnHand)
</div
>

Other helper methods such as @Html.TextBox, @Html.TextBoxFor, @Html.Editor, etc… render nearly identical yet very slim output, explained more later in this post. Views play an integral part in validation, yet as the developer you often won’t need to do much in the view other than use the built-in Html Helpers.

Controllers:

Controllers serve as a gateway to accept HTTP POST requests to process incoming data then to match that data with its model and view for rendering. Controllers shouldn’t be a dumping ground for validation code, server side validation code should be called from controller action methods. While you can put validation code directly into the action methods themselves; the practice tends to lead to code that’s less than optimal to maintain, since you’ve started scattering the code about the project. Rather than having code in multiple locations, think about moving server side validation code to a single location near or in the model, or as its own library project.

How validation works.

Both client and server side validation work because of a few conventions in your project that match up data annotations, Html Helpers, rendered output. Html Helpers in views render HTML elements containing attributes that start with the pattern data-val-*. The data-val-* attributes contain error messages, regular expressions, ranges, and other validation information that originates in data annotations.

That means that this decorated code in the model…

[DisplayName("Qty Available")]
[Required(ErrorMessage = "The Qty Available field is required.")]
[Range(0,120)]
public int QtyOnHand { get; set; }

…combined with this code in the view…

<div class="editor-field">
@Html.EditorFor(model => model.QtyOnHand)
@Html.ValidationMessageFor(model => model.QtyOnHand)
</div
>

…turns into this HTML at runtime…

<div class="editor-field">
<input class="text-box single-line"
data-val="true" data-val-number="The field Qty Available must be a number."
data-val-range="The field Qty Available must be between 0 and 120."
data-val-range-max="120" data-val-range-min="0"
data-val-required="The Qty Available field is required."
id="QtyOnHand" name="QtyOnHand" type="text" value="12" />
<span class="field-validation-valid" data-valmsg-for="QtyOnHand" data-valmsg-replace="true"></span
>
</
div
>

The tie-in between the data model annotations and the data-val-* attributes should be clear after reading the above code, but it’s where the client side validation ties in might not be so obvious. Open the \Scripts\jquery.validate.unobtrusive.js file and search for “data-val”. Right away you’ll see that the JavaScript uses the data-val-*, input-* and field-* CSS classes to display/hide validation messages on the client. Although you shouldn’t modify or need to maintain the built-in .js files; it’s worth investigating them to see how things work together in ASP.NET MVC.

function onError(error, inputElement) {  // 'this' is the form element
var container = $(this).find("[data-valmsg-for='" + inputElement[0].name + "']"),
replace = $.parseJSON(container.attr("data-valmsg-replace")) !== false;

container.removeClass("field-validation-valid").addClass("field-validation-error");
error.data("unobtrusiveContainer", container);

if (replace) {
container.empty();
error.removeClass("input-validation-error").appendTo(container);
}
else {
error.hide();
}
}

Having the onError function tied in by only HTML attributes keeps client side validation unobtrusive, or in other words, out of the way of your view code. Annotations combined with unobtrusive validation make both the view and the output are very clean and maintainable. The final result in the browser is fully capable client side validation that falls back to server side validation for browsers without JavaScript enabled. Either way, the same validation happens and the user sees the same error.

image_thumb2

Summary & Code

Data annotations give you a nice way to keep validation and business logic close to the model, and easier to maintain, test and debug. Additionally, cleaner, simpler output leads to faster download speeds and easier integration with client side script libraries like jQuery for UI manipulation.

Although this post focuses on data annotations and client side script, don’t forget that server side validation is very important.

Download the code.

Notes: [1] Spaghetti# is not a real language.

Integrating ASP.NET Web Forms and ASP.NET MVC

With ASP.NET MVC being a mature platform, many Web Forms developers are wondering whether or not they should move to MVC or are thinking about integrating MVC into their existing Web Forms projects. Web Forms has caught up to MVC in many respects. For example, Web Forms V4+ supports routing, and the controls render less HTML than ever before. ViewState went on a diet and is considerably smaller. In the past some have turned to MVC to address these concerns, but no longer is this the case.

If you’re interested in more content about migrating or integrating Web Forms and MVC, see my WintellectNOW video, “Migrating from Web Forms to MVC”. It covers the many concerns developers face when making the decision about whether or not to migrate to a new technology (and whether or not you should at all). In the meantime, below are some practical tips and techniques required when integrating the two technologies.

MVC Integration: Setup, References, and Configuration

You can install the ASP.NET MVC 4 NuGet package that includes all the resources that you need to use MVC such as references, web.config changes, etc… Once you’ve installed the NuGet package there is little you need to do to use MVC except create folders named “Models”, “Views”, and “Controllers” (assuming you are keeping all these in the same project).

image_thumb3

The NuGet Package adds in several changes to the web.config file as well as references to the project that are worth examining. The web.config sample below shows these references:

Location: <configuration><appSettings>

Configure the ASP.NET Web Pages rendering engine settings in the <appSettings> element.

<appSettings>
  <add key=webpages:Version value=2.0.0.0 />
  <add key=webpages:Enabled value=false />
  <add key=PreserveLoginUrl value=true />
  <add key=ClientValidationEnabled value=true />
  <add key=UnobtrusiveJavaScriptEnabled value=true />
</appSettings>

Location: <configuration><system.web>

This code adds various names
paces to the project’s compilation as well as parser filter and base types, which are settings that determine how views render. The namespace references below are the automatic imports to namespaces for use in views only. You must continue use the using keyword in C# code. The general namespace inclusion is in the previous example.

<pages pageParserFilterType=System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc,
       Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35
       pageBaseType=System.Web.Mvc.ViewPage, System.Web.Mvc,
       Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35
       userControlBaseType=System.Web.Mvc.ViewUserControl, System.Web.Mvc,
       Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35>
  <namespaces>
    <add namespace=System.Web.Optimization />
    <add namespace=System.Web.Helpers />
    <add namespace=System.Web.Mvc />
    <add namespace=System.Web.Mvc.Ajax />
    <add namespace=System.Web.Mvc.Html />
    <add namespace=System.Web.Optimization />
    <add namespace=System.Web.Routing />
    <add namespace=System.Web.WebPages />
    <add namespace=System.Web.WebPages.Html />
  </namespaces>
  <controls>
    <add assembly=Microsoft.AspNet.Web.Optimization.WebForms
     namespace=Microsoft.AspNet.Web.Optimization.WebForms
     tagPrefix=webopt />
  </controls>
</pages>

Location: <configuration><system.webServer><handlers>

These are the ASP.NET runtime HTTP handlers. They are what determines which .dlls service which type of requests at a low level. As demonstrated, these handlers are looking to interact with HTTP via verbs.

<handlers>
  <remove name=ExtensionlessUrlHandler-ISAPI-4.0_32bit />
  <remove name=ExtensionlessUrlHandler-ISAPI-4.0_64bit />
  <remove name=ExtensionlessUrlHandler-Integrated-4.0 />
  <add name=ExtensionlessUrlHandler-ISAPI-4.0_32bit path=*.
       verb=GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS modules=IsapiModule
       scriptProcessor=%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll
       preCondition=classicMode,runtimeVersionv4.0,bitness32 responseBufferLimit=0 />
  <add name=ExtensionlessUrlHandler-ISAPI-4.0_64bit path=*.
       verb=GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS modules=IsapiModule
       scriptProcessor=%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll
       preCondition=classicMode,runtimeVersionv4.0,bitness64 responseBufferLimit=0 />
  <add name=ExtensionlessUrlHandler-Integrated-4.0 path=*.
       verb=GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS type=System.Web.Handlers.TransferRequestHandler
       preCondition=integratedMode,runtimeVersionv4.0 />
</handlers>

Location: <configuration><runtime><assemblyBinding>

Of course if you’re dealing with differing versions of .NET for any type project, you must change assembly bindings. Assembly bindings declare which versions of which libraries to reference in the project. VS will compile against the new redirected binding than the default when you use the settings below:

<dependentAssembly>
  <assemblyIdentity name=System.Web.Helpers publicKeyToken=31bf3856ad364e35 />
  <bindingRedirect oldVersion=1.0.0.0-2.0.0.0 newVersion=2.0.0.0 />
</dependentAssembly>
<dependentAssembly>
  <assemblyIdentity name=System.Web.Mvc publicKeyToken=31bf3856ad364e35 />
  <bindingRedirect oldVersion=1.0.0.0-4.0.0.0 newVersion=4.0.0.0 />
</dependentAssembly>
<dependentAssembly>
  <assemblyIdentity name=System.Web.WebPages publicKeyToken=31bf3856ad364e35 />
  <bindingRedirect oldVersion=1.0.0.0-2.0.0.0 newVersion=2.0.0.0 />
</dependentAssembly>

After configuring the project to incorporate MVC, you’ll need to setup routing.

Controllers and Routing

Routing is an essential component of MVC development, and MVC cannot work without it. In Web Forms V4 and later, routing is baked right in. What you’ll need to do to ensure the proper routes are set is to create a static RouteConfig class, preferably in a file (e.g., RouteConfig.cs) inside the App_Start special folder. After that, add in the code below to assign a generic route.

routes.MapRoute(
    name: “Default”,
    url: “{controller}/{action}/{id}”,
    defaults: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional }
);

Of course, the RouteConfig class won’t instantiate itself. That means you must call its RegisterRoutes function (also static) from the Global.asax.cs file like so:

void Application_Start(object sender, EventArgs e)
{
    RouteConfig.RegisterRoutes(RouteTable.Routes);
}

The last thing to do is use MVC conventions to create the appropriate folders for Models, Views, and Controllers, if you haven’t already. Otherwise, structure your project as you would for use with the MVC pattern, perhaps moving models to their own class library or service layer.

Considerations when integrating Web Forms and MVC

DataSets/DataReaders & Models:

A lot of data is accessed by Web Forms via declarative tags like the <asp:SqlDataSource>, as well as volumes of DataSets and DataReaders in the code behind files. You’ll need to find a strategy for converting these to models, i.e., classes. Some Web Forms projects contain POCOs for models and those often port over quickly. By convention (assuming a single project), model files live in the <ProjectRoot>\Models folder and model classes in the <Project>.Models namespace.

ASPX & Views:

ASP.NET MVC ships with two view engines: Web Forms (ASPX) and Razor. The ASPX view engine continues on using the classic <%# %> syntax for code delimiters, while Razor uses only the @ symbol (or @{}) as a way to denote the start of of code. Razor uses a new parsing engine first introduced in ASP.NET Web Pages that produces clean and concise HTML output. However, if you have a team strong in Web Forms they may want to continue using Web Forms syntax. The difference worth mentioning is that the ASPX view engine uses the traditional Web Forms rendering under the hood so technically it builds a control tree and renders it. You just can’t access the elements in MVC views like you can in a Web Forms page by referring to a control as an object in the code behind. This makes Razor much faster as there is no tree to render. In  views, code renders inline, or in placeholders, rather than from scripted code in a code behind. This is a drastic enough difference that you’ll probably need to completely rewrite many Web Forms as MVC views, as opposed to simply reusing pages in MVC. Of course, redoing all pages as views all at once is often not an option because of time and budget, but you can move them one by one.

Any would be controls in MVC become Html helpers. Html Helpers are the cornerstone of ASP.NET MVC views. Like controls, the Html Helpers render chunks of browser friendly output, but helpers emit the least amount of code as possible and in the least obtrusive way. Helpers also accept and render data from the model. This means if you have 3rd party controls, you might want to migrate these pages last or weigh the option of leaving them as Web Forms. This, of course, depends upon the cost-benefit of the developer’s time to build a control vs. buying a new version of one, if one is available. Most popular 3rd party vendors are up to date.

Code Behind Files & Controllers:

It is not uncommon to see a Web Forms code behind file with 5,000+ lines of code. That’s a lot of code for one single Page object. It also makes the page object a Swiss army knife of sorts as Page objects deal with building the UI and doing all sorts of other things. Many developers add CRUD operations directly in the code behind. This page of all trades ends up doing all the chores and this means more complex code and code that is tightly coupled.

MVC leans toward a concept called Separation of Concerns in which each part of the MVC pattern maps to a concern. M for models or data and CRUD operations. V for views or UI. C for controllers or operational code. All the layers are nicely separated. If your Web Forms code is getting a bit unruly or spaghetti-like then MVC could address and fix some of your maintenance issues by breaking out components into manageable units, or concerns.

Controllers of course make the calls to Web services to retrieve JSON or XML data or directly to the database, a repository, or any number of options. Controllers also do the work of determining how HTTP requests are handled. This responsibility falls to the code behind in Web Forms.

ASP.NET Core:

Since it’s all ASP.NET, you get to share core features such as sessions, caching, globalization, Forms authentication between Web Forms and MVC.

Summary

Fortunately assets like images, CSS, and custom JavaScript are all reusable between Web Forms and MVC projects. Just keep the ID and NAME attributes the same (which you want anyway for consistency). As you can see, both technologies are ASP.NET so they can live harmoniously and even compliment each other.

As you can see, with just a few modifications to a Web Forms project and you can start adding MVC components. You can run both Web Forms and MVC or work toward doing a complete migration.

Use ViewModels to manage data & organize code in ASP.NET MVC applications

The concept of the ViewModel isn’t just for ASP.NET MVC, as you’ll see references to ViewModels throughout the web in articles and blog posts about the MVC, MVP, and MVVM patterns. Those posts and articles can center around any number of technologies such as ASP.NET, Silverlight, WPF, or MVC… This post will investigate ViewModels as they apply to the world of ASP.NET MVC.

What is an ASP.NET MVC ViewModel?

In ASP.NET MVC, ViewModels allow you to shape multiple entities from one or more data models or sources into a single object, optimized for consumption and rendering by the view. The below image illustrates the concept of a ViewModel:

 

image_16

The purpose of a ViewModel is for the view to have a single object to render, alleviating the need for UI logic code in the view that would otherwise be necessary. This means the only responsibility, or concern, of the view is to render that single ViewModel object, aiding in a cleaner separation of concerns (SoC). Concerns are distinct aspects of the application that have a particular purpose (i.e., concern), and keeping these aspects apart means your application is more organized, and the code more focused. Putting data manipulation code in its own location away from the view and controller, enforces SoC.

Using ViewModels in MVC for finer granularity and better SoC leads to more easily maintainable and testable code. Remember, unit testing is about testing small units.

Along with better coding practices, there are many business reasons demonstrating why you might consider using ViewModels:

  • Incorporating dropdown lists of lookup data into a related entity
  • Master-detail records view
  • Pagination: combining actual data and paging information
  • Components like a shopping cart or user profile widget
  • Dashboards, with multiple sources of disparate data
  • Reports, often with aggregate data

The above scenarios are common to a wide variety of applications, and deal with more complex data than basic CRUD forms-over-data page (e.g., a simple 1:1 mapping to the db table). For example, providing a list of states, and ensuring that the state that matches the state of current customer, means that you need to either provide two sets of data or a single set of customer/state data combined, as shown in the image below.

 

image_6

Some scenarios such as a lookup table representing states in the USA, could easily work with either ViewModels or a ViewBag/ViewData object, so there is some potential overlap at times. It’s up to the application architects and developers to decide what works best with their exact use case.

Creating a ViewModel

Although a ViewModel consists of multiple entities, at its core a ViewModel is still just a class – and one that doesn’t even inherit from anything special, as many MVC classes do.

Physically, ViewModels can exist in different locations, listed below:

  • In a folder called ViewModels that resides in the root of the project. (small apps)
  • As a .dll referenced from the MVC project (any size app)
  • In a separate project(s) as a service layer, for large applications that generate view/content specific data. (enterprise apps)

Since a ViewModel is just a class, the easiest way to get started using one is to create a new folder named ViewModels and add a new code file to it.

To create the CustomerViewModel ViewModel, add the Customer and StatesDictionary types as properties to form one CustomerViewModel class. In the example below, the CustomerViewModel class contains the newly defined properties.

public class CustomerViewModel 

{

    public Customer Customer { get; set; }

    public StatesDictionary States { get; set; }

    public CustomerViewModel(Customer customer)

    {

        Customer = customer;

        States = new StatesDictionary();

    }

}

Generally, ViewModels contain the word “ViewModel” as part of its name; however, the conventions at work here are for consistency in code readability, since other classes in MVC state their intents in their names as well (e.g., names of controllers, action methods, etc…use conventions in their names).

The StatesDictionary class is a simple Dictionary object containing two type parameters of type string. The class also contains the definitions for all the members in the Dictionary (i.e., the state data). The only property in the StatesDictionary class is the StateSelectList, which is an object that Html Helpers use with to render an HTML <select> element that displays a listing of states. The type Dictionary<string, string> in the StateSelectList property maps to the state abbreviation then state name, respectively.

public class StatesDictionary

{

    public static SelectList StateSelectList

    {

        get { return new SelectList(StateDictionary, "Value", "Key"); }

    } 

    public static readonly IDictionary<string, string> 

        StateDictionary = new Dictionary<string, string> { 

      {"Choose...",""}

    , { "Alabama", "AL" }

    , { "Alaska", "AK" }

    , { "Arizona", "AZ" }

    , { "Arkansas", "AR" }

    , { "California", "CA" }

    // code continues to add states...

    }; 

}

Data that lives in small lists and infrequently changes, like the StatesDictionary class, exists in all types of applications. In real world applications, you’ll find a variety of methods for dealing with lookup data such as a list of states – often XML files and SQL tables. You can replace the code in the StateDictionary method to use entities from Entity Framework, read data from files, or any data access code that you require.

After creating the ViewModel, the next steps are to instantiate it in a controller and return it to the view.

Getting the ViewModel to the view

Starts with the controller…

Sending a ViewModel to the view for rendering will work the same as when dealing with a model. Since it’s just a class, the view doesn’t know, and doesn’t care, where the model or ViewModel came from. You can create the instance of the ViewModel class in the controller, or resolve it if using an IoC container. Remember that just as you would do with views, you should keep controllers clean of unnecessary code, meaning that only code that fetches the model or ViewModel belongs here, and little more.

public ActionResult Edit(int id)

{

    Customer customer = context.Customers.Single(x => x.Id == id);

    var customerViewModel = new CustomerViewModel(customer);

    return View(customerViewModel);

}

Then the view renders the ViewModel…

In order for the view to know what object to use, set the @model keyword to point to the ViewModel, just like you already would with a regular model.

@model FourthCoffee.Web.ViewModels.CustomerViewModel

Because the Customer object is a property of the ViewModel, you’ll see the model.Class.Property syntax to access the ViewModel data, similar to the following line of code.

<div class="editor-label">

    @Html.LabelFor(model => model.Customer.FirstName)

</div>

<div class="editor-field">

    @Html.EditorFor(model => model.Customer.FirstName)

    @Html.ValidationMessageFor(model => model.Customer.FirstName)

</div>

@* ...View code continues rendering properties... *@

Additionally, you can edit the Edit/Create views so that the DropDownList containing a list of the states will display, and display the correct state matching that of the customer.

<div class="editor-field">    

    @Html.DropDownList("state", new SelectList(StatesDictionary.StateSelectList, 

                       "Value", "Text", Model.Customer == null ? "" : Model.Customer.State))

    @Html.ValidationMessageFor(model => model.Customer.State)

</div>

As you might have noticed, using a ViewModel is just as easy as using the ViewBag or ViewData objects. ViewModels, however, provide those extra benefits like being easier to test and optimize.

Checking the results

After a user navigates to the /Customers/Edit/1 URL in the browser, the Razor view engine renders the CustomerViewModel similarly to the following screen shot.

image_4

The State DropDownList displays the states and the current state for that customer, as expected.

Digging Further into ViewModels

Because ViewModels render pre-manipulated data that no longer have those 1:1 mappings between model classes and database tables, you’ll need to do create mappings yourself. You can manually map small ViewModels, but this will quickly become burdensome when mapping larger classes, especially when working with parent-child-grandchild, multi-level, or complex data. This is where a tool such as AutoMapper comes into play. AutoMapper will let you fluently setup mappings between ViewModels and models more easily than doing so manually, or writing your own mapper.

Here are some tips for using ViewModels:

  • Put only data that you’ll render in the ViewModel.
  • The view should direct the properties of the ViewModel, this way it fits better for rendering and maintenance.
  • Use a mapper when ViewModels become complex.

Some tools that can help assist you in generating POCOs (Plain Old CLR Objects) for models and ViewModels are:

POCO Generator

EF POCO Templates

In addition to these tools, you can use MvcScaffolding to create actions and views based on ViewModels. MvcScaffolding, invention of ASP.NET team member Steve Sanderson, gives you more power in creating CRUD, repository, unit test and other templates quickly and painlessly. Check out Steve’s Multi-part series on MvcScaffolding here. MvcScaffolding works with ViewModels as well as models.

You should always prefer using a ViewModel rather than instantiating multiple models and putting that manipulation code in the controller.

Summary

ViewModels help you organize and manage data in MVC applications when you need to work with more complex data than the other objects allow. Using ViewModels gives you the flexibility to use data as you see fit. ViewModels area generally a more flexible way to access multiple data sources than models + ViewBag/ViewData objects.

Further reading: Comparing the MVC and MVVM patterns along with their respective ViewModels

Download the code!