Archive

Archive for the ‘ASP.NET MVC’ Category

WebSockets vs. SignalR: or why you should not have to care

July 20, 2012 1 comment

Introduction

When the web was founded, it was designed as a system to distribute and update data. If you look at the HTTP protocol you can clearly see these origins. It has commands to GET, UPDATE, POST or DELETE data, but it is always the client (and if we ignore REST, this means in most cases the browser) who takes the initiative. However, the web is changing. It has evolved from a pure data distribution system to an application distribution system. Today, the magic word of IT vendors for this is the ‘cloud’, but in fact this shift to an application distribution system has already started some years ago.

In order to start massively replacing traditional desktop applications, the web needs a new trick: two way communication between browser and server. The back-end must be able to update parts of a web page without user initiative. A definitive technical solution is underway in the form of web sockets, but do we really need to wait until this technology is broadly supported by the browsers of most users? In my opinion, the answer should be a clear NO.

Where SignalR comes in

When there are limitations, people become creative and are able to circumvent the issues blocking them from developing great products. Many popular web applications/sits are already capable of updating their content dynamically, yet they do not rely on web sockets. How is this possible? Because they rely on patterns such as ‘long polling’. With long polling, the browser sends a request for information to the web server with a huge timeout. The web server does not immediately sends data back to the browser, but waits until it has data to send back. When the client receives back data from the server, it will immediately resend a new request to the server.

This long polling pattern and similar patterns give the user the illusion that a persistent two way connection exists between the browser and the web server, but it causes some unnecessary hard work for applicative developers and this is where SignalR comes in for .NET developers. It makes an abstraction of the long polling pattern and gives applicative developers the same illusion as their end users: a persistent two way connection between browser and web server. SignalR takes care of all the details and allows developers to focus on their most important task: building a great application for users.

Because SignalR abstracts the underlying communication protocol, it can both support WebSockets and patterns, such as long polling. This makes an upgrade to WebSockets fairly easy when your organization adopts Windows Server 2012 and your users have moved to modern browsers such as Internet Explorer 10 or recent versions of Firefox and Google Chrome.

Conclusion

As I already wanted to emphasize in the title, comparing WebSockets with SignalR is pointless. Yes, WebSockets is technically superior and will probably give you some extra performance on your server side. But SignalR makes it possible to start developing today the web applications of tomorrow. When WebSockets become broadly available, SignalR will make it possible for you to move away from long polling without a lot of impact on your code.

Categories: ASP.NET MVC, C# Tags: ,

Implementing an HTML5 drag & drop based file upload in ASP.NET MVC 3

May 21, 2012 31 comments

Introduction

HTML5 makes it possible to develop more powerful and more user friendly web applications than we could do ever before. One of the interesting new features is support for drag and drop of files. In the past, if your application needed to provide the possibility to upload files you had to use a file selection chooser. Although this works without issues in all browsers, it is far from user friendly. In native applications, users can interact with files by using drag and drop which is much more intuitive. Luckily for us, HTML5 now also supports this and it is already supported in a number of browsers (Chrome, Firefox, Safari, …).

In this article, I will show you how we can implement drag & drop in an ASP.NET MVC3 web application. We will create a webpage containing a simple drop area that changes of color when the user is dragging a file over the page and we will update the content of the page if the file upload was successful. In order to implement the client side code, we will make use of jQuery and a jQuery plugin called “jquery-filedrop” that simplifies implementing drag & drop based file upload.

You can download “jquery-filedrop” from:
https://github.com/weixiyen/jquery-filedrop

Implementation

We start by creating a new ASP.NET MVC 3 web application and we add the file “jquery-filedrop.js” to the Scripts folder of the project. After this is done we modify the default layout “Views/Shared/_Layout.cshtml” to reference our newly added JavaScript library. In order to do is, add the following line to the head tag.

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

I also choose to upgrade to the latest version of jQuery with NuGet; but this is not strictly required…

Now that everything is in place, we can start writing our applicative code. First create a HomeController and an “Index” view for this controller.

Solution View

In the view we will create a div with the id “dropZone”. This will be the area in which users can drop files. Next, we will write some jQuery code that will make the div “droppable”. Thanks to the jQuery plugin we are using, the required code for this is trivial. We just have to call the method “filedrop” with a number of needed parameters.

For our sample application, we provide the URL for the file upload, the parameter name of the files to be used in the HTTP POST, the maximum allowed number of files that can be upload simultaneously and we will listen to some events to add some dynamic behavior to the page. More specifically, if the user is dragging a file over the page we will change the color of the drop zone and we will update a list of successfully updated files.

@{
    ViewBag.Title = "Index";
}
<style type="text/css">
    #dropZone {
        background: gray;
        border: black dashed 3px;
        width: 200px;
        padding: 50px;
        text-align: center;
        color: white;
    }
</style>
<script type="text/javascript">
    $(function () {
        $('#dropZone').filedrop({
            url: '@Url.Action("UploadFiles")',
            paramname: 'files',
            maxFiles: 5,
            dragOver: function () {
                $('#dropZone').css('background', 'blue');
            },
            dragLeave: function () {
                $('#dropZone').css('background', 'gray');
            },
            drop: function () {
                $('#dropZone').css('background', 'gray');
            },
            afterAll: function () {
                $('#dropZone').html('The file(s) have been uploaded successfully!');
            },
            uploadFinished: function (i, file, response, time) {
                $('#uploadResult').append('<li>' + file.name + '</li>');
            }
        });
    });
</script>

<h2>File Drag & Drop Upload Demo</h2>
<div id="dropZone">Drop your files here</div>
<br/>
Uploaded Files:
<ul id="uploadResult">

</ul>

Now that the view is in place, we can add the required method to our HomeController in order to support the file upload. I choose to call this method “UploadFiles”, it must have a parameter named files (the one we choose in the configuration of our drop zone) and the parameter must be of type “IEnumerable<HttpPostedFileBase>”. In order to keep things simple, we will just write the files to some temporary folder. But of course you can do whatever you want with the uploaded files…

public class HomeController : Controller
{
    private const string TempPath = @"C:\Temp";

    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult UploadFiles(IEnumerable<HttpPostedFileBase> files)
    {
        foreach (HttpPostedFileBase file in files)
        {
            string filePath = Path.Combine(TempPath, file.FileName);
            System.IO.File.WriteAllBytes(filePath, ReadData(file.InputStream));
        }

        return Json("All files have been successfully stored.");
    }

    private byte[] ReadData(Stream stream)
    {
        byte[] buffer = new byte[16 * 1024];

        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }

            return ms.ToArray();
        }
    }
}

Conclusion

Now al what rest us, is pressing F5 and testing the application in a browser that already supports this HTML5 specification. I have tested this in the latest version of Google Chrome and Firefox.

image

As I have shown you, it is very easy to implement file drag and drop behavior into your web application, but of course you will still have to support a legacy mechanism as well for people with older browsers.

You can download my sample from:
https://skydrive.live.com/redir?resid=7A3CD9AFBD57E81E!428

Categories: ASP.NET MVC, C#, jQuery

Using ASP.NET filters with the Ninject Depencency Resolver

Recently, I had an issue activating authorization in an ASP.NET MVC application. No matter what I tried to do, applying the AuthorizeAttribute to my controller methods had no effect. But in a dummy MvcApplication the AuthorizationAttribute worked without issues. After some debugging, I discovered that this was caused by the NinjectDependencyResolver I used to hook Ninject into the ASP.NET MVC stack.

An IDependencyResolver instance is responsible for resolving of all the required components of the ASP.NET MVC stack; it does a lot more than only resolving controllers. At a given moment during then processing of a request, ASP.NET MVC asks the dependency resolver to get all the IFilterProvider instances. Because I had not bound any filter provider to my Ninject kernel, Ninject returned an empty collection. This caused ASP.NET MVC not to use the default filter provider but to use no filter provider at all. Once I detected this behavior, the solution was very simple; I just had to register the default attribute based filter provider in my Ninject kernel.

kernel.Bind<IFilterProvider>().To<FilterAttributeFilterProvider>();

If you only want to use Ninject (or any other IoC container) for resolving controllers, another solution could be not to use an IDependencyResolver but to use an IControllerFactory to hook the IoC container into the ASP.NET MVC stack. This way, the IoC container will only create controller instances and will not interfere with the rest of the ASP.NET MVC stack. Allowing you to use all the ASP.NET MVC defaults.

Categories: ASP.NET MVC, C#, Ninject