Julian Jelfs’ Blog

Angular auto-retry interceptor for WinInet error codes

Posted in angular, Javascript by julianjelfs on June 5, 2015

It’s a little known fact that IE9 (and maybe lower versions if you have to support them) will occasionally return strange looking codes from xhr requests. You probably won’t be handling these in your angular app because they are not http codes. But they do happen and they happen quite often.

I have found that simply retrying the request (just once) will all but eradicate this problem. You might also consider a single retry on any xhr error.

How do you actually do this? Using an http interceptor as follows is the most generic way I have found.

'use strict';

angular
    .module('app')
    .config(($provide, $httpProvider) => {

    var codesToRetry = [12152,12002,12031,12029,12030,12041,12019];

    $provide.factory('retryInterceptor', ($injector, $q) => {
        return {
            'responseError' : (resp) => {
                if(codesToRetry.indexOf(resp.status) >= 0 &&
                    resp.config.headers['X-Auto-Retry'] == null) {
                    resp.config.headers['X-Auto-Retry'] = resp.status;
                    var $http = $injector.get('$http');
                    return $http(resp.config);
                } else {
                    return $q.reject(resp);
                }
            }
        };
    });

    if ($httpProvider.interceptors.indexOf('retryInterceptor') < 0) {
        $httpProvider.interceptors.push('retryInterceptor');
    }
});

 

Here I have just picked a handful of codes that I saw in my own logs to automatically retry. We ensure that we only retry once by inserting a custom retry header to check on subsequent failures.

Hope this is useful to someone.

LESS (or SASS) can be MORE

Posted in Uncategorized by julianjelfs on April 27, 2013

When converting a conventional CSS file to SASS the other day it occurred to me that it could actually encourage less efficient CSS by creating the illusion of reuse. This seems specifically to be true when using mixins. Suppose I have several different kinds of icon and they just differ by background image, then I would naturally consider using a mixin to accomplish that like this:

@mixin icon($img) {
    background-image: url("#{$img}");
    background-repeat:no-repeat;
    background-position:center center;
    height:20px;
}

.error-icon
{
    @include icon("/images/error.png");
}

.save-icon
{
    @include icon("/images/save.png");
}

This gives me the illusion that I have reused that section of CSS. But really when you look at the output CSS you can see that the content of the mixin is duplicated:

.error-icon
{
    background-image: url("/images/error.png");
    background-repeat:no-repeat;
    background-position:center center;
    height:20px;
}

.save-icon
{
    background-image: url("/images/save.png");
    background-repeat:no-repeat;
    background-position:center center;
    height:20px;
}

In fact it is more efficient to create a separate CSS class for the common attributes and one for the icon specific background image like this:

.icon 
{
    background-repeat:no-repeat;
    background-position:center center;
    height:20px;
}

.error-icon
{
    background-image: url("/images/error.png");
}

.save-icon
{
    background-image: url("/images/save.png");
}

The moral of the story is not to forget that the important thing is is what actually gets generated, not just how cool your pre-processed file looks.

Tagged with: , ,

Securely posting application/json data to Asp.Net MVC4

Posted in Javascript, MVC by julianjelfs on April 3, 2013

Asp.Net MVC4 has some good mechanisms to protect against cross-site request forgery. The gist is that on the server you generate a unique token that is written out as a cookie and then also written out to the page you are rendering. Then when the system receives data via a POST request, it can check that the anti-forgery token has been supplied in both the submitted form and in the cookie and that they match. This way, if the user has been tricked into submitting a form that did not originate on the server as the user supposes, that request may have assumed the correct cookie, but will not have the matching form field counterpart and the request will fail.

We do this in Asp.Net MVC4 by simply calling the @Html.AntiForgeryToken() helper inside our view and then adorning our controller’s POST actions with the ValidateAntiForgeryToken attribute. Easy. This works really well if you are taking a traditional approach and posting forms of data to the server. But it is now very common for people to be using some kind of client side MVC framework (angular, knockout, ember etc etc) or even just using $.post to send json data back to the server outside a form submission.

I have seen a lot of people asking the question, how come my ValidateAntiForgeryToken doesn’t work when I post data back to the server using an ajax call in this way? Usually the response is that they are using the wrong content type. They are using “application/json” and they should be using “application/x-www-form-urlencoded” and this is why the anti forgery token cannot be read. This is true – the ValidateAntiForgeryToken attribute specifically looks in the Request.Form for the __RequestVerificationToken value and so it will only work with form url encoded data. But the answer is not to change the content type of your request it is to change your attribute.

The content type of “application/json” is entirely appropriate and correct. That is what you are doing – posting json. It’s much more easily parsed and it’s easier to read across the wire using something like fiddler, it’s easy to serialise and deserialise, it works with MVC model binding out of the box, so leave it alone. All you need to do is tag the verification token onto your request somehow and write a new attribute to pick it out of the request according to your rules. For example, it can easily be stored in and retrieved from a custom http header.

Continue to write the token out to the page using @Html.AntiForgeryToken() and replace the ValidateAntiForgeryToken attribute with something like this:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class ValidateJsonAntiForgeryToken : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;

if (request.HttpMethod == WebRequestMethods.Http.Post)
{
if (request.IsAjaxRequest())
AntiForgery.Validate(CookieValue(request), request.Headers["__RequestVerificationToken"]);
else
new ValidateAntiForgeryTokenAttribute().OnAuthorization(filterContext);
}
}

private string CookieValue(HttpRequestBase request)
{
var cookie = request.Cookies[AntiForgeryConfig.CookieName];
return cookie != null ? cookie.Value : null;
}
}

Then modify your client code to supply the token as a custom http header. In my case, I have created an angular service that wraps $http.post to achieve this as follows:

 

app.factory("xsrfPost", function($http) {
return {
post: function(url, args) {
var config = {
headers: {
'__RequestVerificationToken' : angular.element("input[name='__RequestVerificationToken']").val()
}
};
return $http.post(url, args, config);
}
};
})

Now, you can use a content-type that makes sense and still take advantage of the framework support for anti-XSRF protection.

“Patch” model binding with Asp.Net MVC

Posted in MVC by julianjelfs on March 8, 2013

Let’s say you have an update Action on a controller in Asp.Net MVC that accepts a domain object which you use for updating something like this:

[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public ViewResult UpdateCustomer(Customer model)
{
    //persist your model somehow etc etc
    return View(model);
}

When you use the DefaultModelBinding the MVC framework will create an instance of the Customer class and fill in any properties that it finds according to the registered ValueProviders (which will pull parameters from various places like the Form and the QueryString etc). This is all very well described here.

But what happens if you have more than one view of the data and sometimes not all of the data is passed back with the form? When might this happen? Perhaps you have a workflow where one user enters some of the data and another user completes the data. You could achieve this with two models and two views and two controller actions but you might have a dynamic view and just pass back the data that user is required to fill in (or has access to).

In this scenario, the DefaultModelBinder will cause us a problem because it creates a new instance of the Customer class to bind to. So suppose that user A has filled out the customer’s name and saved, but user B has to fill out the customer’s address but does not have access to the customer’s name (not very realistic I know). In this case the form posted by user B will not contain a value for the customer’s name, so that value will not be bound and user A’s data will get overwritten with a null value when the model is persisted.

You might be able to handle this with validation, but there is no point giving user B a validation error message relating to a field that he cannot see.

One way to deal with this is to create a custom model binder that loads the existing state of the model before binding rather than loading a blank instance of the type. It might look something like this:

public class CustomerModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, 
                                    ModelBindingContext bindingContext, Type modelType)
    {
        var session = ServiceLocator.Current.GetInstance<IDocumentSession>();
        var val = bindingContext.ValueProvider.GetValue("model.Id");    //this could be parameterised
        if (val != null)
        {
            var customer = session.Load<Customer>(val.AttemptedValue);
            if (customer != null)
            {
                return customer;
            }
        }
        return base.CreateModel(controllerContext, bindingContext, modelType);
    }
}

In this code, we are checking to see if the ValueProvider has a value for the key to our model object. If it does, we load the object (I’m using Raven but that doesn’t matter), if not we fallback to the DefaultModelBinder.

We then need to register this custom model binder for the specific type we are interested in at application start up;

ModelBinders.Binders.Add(typeof(Customer), new CustomerModelBinder());
And now, when user B’s partially complete POST arrives, it will be bound to the instance of the Customer object that user A created and we will not lose any data. Nice.

Dynamic validation with FluentValidation and MVC 4

Posted in MVC, Uncategorized by julianjelfs on March 7, 2013

FluentValidation is a very nice way to perform custom validations in .Net and integrating it into the built in validation system used in MVC 4 is relatively straightforward. But it is not immediately clear how you go about performing dynamic validation on a MVC model based on the state of that model. If you are implementing a workflow, for example, this is something that you may well want to do. For example, let’s say that you have the following model:

   1: public class Customer

   2: {

   3:     public int Id {get;set;}

   4:     public string Name {get;set;}

   5:     public string Email {get;set;}

   6:     public string Status {get;set;

   7: }

Suppose that you would like the Name to be mandatory if the Status property is set to “New”, but if the Status property is set to “Existing” you would like the Name and the Email to be mandatory. The standard integration of FluentValidation with MVC 4 allows you to correlate a controller action’s input parameter with a validator, by decorating the model type with a Validator attribute. It will then call the Validate method on that validator at the right point by plugging in to the MVC model validation infrastructure. So far this will only allow you to run the same validation regardless of context. The validation can be further customised by adding a CustomizeValidator attribute to the model parameter on your controller action.

The CustomizeValidator attribute allows you to override the properties to validate, the rule sets to validate and an interceptor to call before and after MVC validation takes place. To take advantage of model state to apply specific validation we first need to capture our different scenarios as rule sets in the validator as follows:

   1: public class CustomerValidator : AbstractValidator

   2: {

   3:     public CustomerValidator()

   4:     {

   5:             RuleSet("New", () => {

   6:             RuleFor(c => c.Name).NotEmpty();

   7:         });

   8:

   9:         RuleSet("Existing", () => {

  10:             RuleFor(c => c.Name).NotEmpty();

  11:             RuleFor(c => c.Email).NotEmpty();

  12:         });

  13:     }

  14: }

then attribute the model class with this validator:

   1: [Validator(typeof(CustomerValidator))]

   2: public class Customer ....

Create a validation interceptor to specify the correct selector on the ValidationContext based on the model state like this:

   1: public class CustomerValidatorInterceptor : IValidatorInterceptor

   2: {

   3:     public ValidationContext BeforeMvcValidation(ControllerContext controllerContext,

   4:                 ValidationContext validationContext)

   5:     {

   6:         if (validationContext.InstanceToValidate is Customer)

   7:         {

   8:             var customer = (Customer) validationContext.InstanceToValidate;

   9:             return new ValidationContext(customer, validationContext.PropertyChain,

  10:                 new RulesetValidatorSelector(customer.Status));

  11:         }

  12:         return validationContext;

  13:     }

  14:

  15:     public ValidationResult AfterMvcValidation(ControllerContext controllerContext,

  16:                 ValidationContext validationContext,

  17:                 ValidationResult result)

  18:     {

  19:         return result;

  20:     }

  21: }

  22:

and finally add this interceptor to your controller action via the CustomizeValidation attribute like this:

   1: public ViewResult UpdateCustomer(

   2:     [CustomizeValidator(Interceptor = typeof(CustomerValidatorInterceptor))]Customer model)

   3: {

   4:     ...

   5: }

And now we will execute the correct RuleSet according to the state of the Customer object and it will all integrate with the MVC validation infrastructure nicely.

Galloway marathon calculator app

Posted in Uncategorized by julianjelfs on February 6, 2013

…and as a follow up to my last post, I also wanted an easy way to calculate what my overall time over 50 miles might be which is a slightly annoying calculation when you’re running for 4 minutes at speed x then walking for 45 seconds at speed y and you have z checkpoints and you spend a certain amount of time in those checkpoints. So I also wrote a calculator to capture all of those variables to help me fine tune my strategy. 

Image

Source is also available on GitHub.

Of course in the end my strategy was just to keep going and try not to be sick, but it was nice to have the app anyway.

Android Lap Timer app

Posted in Uncategorized by julianjelfs on February 6, 2013

When I was training for my first ultra-marathon, I used the Galloway run-walk marathon training method, where you run for a bit and then walk for a bit (read about it here). I had been using 5 minutes running and then 1 minute walking and then later I moved to 4 minutes running and 45 seconds walking. 

I had programmed an advanced workout into my Garmin 405 to beep at me and help me maintain this cycle. On my 25+ mile training runs I realised that the Garmin (which I hate for many other reasons also) was not going to last the course before the battery died. I didn’t want to be clock watching while running this thing so I decided to create a (very) simple Android app. I just enter the run time in seconds and the walk time in seconds and hit start and it beeps and vibrates at the end of each cycle. 

Image

On many occasions when the Garmin was having one of its hissy fits this simple Android app came to the rescue and it performed beautifully on the day of the race too. 

For the 0.000001% of the population that run for more than 6 hours, use a run-walk approach to  training, are on the exact version of Android that I am and know how to build it – you can find the source on my GitHub!

Tagged with: ,

Forms Authentication for SSRS using SqlMembershipProvider

Posted in SSRS by julianjelfs on February 6, 2013

Sql Server 2008 includes a sample solution explaining for to write a security extension that will enable SSRS to work with Form Authentication. By default you will find this sample in the C:\Program Files\Microsoft SQL Server\100\Samples\Reporting Services\Extension Samples\FormsAuthentication Sample directory.

It’s reasonably easy to follow the instructions for this sample and the general idea is simple. You tell SSRS that you’re going to take care of authentication yourself and then you implement some code to capture and verify the user’s credentials.

When you’re trying to implement Forms Authentication you might be forgiven for thinking that you would just somehow use one of the membership providers already present in the .Net framework. That’s what I was expecting, but when you look at the sample code you see a class called AuthenticationUtilities containing all sorts of hideous manual Ado.Net queries (complete with hard-coded connection strings), and all sorts of nasty scary password hashing code. For example, the VerifyPassword method in this class does the following:

  • Retrieves the hashed password from the UserAccounts db
  • Hashes the supplied password using the same salt (though it is not necessarily using the correct hash algorithm
  • Compares the two hashes to see if they match

Not too much wrong with that, but if you decompile the SqlMembershipProvider you will find that it does pretty much exactly the same thing, but the code is a more robust.

This means that you can replace the contents of VerifyPassword with a call to Membership.ValidateUser(user, password). All you have to do to make this work is to set it up in the Report Server web.config exactly like you would in a normal web application:

<connectionStrings>
    <add name="UserAccounts" connectionString="server=*******;database=UserAccounts;uid=**;pwd=*****;Connection Reset=false;" />
</connectionStrings>

<authentication mode="Windows" />

<authentication mode="Forms">
      <forms loginUrl="Logon.aspx" 
             name="SqlAuthCookie" 
             timeout="90"
             enableCrossAppRedirects="true"
             path="/" >
      </forms>
</authentication>

<identity impersonate="false" />

<authorization>
      <deny users="?" />
</authorization>

<membership defaultProvider="SqlMembershipProvider">
      <providers>
        <add applicationName="MyApp" 
             connectionStringName="UserAccounts" 
             name="SqlMembershipProvider" 
             minRequiredPasswordLength="1" 
             minRequiredNonalphanumericCharacters="0" 
             requiresQuestionAndAnswer="true" 
             requiresUniqueEmail="false" 
             type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      </providers>
</membership>



Note that you can and should use aspnet_regiis to encrypt that connection string.

In all the hours of googling involved in getting this to work I didn’t find any reference to the fact that it was perfectly possible to use the SqlMembershipProvider just like you would in a normal web application and leave all the nasty password handling to the experts. I’ve no idea why they decided to write the samples in this way…

WatiN Javascript Alert Dialog Handler

Posted in Unit Testing, WatiN by julianjelfs on October 7, 2011

The javascript alert handler that comes with WatiN out of the box didn’t quite do what I wanted. I needed something that could be automatically running the whole time and dismiss the alert whenever it happens but notify my code that the alert had happened and what the alert message had been. So I came up with the following modification to the WatiN version which suits my purpose:

    public class JavaScriptAlertDialogHandler : BaseDialogHandler
    {
        private readonly Action _onAlert;

        public JavaScriptAlertDialogHandler(Action onAlert)
        {
            _onAlert = onAlert;
        }

        public override bool HandleDialog(Window window)
        {
            if (CanHandleDialog(window))
            {
                _onAlert(window.Message);
                new WinButton(GetOKButtonId(), window.Hwnd).Click();
                return true;
            }
            return false;
        }

        public override bool CanHandleDialog(Window window)
        {
            return (window.StyleInHex == "94C801C5" && !ButtonWithId1Exists(window.Hwnd));
        }

        private static int GetOKButtonId()
        {
            return 2;
        }

        protected static bool ButtonWithId1Exists(IntPtr windowHwnd)
        {
            var button = new WinButton(1, windowHwnd);
            return button.Exists();
        }
    }

So when you construct the handler you pass in an Action that will receive the text of the message when the handler handles an alert e.g.

    IE.AddDialogHandler(new JavaScriptAlertDialogHandler(s => ScriptAlert = s));

Hope this is of some use to someone else too …

Tagged with:

WatiN Dialog Handler for unhandled javascript exceptions

Posted in Unit Testing, WatiN by julianjelfs on September 27, 2011

I’m not sure what WatiN does with javascript exception alerts by default, but I was finding that it seemed to silently close any exception dialog and the test would carry on and would possibly still pass. In my case, I would like the test to fail if there is a javscript error and I would like it to report the text of the javascript error as the reason for the test failure.

First I tried to do this using the NativeMethods supplied with WatiN but I wasn’t able to get at the text description of the error which was important for reporting the reason for test failure. So I then resorted to the UI Automation API found in C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\UIAutomationClient.dll and came up with the following code:

using System.Windows.Automation;
using WatiN.Core.DialogHandlers;
using WatiN.Core.Native.Windows;

namespace WatiNExtensions
{
    public class ScriptExceptionDialogHandler : BaseDialogHandler
    {
        private readonly ITestFailureLogger _logger;

        readonly AndCondition _documentCondition = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
                                                                    new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document));

        readonly AndCondition _buttonConditions = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
                                                                   new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button));


        public ScriptExceptionDialogHandler(ITestFailureLogger logger)
        {
            _logger = logger;
        }

        public override bool HandleDialog(Window window)
        {
            if (CanHandleDialog(window))
            {
                var win = AutomationElement.FromHandle(window.Hwnd);
                var documents = win.FindAll(TreeScope.Children, _documentCondition);
                var buttons = win.FindAll(TreeScope.Children, _buttonConditions);

                foreach (AutomationElement document in documents)
                {
                    var textPattern = document.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
                    var text = textPattern.DocumentRange.GetText(-1);
                    _logger.Log(string.Format("Unhandled javascript exception: {0}", text));
                }

                foreach (AutomationElement button in buttons)
                {
                    if(button.Current.AutomationId == "7")
                    {
                        var invokePattern = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
                        invokePattern.Invoke();
                        break;
                    }
                }
                return true;
            }
            return false;
        }

        public override bool CanHandleDialog(Window window)
        {
            return window.StyleInHex == "94C808CC";
        }
    }
}

This accepts an ITestFailureLogger interface in the constructor, finds the text of the error and logs it, then clicks on the “No” button to dismiss the dialog. What the ITestFailureLogger does is up to you. In my case it just tracks the errors and then checks them in the NUnit test’s tear down. You cannot throw an exception in the dialog handler to stop the test in its tracks because any exception thrown by IDialogHandler.HandleDialog will be swallowed by the WatiN DialogWatcher (understandable but a little bit irritating).

Hope this is of some use to someone.

Tagged with: ,