Getting Started With Glimpse In ASP.NET MVC

25. June 2013 22:43

ASP.NET ASP.NET MVC 

When I heard about Glimpse, I thought it like to be another MiniProfiler like stuff or a combination of MiniProfiler and this. But it seems to be more robust diagnostic tool for developers. Here is my experience with this awesome diagnostic tool.

What is Glimpse?

Glimpse is a diagnostic tool for ASP.NET applications which let you see detailed diagnostic information of your web application. Glimpse knows everything your server is doing and displays it straight away to you in your browser. Currently Glimpse is supported for ASP.NET – Web Forms and MVC and PHP and other languages are in queue as well. If you want to contribute to the project as it is open-source, you can contact the project developers here. The Glimpse project is still under development and there are more that 70 bugs reported at Github.

Getting Glimpse & Getting Started

I have used MiniProfile in the past and the major difference between the two tools I noticed is that in MiniProfile you have to make changes in the code to profile or view the diagnostic information. On the other hand Glimpse is just simply plug and play library. If you are going to give Glimpse a try make sure that you use NuGet to get the library. Glimpse comes with lots of configurations and setting them out manually in the application will be a pain just like ELMAH. As we are now living in post-NuGet era, we must use the power of NuGet to do all the hard work and configuration for us. You can get Glimpse depending on the type of project you have. To add Glimpse in MVC application fire the below NuGet command.

PM> Install-Package Glimpse.MVC

For Web Forms

PM> Install-Package Glimpse.ASP

After the command gets completed, take a look at the web.config file where you can see all the configurations. Without paying more attention to the configs, run the application to see Glimpse in action. Unlike MiniProfiler, there were no changes in the code. Before you can actually see Glimpse in action you have to turn it on, and to turn Glimpse on navigate to the URL http://localhost:XXXX/glimpse.axd 

A cookie is set when Glimpse is turned on. This cookie tells the server to send the diagnostic data to the application. Here is how it looks on my home page.

The above screenshot gives you a summarized information of what your application and server is doing. The summary part is distributed in three parts i.e. HTTP, HOST and AJAX. The HTTP segment shows the summary of the diagnostic information that flows over HTTP. In the HOST segment you can also see the name of the controller and action name. AJAX segment shows zero count as there are no AJAX call yet in my application which communicates with the server. This is just a summary which is visible at the bottom right hand corner of the web page. To view more detailed diagnostic information hover the mouse over any of these segments and you get one level more information.

If this is not enough for you then click on the big g icon at the bottom right corner.

The screenshot above just covering one tab out of 12 tabs which have complete diagnostic information about the application.

What else it can do?

Glimpse has extensions that will let you get information about EF, nHibernate, Ninject and many more. You can view the complete list of extensions here which you can use to see what these libraries are doing behind the scenes. Check out the complete list of extensions here.

Moving to production

Glimpse is a diagnostic tool and is very powerful from a developer’s perspective. When moving the website or web application to the production servers, no developer would want to leave Glimpse working on the landing page of your site. So before you move to production you have to turn Glimpse off. To turn off Glimpse you can navigate to the same URL which you have used earlier to turn it on. This is the easy option available, but anyone with the Glimpse handler URL can easily turn it on!? The best approach is to change the setting in the web.config file, so even if the third person has the URL of the Glimpse handler he will never be able to turn it on. To turn off Glimpse permanently set defaultRuntimePolicy to Off. The line in your web.config after the change will look like this.

<glimpse defaultRuntimePolicy="Off" endpointBaseUri="~/Glimpse.axd">

Once this property is set to Off, there is no way a user can turn Glimpse on without changing its value back to On. Glimpse has a lot more options to explore which I can’t cover in single blog post. I am looking forward on using some extensions now for Ninject and Entity Framework.

References:

 No Rating

HTML5 Video - Capture And Upload Image To Azure Storage

2. June 2013 23:46

ASP.NET Cloud HTML5 Web Azure 

I was exploring Github for some image effects/filters and I found some but still keep exploring and found an interesting plugin called face-detection. This plugin uses HTML5 getUserMedia to use your web camera only if your browser supports it. Unfortunately, IE10 still doesn’t support it. This seems cool to me, so I created a sample application to test it. This sample application will let you preview the video using your web camera and allows you to capture the image from your web camera and upload  it to the Azure storage. The javascript code for the HTML5 video I am using is from David Walsh’s post. Not every browser supports getUserMedia, so if the user is not using the browser which supports getUserMedia then you can show an alert message to the user notifying about the browser incompatibility. Here is the function which will check your browser compatibility for getUserMedia.

function hasGetUserMedia() {
 // Note: Opera is unprefixed.
 return !!(navigator.getUserMedia || navigator.webkitGetUserMedia ||
 navigator.mozGetUserMedia || navigator.msGetUserMedia);
}
 
if (hasGetUserMedia()) {
 // Good to go!
} else {
 alert('getUserMedia() is not supported in your browser');
}

To know more and explore more what you can do with getUserMedia visit HTML5Rocks. Moving further, I have a normal HTML page where initially I am placing 3 elements on the page. One is a video tag which will show the stream from the web camera attached to your machine or your laptop camera. Second, is the canvas tag which is used to show the image captured from the web camera and the third one is the normal button which will let me capture the image at my will on its click.

<video autoplay id="video" width="640" height="480"></video>
<input id="snap" type="button" value="Click" />
<canvas id="canvas" width="640" height="480"></canvas>

Notice the autoplay property in the video tag. I have set it because I don’t want the video to be frozen as soon as it started. To make the video work I am using David Walsh’s code as it is without any changes.

window.addEventListener("DOMContentLoaded", function () {
    // Grab elements, create settings, etc.
    var canvas = document.getElementById("canvas"),
        context = canvas.getContext("2d"),
        video = document.getElementById("video"),
        videoObj = { "video": true },
        errBack = function (error) {
            console.log("Video capture error: ", error.code);
        };
 
    if (navigator.getUserMedia) { // Standard
        navigator.getUserMedia(videoObj, function (stream) {
            video.src = stream;
            video.play();
        }, errBack);
    } else if (navigator.webkitGetUserMedia) { // WebKit-prefixed
        navigator.webkitGetUserMedia(videoObj, function (stream) {
            video.src = window.webkitURL.createObjectURL(stream);
            video.play();
        }, errBack);
    }
 
    // Trigger photo take
    document.getElementById("snap").addEventListener("click", function () {
        context.drawImage(video, 0, 0, 640, 480);
    });
}, false);

In the above script, you can see that it first checks if the browser or navigator has the getUserMedia support. if you see there are two conditions one for the standard and other one with the webkit prefix. In the end, the click event on the button which will let me capture the image.

When you view the application in the browser, the browser will prompt you whether you want to allow or deny the application to use the web camera.

You cannot run this just by double-clicking the file due to security reasons. You must access the web page from the server itself, either from within the Visual Studio development server, from IIS or by publishing the file on your production server. It can be annoying for many users to grant the access to the camera every time they access the page. You can save the user consent if you are using https. If you plan to stick with http, you will not be able to do this.

Looking in the address bar again, you will notice that the fav icon of the web application, changed to an animated icon. It is a little red dot which keeps on flashing notifying the user that the camera is in use. If you plan to block the access to the camera permanently or temporarily, you can then click the camera icon which is on the right hand side of the address bar.

When you click the icon you will be prompted with options to continue allow the access to the camera or always block the camera. Also if you notice the camera option, you will see that it is showing me two devices or camera attached to the machine. I build this application on my laptop so I am able to the integrated camera which is the front facing camera of my laptop and the second one is the USB camera I have plugged on my laptop’s USB port. I can choose to use any one of these. If you make any changes to these settings and click on done, you will be asked to reload the page.

This is how my web page looks.

The click button is at the bottom right hand side will let me take a snap of the feed coming from my camera. When I click the Click button, the image is captured and show on the canvas we have added on the page. This is my web page after I took the snap from my web camera.

The second image (at the bottom) is the image on the canvas that is snapped from the camera. Now I want to upload the image to my Azure cloud storage. If you look at the address bar, you’ll notice that I have used normal HTML page. It’s you wish if you want to use a simple HTML page or a web form. Both works good. The problem I am going to face with web forms is if I am going to upload the snapped image to my cloud storage or to my server repository, the page will post-back which is not cool at all. So I am going to accomplish it by making an AJAX call. Add a HTML button to your page and on its click event upload the file to the cloud.

I have the image on my canvas, therefore you just cannot retrieve the image Base64 string just like that. I am going to extract the Base64 string of the image from the canvas and pass it as a parameter. The server method will then convert the Base64 string to stream and upload it to the cloud storage. Here is the jQuery AJAX call.

function UploadToCloud() {
    $("#upload").attr('disabled', 'disabled');
    $("#upload").attr("value", "Uploading...");
    var img = canvas.toDataURL('image/jpeg', 0.9).split(',')[1];
    $.ajax({
        url: "Camera.aspx/Upload",
        type: "POST",
        data: "{ 'image': '" + img + "' }",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function () {
            alert('Image Uploaded!!');
            $("#upload").removeAttr('disabled');
            $("#upload").attr("value", "Upload");
        },
        error: function () {
            alert("There was some error while uploading Image");
            $("#upload").removeAttr('disabled');
            $("#upload").attr("value", "Upload");
        }
    });
}

The line 4 in the above script is the one which will get the Base64 string of the image from the canvas. The string is now in the variable named img which I am passing as a parameter to the Upload web method in my code-behind page. You can use web service or handler or maybe a WCF service to handle the request but I am sticking with page methods. Before you can actually make use of the Azure storage, you have to add reference of the Azure Storage library from NuGet. Fire the below NuGet command to add the Azure Storage reference to your application.

Install-Package WindowsAzure.Storage

After the package/assemblies are referenced in your code, add the below namespaces.

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage.Auth;
using System.IO; //For MemoryStream
using System.Web.Services; //For WebMethod attribute

These all the namespace will help me to connect to my local cloud storage emulator or to my live cloud storage. This is my upload method which will upload the file to my live cloud storage.

[WebMethod]
public static string Upload(string image)
{
    string APIKey = "LFuAPbLLyUtFTNIWwR9Tju/v7AApFGDFwSbodLB4xlQ5tBq3Bvq9ToFDrmsZxt3u1/qlAbu0B/RF4eJhpQUchA==";
    string AzureString = "DefaultEndpointsProtocol=https;AccountName=[AccountName];AccountKey=" + APIKey;
 
    byte[] bytes = Convert.FromBase64String(image);
 
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(AzureString);
 
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
 
    CloudBlobContainer container = blobClient.GetContainerReference("img");
 
    string ImageFileName = RandomString(5) + ".jpg";
 
    CloudBlockBlob imgBlockBlob = container.GetBlockBlobReference(ImageFileName);
 
    using (MemoryStream ms = new MemoryStream(bytes))
    {
        imgBlockBlob.UploadFromStream(ms);
    }
 
    return "uploaded";
}

I have decorated this method with WebMethod attribute. This is necessary as I have to call this method from jQuery/javascript. Also the method should be public static. The AzureString  serves as the connection string for the cloud storage. You have to change the [AccountName] in the connection string to the storage account name. In my case it is propics. The method accepts the Base64 string as a parameter.

Storage is something different than that of the container and therefore I have to create a container which actually holds my images which I upload to the cloud storage. I am not explaining the code completely but it is not that complicate. To upload the file to the storage I must have a file name. The image I get from the canvas is just a Base64 string and does not have a name, so I have to give it a name. I have a random function which will generate the random string which I will be using as a file name for my image file.

//stole from http://stackoverflow.com/questions/1122483/c-sharp-random-string-generator
private static string RandomString(int size)
{
    Random _rng = new Random();
    string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
    char[] buffer = new char[size];
 
    for (int i = 0; i < size; i++)
    {
        buffer[i] = _chars[_rng.Next(_chars.Length)];
    }
 
    return new string(buffer);
}

This is a small function which I stole from Stackoverflow to generate random name for my image file. So this is it and when I click the upload button on my page.

Now if I check my cloud storage I have can see the uploaded files.

This is just a simple example to get you started. You can give some cool effects before you can actually upload the files. If you do a quick search you’ll find plenty of links which will let you give some cool effects to your pictures. I came across a brilliant plugin called filtrr. You should try it and come up with something which is awesome or may be something like Instagram. Hope this help some folks out there.

References:

 No Rating

Attribute Routing In MVC

26. August 2012 14:33

ASP.NET ASP.NET MVC Web 

I took a look at Stack Overflow Stack-Exchange Data Explorer that is built in MVC and is open-source application to query the Stack Exchange data dump that is being provided by Stack Exchange team in every month or few. I do have a dump, but I was more curious to know about the application that they built to query the database. And I must admit that I learned tons of things. I came to know the power of Micro-ORM (Dapper) over Entity-Framework (EF) and one more pretty thing that attracted me was the routing mechanism used in the application. I strongly recommend that you check out this tool/application and take a deep dive in the code, lot of things to learn.

Before we start writing the code, we'll take a quick look at a NuGet package AttributeRouting. You can find the source code at GitHub in case if you are interested. The documentation is simple and explains almost every bit of the package. It's incredibly easy.

The NuGet package I am using is for MVC, if you want to do the same with your Web API application then use this package.

To see how easy it is to implement routing in your MVC application. Start Visual Studio and create a new MVC4 (Internet) application and fire up the below NuGet command.

This command just don't install one single package but also some other dependent packages. Here is the output when I fire the above NuGet command:

PM> Install-Package AttributeRouting
Attempting to resolve dependency 'AttributeRouting.Core (≥ 2.5.1.0)'.
Attempting to resolve dependency 'AttributeRouting.Core.Web (≥ 2.5.1.0)'.
Attempting to resolve dependency 'WebActivator (≥ 1.0.0.0)'.
Successfully installed 'AttributeRouting.Core 2.5.1.0'.
Successfully installed 'AttributeRouting.Core.Web 2.5.1.0'.
Successfully installed 'WebActivator 1.0.0.0'.
Successfully installed 'AttributeRouting 2.5.1.0'.
Successfully added 'AttributeRouting.Core 2.5.1.0' to MVCAttrRouteTest.
Successfully added 'AttributeRouting.Core.Web 2.5.1.0' to MVCAttrRouteTest.
Successfully added 'WebActivator 1.0.0.0' to MVCAttrRouteTest.
Successfully added 'AttributeRouting 2.5.1.0' to MVCAttrRouteTest.

Now before you make any changes to the web application, hit CTRL+F5. Hover or click on the links which are on the top which are About and Contact. The URL rendered in the address bar is something like this (as what specified in your application Global.asax file).

For About View:

/Home/About

For Contact View:

/Home/Contact

The Home that we see here is the name of the controller being used. I don't want the name of the controller to be visible to my site visitors or maybe I just want a different name there. Usually, I would have switch to my application Global.asax file and register a new route there. But now I can now control my routes within controller itself. This is pretty cool for and a time saver, as I do not have to avoid working with Global.asax. This is the simplest implementation of AttributeRouting. Below are the 2 Home controller methods About and Contact:

[GET("About")]
public ActionResult About()
{
    ViewBag.Message = "Your app description page.";
    return View();
}

[GET("Contact")]
public ActionResult Contact()
{
    ViewBag.Message = "Your contact page.";
    return View();
}

There are no changes in the method, only the routing attribute has been added. The URLs for About and Contact are now free from the controller name Home. Now we look at a second condition where I want to have a totally different URL for About view or to be specific I would say I want to have outbound URLs and this will require RouteName property with the routing attribute. This is called Named Routes. I am going to change the URL to /App/AboutMe.

[GET("App/AboutMe", RouteName = "About")]
public ActionResult About()
{
    ViewBag.Message = "Your app description page.";
    return View();
}

Working with parameters without routing can lead to very ugly URLs or some un-wanted params in the URLs. Again to have a clean URL we can handle the parameters passed to the controller action. I have added a new view named Welcome (no scaffolding) in the Home controller and added a ViewBag property GreetMessage. When this view is called, it will display a greeting message in a heading. The GreetMessage will hold the name of the person, which is our parameter. Below is our controller action:

[GET("App/Greet/{name}")]
public ActionResult Welcome(string Name)
{
    ViewBag.GreetMessage = "Welcome " + Name;
    return View();
}

The URL that is rendered on the browser is:

http://domain.com/App/Greet/Prashant

/App/Greet/ is the URL we want to show and Prashant is the parameter is being passed to the Welcome view.

This is it for this tutorial but this is not it. The AttributeRouting package has to offer a lot of things and has a very powerful and easy way of routing. There are very advance topics that are documented at GitHub.

Related Links:

 No Rating

ASP.NET Postback Issue with Colorbox jQuery Plugin

19. August 2012 15:27

ASP.NET Jquery 

Yesterday, while working on a project I came across a weird problem while working with Colorbox jquery plugin and ASP.NET. The problem is not only with Colorbox but also with another famous plugin called Fancybox. If you plan to use the plugine just to show dialog boxes, then this plugin works perfectly fine. Integrating the plugin with ASP.NET works fine but prevents post back if you have server controls on the colorbox dialog box (which is actually an invisible div on the page). ASP.NET developers can consider this as a bug but actually it's not a bug, but a scenario missed in the plugin.

I have a button click for button labelled Yes which redirects me to the about page. Now when you try to click the button there will be no post back event. This is because Colorbox renders the div outside the form tag which hinders the post back event.

Now to overcome this problem, you need to jump inside the Colorbox plugin code. The main function that add the content to the DOM or on the page is called appendHTML

function appendHTML() {
    if (!$box && document.body) {
        init = false;

        $window = $(window);
        $box = $tag(div).attr({ id: colorbox, 'class': isIE ? prefix + (isIE6 ? 'IE6' : 'IE') : '' }).hide();
        $overlay = $tag(div, "Overlay", isIE6 ? 'position:absolute' : '').hide();
        $wrap = $tag(div, "Wrapper");
        $content = $tag(div, "Content").append(
			$loaded = $tag(div, "LoadedContent", 'width:0; height:0; overflow:hidden'),
			$loadingOverlay = $tag(div, "LoadingOverlay").add($tag(div, "LoadingGraphic")),
			$title = $tag(div, "Title"),
			$current = $tag(div, "Current"),
			$next = $tag(div, "Next"),
			$prev = $tag(div, "Previous"),
			$slideshow = $tag(div, "Slideshow").bind(event_open, slideshow),
			$close = $tag(div, "Close")
		);

        $wrap.append( // The -1x3 Grid that makes up ColorBox
			$tag(div).append(
				$tag(div, "TopLeft"),
				$topBorder = $tag(div, "TopCenter"),
				$tag(div, "TopRight")
			),
			$tag(div, false, 'clear:left').append(
				$leftBorder = $tag(div, "MiddleLeft"),
				$content,
				$rightBorder = $tag(div, "MiddleRight")
			),
			$tag(div, false, 'clear:left').append(
				$tag(div, "BottomLeft"),
				$bottomBorder = $tag(div, "BottomCenter"),
				$tag(div, "BottomRight")
			)
		).find('div div').css({ 'float': 'left' });

        $loadingBay = $tag(div, false, 'position:absolute; width:9999px; visibility:hidden; display:none');

        $groupControls = $next.add($prev).add($current).add($slideshow);

        $(document.body).append($overlay, $box.append($wrap, $loadingBay));
    }
}

In the above method (which is an extract from the plugin), notice that the plugin is focusing on document.body whereas in order to get it working with the post back events we need to change the above highlighted lines with the one below:

if (!$box && document.forms[0]) {

And

$(document.forms[0]).append($overlay, $box.append($wrap, $loadingBay));

After the changes have been made, it's time to check again. Try clicking the button and check again. This time you will be redirected to the about page. Although, this seems to be simple problem, but there will be few fellow programmers who will scratch their head if they stuck in this sort of a problem. Hope this helps someone out there.

Currently rated 5.0 by 1 person

Integrate Windows Live SignIn Support In ASP.NET

28. July 2012 12:35

API ASP.NET 

Last year I wrote a post on how you can integrate OpenID support in your ASP.NET application. Few days back as usual I was chasing Windows Live SDK updates on Twitter and yes the most awaited SkyDrive API was made available to all the developers. I will be writing a post later on how to upload files using SkyDrive API.

Setting up the application

To integrate Windows Live Sign-In support I have downloaded the LiveService samples from Github and take a look at ASP.NET sample. All the hard work has been done for you from before. First you need to create an application at https://manage.dev.live.com. Once you create an application, you will get the Client ID and Client secret for the application which we will be using in our application.

Now you have the Client ID and Client secret, you then need to update the same in the Callback.aspx code-behind. The redirect domain will be the name of the domain. In my case I have hosted the complete solution which you can try here. The pretty looking Sign In button rendered on the page is from the JavaScript code.

When you click on the button it will open a window which will ask your Live or Hotmail credentials.

After you successfully authenticated from Live service, it will return you the authentication code. For your ease I have made the authentication code (along with the URL that retrieves the user's image) available to you through a JavaScript alert.

Don't waste your time in looking into the alert message. Just press CTRL+C to copy the whole message and paste it into notepad. Now it's time to look into it carefully. If you quickly open a new tab in your browser and paste the copied URL, then you will get the image of the user who is authenticated. To get more information about the user, modify the URL in the notepad to this:

https://apis.live.net/v5.0/me?access_token=EwBAAq1DBAAUlbRWyAJjK5w968Ru3Cyt/6GvwXwAAf/Zr2CM5/qilrH.......

Note that from the URL above I have removed /picture. Now hit the new URL to the browser again, and this time the output has more information:

The question comes here is: What if I want to get the contacts of the authenticated user or want to get the list of folders in his/her SkyDrive? To understand this, consider that Windows Live is a big application which is built up with small applications like mail, SkyDrive, calendar etc. Now if someone wants to access any part of the application we need to specify which part of the application we need to access. For us (programmers) it is called Scope. The test application I am demonstrating here has the following scopes: wl.signin, wl.basic, wl.offline_access, wl.skydrive. To grant access to your application you should provide the correct scopes in your application. To know more about scopes read here

After everything went fine and I was successfully authenticated I get my picture with Windows Live (it's 2 year old) and the Sign in button changed to Sign out:

You can also display other user information, if you wish. I have compiled all the files under one hood for your ease and you only have to create a new application, get the Client ID and Client secret and update it into the application.

Download: Live-SignIn.zip (9.71 kb)

 No Rating