by Andreas

Aborting AJAX requests in ASP.NET applications

imageI’ve been working on a pretty extensive web application lately, build on top of the .NET framework but with around 80% client side functionality (KnockoutJS, jQuery). There’s a lot of AJAX calls back to the server (naturally.. ) and one of the challenges I faced was that ASP.NET refused to navigate away from a page until all AJAX requests were processed. I did some searching and found out that an AJAX request could be aborted by adding some functionality to the window.onbeforeunload event:

window.onbeforeunload = function() {
    if (ajaxRequest !== undefined) {
        ajaxRequest.abort();
    }
};

 

By adding some logging to console I could clearly see that as soon as I clicked a link to navigate away this event was called and processed. But still nothing happened until the request had fully been processed – which made me think this had to do with the browser. Wrong assumption, and when writing this it seems very obvious to me why but then again retrospect is an ugly thing.

A bit more research and it turned out that this was all due to ASP.NET session state (which is enabled by default). Because of the session state my site serializes all requests within the same session, so the request for a new page would not be processed until the first one had completed. Turning session state off completely was out of the question, but by changing my .ashx handler (which receives all my ajax requests) to implement the IReadOnlySessionState interface rather than IRequiresSessionState there is no lock on the current session and concurrent requests are made possible.

Something to keep in mind though is that aborting an ajax request obviously doesn’t stop the server from processing it.

by Njål

Windows Azure SQL – Entity Framework 6 Retry Logic

 

One of the biggest drawbacks of using Azure SQL is that the connection towards the database is a lot more fragile and unstable than when you’re using a database server on your LAN. Also – your Azure database is running on servers with several hundred other databases – so the database server might disconnect you at any given time to ensure fairness of service etc.

These are transient errors – meaning that a retry of the query most often will succeed and fix the error.

Microsoft has released several code blocks and guidelines to help developers use this retry logic – http://code.msdn.microsoft.com/windowsazure/SQL-Azure-Retry-Logic-2d0a8401

And luckily – the EntityFramework team has added support for this in version 6 as well.

Here’s how you can get started with EF6 (beta 1) – using the built in SqlAzureExecutionStrategy

 

1. Install EF6 beta by opening the NUGET console in Visual Studio and typing
     PM> Install-Package EntityFramework –Pre

2. Install the EF6 Template generator – http://visualstudiogallery.msdn.microsoft.com/18a7db90-6705-4d19-9dd1-0a6c23d0751f. This will create the C# code for you – which will handle the communication towards the database

3. Restart Visual Studio

4. Add New Item  -> EDMX file. Connect to Database and/or specify your datamodel. Just like older versions of Entity Framework.

5. Right click in the EDMX editor – and select Add Code Generation Item. Select EF 6.x DbContext Generator.

6.
Compile. You should now have EF6 up and running. Only one crucial part missing – the Azure Retry Logic.

7. Add a class inside your Project with the following code. It will get picked up upon Application Start – and make sure that all the EF Database queries will be retried if they fail.

 

using System;
using System.Data.Entity.Config;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;

namespace Www.Business.Database
{
    public class SqlAzureDbConfiguration : DbConfiguration
    {
        public SqlAzureDbConfiguration()
        {
            AddExecutionStrategy(() => new SqlAzureExecutionStrategy(), null);
        }

        protected void AddExecutionStrategy(Func<IExecutionStrategy> getExecutionStrategy, string serverName)
        {
            AddDependencyResolver(new ExecutionStrategyResolver<IExecutionStrategy>("SqlAzureExecutionStrategy", serverName, getExecutionStrategy));
        }
    }
}

(The example provided here: http://entityframework.codeplex.com/wikipage?title=Connection%20Resiliency%20Spec does not work/compile)

by Joakim

JavaScript file missing from resource bundle (ASP.NET Web Optimization Framework)

I came across some odd behavior related to the Microsoft ASP.NET Web optimization Framework the other day, when I was creating a JavaScript resource bundle in an application I was working on. When I ran the website with optimizations enabled, the script file showed up as part of the bundle, but if I turned optimizations off the script include for the file in question was nowhere to be found.

For the application I was working on, which was only a proof of concept, I had simply copied the minified version of the JavaScript libraries I needed into the Script manually. I then included my libraries in a script bundle like so;

BundleTable.Bundles.Add(newScriptBundle(“~/bundles/jquery”).Include(“~/Scripts/jquery-1.8.2.min.js”));

If you have used this bundling functionality before, you probably know that if you include a JavaScript file in a bundle and you enable optimizations, the file will be minified and added to a single resource together with any other JavaScript files in the bundle. During the minification process the system will look for other files in the directory called exactly the same filename as the file in question only with .min.js at the end instead of only .js. If it finds a file like this, it assumes that this it is a pre-minified version of the file in question and uses it instead of minifying the original file.

However, if you add a file to your bundle that has a name that ends in .min.js (like I did) and optimizations aren’t enabled (e.g. debug is set to true in web.config and BundleTable.EnableOptimizations has not been set to true), this file will be ignored (i.e no script include will be generated for it in your html).

by Andreas

OWA in an iFrame – yes, it’s possible

imageMicrosoft is very clear on one thing when it comes to showing OWA (Outlook Web App) in an iFrame: it is not supported, and you’re on your own (unless you’re using their Sharepoint web parts).

That doesn’t mean it can’t be done, and if you’re happy with the light version (no right-click support, no custom toolbar items and probably other missing features..) it can be done as easy as displaying the following HTML page in an iFrame:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>

<script>
    function LoginToOWA(server, domain, username, password) {


        var url = "https://" + server + "/owa/auth/owaauth.dll";
        // flags 0 = full version, flags 1 = light weight mode
        var p = { destination: 'https://' + server + '/exchange', flags: '1', forcedownlevel: '0', trusted: '0', isutf8: '1', username: domain + '\\' + username, password: password };


        var myForm = document.createElement("form");
        myForm.method = "post";
        myForm.action = url;

        for (var k in p) {

            var myInput = document.createElement("input");
            myInput.setAttribute("name", k);
            myInput.setAttribute("value", p[k]);
            myForm.appendChild(myInput);
        }


        document.body.appendChild(myForm);
        myForm.submit();
        document.body.removeChild(myForm);
    }
</script>


<body onload="javascript:LoginToOWA('mail.someserver.com','yourdomain','yourusername@someserver.com','yourpassword');">
    <img src="../../gfx/loadingAnim.gif" /> Please wait while your inbox is loading... 
</body>
</html>

 

The javascript function is called during the body onload event with the mail server url and logon credentials. That’s it, works like a charm!

Now, to make this work for the full version OWA and get the right click support and other features just make sure the web site is running on the same domain as your Exchange server. If your web site is hosted on somesite.someserver.com, and your Exchange is running on mail.someserver.com you should be good to go – despite some console warning messages that so far haven’t proven to cause any issues for me at least. The only change to the above code is to set the “flags” attribute to 0 instead of 1, and this switches from “light mode” to “full mode” (see in-code comment).

by Andreas

Define a #Region in javascript files (Visual Studio 2010 / 2012)

In these times of super responsive client side processing mega javascript extravaganza web applications  you’re more than likely to end up with fairly large .js files in your projects. The standard code file in Visual Studio allows you to define collapsible sections by wrapping them with the #region / #endregion blocks. In javascript files however, you are restricted to collapsible functions only (“#region” is not recognized as anything valid):

image

Well, I just found out that that’s not entirely true. By marking a section of code (regardless of any logical blocks) and hitting CTRL + M + H you’ll define the selection as a region which is collapsible and expandable

image

by Njål

Quick row count from Microsoft SQL Database

 

Recently, I’ve been involved in a cloud provider project where I had to do a row count on a Microsoft SQL Database table with more than 50.000.000 rows in it.

Doing

SELECT COUNT(*) FROM myTable

took about 10 seconds – since it performs a full table scan.

 

Here’s an alternative way (still accurate) of doing it that takes under 1 sec:

SELECT SUM (row_count)
FROM sys.dm_db_partition_stats
WHERE object_id=OBJECT_ID('myTable')   
AND (index_id=0 or index_id=1);

 

You can run this from Microsoft Entity Framework as well:

long total = dbContext.Database.SqlQuery<long>("SELECT SUM (row_count) FROM sys.dm_db_partition_stats WHERE object_id=OBJECT_ID('myTable') AND (index_id=0 or index_id=1);").First();

by Njål

The directory specified for caching compressed content is invalid. Static compression is being disabled.

image

 

After adding this in my web.config (Azure Project)…

<staticContent>
    <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
</staticContent>

…IIS refused to serve any static content – such as js and png files. Log entries in Event Viewer said:

The directory specified for caching compressed content
C:\Users\xxx\AppData\Local\dftmp\Resources\b503ce54-3fba-4772-beaa-415d94ffc214\temp\temp\RoleTemp\iisexpress\IIS Temporary Compressed Files\9ef2ab2d-28fc-4554-a09c-5ba867eb1d19 is invalid.
Static compression is being disabled.

The problem was that .svg files were already added to the staticContent list in my applicationHost.config – but still – the error message shown in the Event Viewer is pretty useless. There is nothing wrong with the directory specified to store compressed content.

So if you suddenly get this error – undo any changes in Web.config (remove all config under staticContent) and restart IIS (Express).

by Stian

Decimal validation with comma in MVC

20130228DecimalSeparator.svgIn MVC 3, when using jQuery validation plugin with unobtrusive validation, you will see that comma in a textbox that is bound to a decimal value will not be allowed by client side validation.

Instead of going in and changing the jquery.validate.js, you should override the default behavior by adding these lines to your own javascript file (make sure it is loaded after the valiate javascript!)

$.validator.methods.range = function(value, element, param) {
    var globalizedValue = value.replace(",", ".");
    return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);
};

$.validator.methods.number = function(value, element) {
    return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);
};



This will fix your problem for the number validation and the range validation!

by Andreas

VMWare Player (free) – how to run virtual machine in headless mode

Virtual machine performance can be improved by running your virtual machine in headless mode (e.g. as a background process, without the GUI). Instead of using the console view in the VMWare Player you’ll connect via standard RDP, and in some cases achieve significant performance improvements.

There’s a small requirement to the VMWare Player preference file. You’ll find it under the following directory (at least in Windows 8):

C:\Users\[Username]\AppData\Roaming\VMware\preferences.ini

Add the following line at the bottom:

pref.vmplayer.exit.vmAction = "disconnect"

This will ensure that you only disconnect from the virtual machine when closing VMWare Player, not send it into Suspended mode.

Fire the virtual machine up as normal (throught the player), and then kill the VMWare Player process through Task Manager (closing it by clicking the X icon will not work – this will also send the virtual machine into Suspended mode):

image

 

The virtual machine is still running in the background, and you’re now able to connect via RDP.

by Aage Andre

Office 2013 – Disable Animations and Effects

While I like the new Office, I honestly loath the “design-guru” who decided to cross-fade, smooth transitions and in general make everything you do slow down, so you can look at the nice little flow of the programs.

The most irritating, for me, the Word typing animations and Excel cell-change. Luckily you can turn them off.

Go into your registry: [HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Common\Graphics]
Create a new dword: “DisableAnimations”=dword:00000001
(I also had to create the Graphic-key)

Reboot and enjoy efficiency once again.