Monday, June 30, 2014

ASP.NET Web Optimizations: 404 not found error

To optimize an ASP.NET MVC application we are using the ASP.NET Optimization framework. During development everything worked fine but the moment we enabled the bundling and minification functionally we started to get 404 errors. These 404 errors were not coming from resources that we loaded directly. Instead they were loaded through some CSS files that were part of our bundles.

This was really some strange and unexpected behavior. What was going in?

The thing is when using the StyleBundle and ScriptBundle classes, the "virtualpath" parameter of the classes DOES matter when  have various folders inside the Content folder that can contain many different sets of styles for various reasons, and you want to maintain that folder structure. In our case we were using the Kendo UI widgets, so we had multiple folders inside our MVC content folder:

image

We fixed this by changing the path to the Kendo CSS to:

bundles.Add(new StyleBundle("~/Content/kendo/2014.1.318/kendostyles").Include("~/Content/kendo/2014.1.318/kendo.common.*", "~/Content/kendo/2014.1.318/kendo.default.*"));

The important thing is that the virtual path matches the folder structure of your content folder.

More information about this issue and how to resolve it can be found in  the following blog post: http://www.mvccentral.net/Story/Details/articles/kahanu/stylebundle-403-error-solved.

Friday, June 27, 2014

Angular.js: Create a select list with a default option

Like most things in Angular.js, once you know how to do it, it’s really simple. This time I was struggling with creating a dropdown in Angular.js and providing it with an extra default ‘select a category…’ option.

This is how I got this working:

The only thing I had to do was adding one extra <option> tag myself inside the <select>.  Easy enough once you know it!

Thursday, June 26, 2014

Azure WebJobs Logging

There are multiple ways to enable logging inside your Azure Web Job.

Console.WriteLine

One option that works if you created a C# console application, is using the Console.WriteLine() or Console.Write() methods on the Console object.

image

Inject a TextWriter

Another option is injecting a TextWriter into one of the WebJobs methods:

Wednesday, June 25, 2014

Running SQL Server on an Azure VM

If you are using IAAS and running your SQL Server environment on a VM in Windows Azure, there are some things you need to be aware of. Otherwise you could end up with a decreased performance.

azure%20logo

Based on some research and performance testing, Microsoft  has revised some of the guidelines and best practices on how to best configure SQL Server in this environment. You can find this collective advice which includes a quick “checklist” at this location on the web:

Tuesday, June 24, 2014

ASP.NET MVC: Async timeout for AsyncControllers

On one of my projects, we are still using ASP.NET MVC 3. To implement some asynchronous behavior we therefore cannot use the shiny async/await syntax but instead we use the good old AsyncController and AsyncManager. This works fine as long as the async work didn’t take too long. If it took too long, the page was timing out. Changing the ScriptTimeout value made no difference.

In the end we discovered that the AsyncManager is using different timeout values(45 seconds by default) and doesn’t look at the ScriptTimeout value.

To change this value you can use one of the following action attributes:

Monday, June 23, 2014

Visual Studio ALM Widgets list

The Visual Studio ALM Rangers team released a list of cool, productive and recommended community widgets for Visual Studio and Team Foundation Server at http://aka.ms/widgets.

image

A must have for every TFS administrator!

Friday, June 20, 2014

Using Gmail on Windows Azure

One part of the application I’m currently working on, generates reminder mails on certain time intervals. To test this functionality we used a specific Gmail account to connect to. The problem was the moment we deployed it to Windows Azure, the email functionality no longer worked. The problem was that Google was rejecting the authentication request that was coming from Azure. When the application tried to access the Gmail account from a different location(from inside the Azure Data Center), Google noticed this and blocks access.

When we logged in on the Gmail account, there was a warning message saying:

Someone signed in from a location that isn't typical for your account. If it wasn't you, change your password immediately.

We also got an email saying that someone tried to use an application to sign in:

image

In the email there is a link, providing the necessary instructions to get it working. Using the DisplayUnlockCaptcha did the trick. After doing that, we could successfully log into the Gmail account from inside our Azure Website.

Thursday, June 19, 2014

Team Foundation Server: Version Control Guidance

The ALM Rangers released their third version of the Version Control guidance. It has been split into separate topics as summarized below, allowing you to pick the “world” (guide) you are interested in. This release delivers a new crisper, more compact style, which is easier to consume on multiple devices without sacrificing any content. The content is updated and aligns with the latest Visual Studio technologies and incorporates feedback from the readers of the previous guidance.

image

Branching Strategies
Practical guidance on a number of (not all) common Branching Strategies and usage thereof.

  • Branching concepts
  • Branching strategies
  • Walkthroughs

image

Team Foundation Version Control (TFVC)
Practical guidance on how to use Team Foundation Version Control (TFVC) features.

  • Workspaces
  • Merging
  • New features, i.e. Code Lens
  • Walkthroughs

image

Dependency Management with NuGet
Practical guidance on dependency management, using NuGet with Visual Studio.

  • Managing shared resources
  • Dependency management
  • Walkthroughs

 

Go download them here

Wednesday, June 18, 2014

26 Essential Metrics for Successful Mobile Apps

Have a look at this great infographic by Telerik:

Tuesday, June 17, 2014

Fun with WebJobs in Azure Websites: AzureImageOptimizer and AzureMinifier

I’m currently working on a project where we want to use the WebJobs feature of Azure Websites. Azure WebJobs enables you to run programs or scripts in your web site either continuously, on demand or on a schedule.

While investigating the possibilities of WebJobs I stumbled over 2 great usages of WebJobs:

  • Azure Image Optimizer: This will compress images on your website when running in Azure Web Sites.
  • Azure Minifier: This will minify your .css and .js files on your website when running in Azure Web Sites.

Just install the NuGet packages and the WebJobs will be deployed together with your website.

For more information have a look at the following blog post: http://madskristensen.net/post/automatic-optimization-of-images-css-and-javascript

Monday, June 16, 2014

ASP.NET Web API: Combining Attribute Based Routing and Url.Link

Similar to ASP.NET MVC, ASP.NET Web API offers the Url.Link method which allows you to generate a url based on the configured route information.

The thing is that if you look at the method signature the Link method expects a routeName:

public virtual string Link( string routeName, Object routeValues )

This works perfect when you are using the default code based routing configuration:

config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

But when you are using the ASP.NET Web API Attribute based routing, you don’t have a route name!? So how can we still use the Url.Link method?

The ASP.NET team was smart enough to think about this scenario and they provided an extra property on the Route attribute called Name:

Friday, June 13, 2014

Angular.js: wait for multiple calls to complete

In Angular.js I had a controller where I had to execute an action after multiple service calls are completed. Thanks to the $q promise library integrated in Angular.js, this is easy to achieve:

Both getApplications() and getEnvironments() return a Promise. By wrapping them in a call to $q.all(), the parent Promise is only resolved after both wrapped Promised are completed.

Thursday, June 12, 2014

sp_BlitzCache™: finding the worst queries in SQL Server made easy…

I’m not a SQL Server expert, so any tool that can help me improve my data access strategy is welcome.

One of these tools that I found very useful is the sp_BlitzCache stored procedure created by Jeremiah Peschka. It analyzes the top poorly performing queries for many different problems giving you a nice and useful result set.

Just download the script and run it on your database server. This will install the sp_BlitzCache stored procedure, afterwards you can run it by calling EXEC sp_BlitzCache.

image

Download sp_BlitzCache now!

Wednesday, June 11, 2014

PhoneGap/Cordova: Introducing the cross platform WebSQL plugin

Some months ago, I did an attempt to integrate SQLite in a cross platform Android, iOS and Windows Phone PhoneGap application. It was a painful experience to say the least. We encountered a lot of isssues and in the end it was way to slow. Not a good first experience with using a SQL store on a mobile device…

phonegap_logo

So it makes me really happy to see that Microsoft Open Technologies published an open source WebSQL plugin for Apache Cordova and PhoneGap. This plugin allows developers to integrate a persistent SQL-based local storage solution in their Cordova apps using the exact same JavaScript code across Android, iOS, Windows Phone and Windows Store. Under the hood, the plugin is using WebSQL on iOS and Android, and the open source SQLite library on Windows devices. SQLite happens to be easily usable across Windows devices using the SQLitePCL portable Class Library published recently.

The plugin can be found on the Apache Cordova plugins registry

More information and the official announcement here: http://msopentech.com/blog/2014/05/05/websql-plugin-for-apache-cordova/

Tuesday, June 10, 2014

ASP.NET Web API: use camel casing for your JSON objects

There is a general agreement to use PascalCasing for your objects in .NET, this in contrast to JavaScript where camelCasing is the default.  This is a little bit unfortunate when you are using ASP.NET Web API and want to return a JSON object to your JavaScript object. By default the properties will be PascalCased because of the fact that your C# objects are PascalCased as well.

Luckily this is an easy one to fix using the Json.NET serializer. Inside the WebAPIConfig class, add the following lines:

Friday, June 6, 2014

Angular.js: Form validation

Just a quick tip before the weekend. Angular.js provides validation through some of the well known HTML5 validation attributes like required, pattern, minlength, maxlength, min, max. However when your browser supports HTML5, the build-in validation will kick in, giving you no chance to integrate with Angular.js (to restyle or localize your validation messages for example).

To prevent HTML5  validation, it’s necessary to add the novalidate attribute to your form:

<form name="form" class="css-form" novalidate>

Thursday, June 5, 2014

What’s new in .NET 4.5.2?

With all the news and announcements about Roslyn, ASP.NET vNext, Entity Framework 7 and so on, you would almost forget that there is still a .NET framework behind the scenes. A few weeks ago, Microsoft released .NET version 4.5.2, a release that not only offers some nice reliability and performance improvements but even introduces some new features.

Here are some interesting links in case you missed the news:

I’m especially happy with the announced performance improvements to the Distributed Transaction Coordinator(DTC):

[The] distributed transactions enhancement enables promotion of local transactions to Microsoft Distributed Transaction Coordinator (MSDTC) transactions without the use of another application domain or unmanaged code. This has a significant positive impact on the performance of distributed transactions.

Wednesday, June 4, 2014

Using async/await in .NET 3.5 and 4.0

.NET 4.5 introduced the async and await keywords, simplifying asynchronous programming as much as possible. But did you know that you can also use async/await in .NET 4.0 and even .NET 3.5?

Thanks to the following NuGet packages, you can bring the power and simplicity of async/await to your older applications:

This package enables Visual Studio 2012 projects to use the new 'async' and 'await' keywords. This package also includes Task-based extension methods that allow using some of the existing asynchronous APIs with the new language keywords. Windows Phone Silverlight 8 projects can use this package to get access to async extension methods for the networking types.

This package is not supported in Visual Studio 2010, and is only required for projects targeting .NET Framework 4.5, Windows 8, Windows Phone Silverlight 8, or Windows Phone 8.1 when consuming a library that uses this package. For known issues, please see: http://blogs.msdn.com/b/bclteam/p/asynctargetingpackkb.aspx.

For more information on the async programming model, visit MSDN: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx.

Supported Platforms:

- .NET Framework 4 (with KB2468871)

- Windows 8

- Windows Phone 8.1

- Windows Phone Silverlight 7.5

- Silverlight 4

- Portable Class Libraries

Adds the new C#5 async features for .NET 3.5 projects

Tuesday, June 3, 2014

ASP.NET Web API: Map a virtual path to a physical path

ASP.NET always had the Server.MapPath option. This allowed you to translate a virtual path like “~/Content/Images” to an absolute path on the file system. The question is how can do this in Web API without tying yourself to ASP.NET(which makes self hosting a no-go).

The correct way seems to be the HostingEnvironment.MapPath method. Sounds good to me…

Monday, June 2, 2014

Entity Framework: SqlQuery does not support mapping

I had a simple query that I wanted to execute directly. I didn’t want to introduce any extra ADO.NET related classes so I used the SqlQuery<T> method that is available on the Entity Framework DbContext. If you want to have an Entity returned than this is easy. Just use the SqlQuery<> method on your DBSet<>:

If you don’t want an Entity returned but just a random class, you can use the SqlQuery<> method on the Database object:

Still easy to do…

There is however an important remark: the columns returned from your query should exactly match the property names of your objects. There is (at the moment) no way to specify a mapping between your custom class and a query.  Of course you can always use a column alias (AS keyword in SQL Server) to rename the column in the results.