Retrying with .net WebAPI client

We’ve been building a prototype Windows 8 dashboard to show management information on our Azure application.

One thing we were conscious of was unreliable mobile network connections so we wanted to make some attempt to retry if we get a failure.

We achieved this with a custom HttpMessageHandler.  We extend the DelegatingHandler so we can pass on to the real HttpClientHandler – this usefully also allows us to resend requests (if you try and send the same request twice you’ll get an exception when not using a delegating handler).  It’s pretty simple but seems to work ok (it doesn’t have any back off or handle specific types of errors – it is the simplest thing we can get away with right now).

    public class RetryingMessageHandler : DelegatingHandler
    {
        const int MaximumRetries = 10;

        public RetryingMessageHandler(HttpMessageHandler httpMessageSender, IEnumerable<IHttpResponseInspector> inspectors)
            : base(httpMessageSender)
        {
            Inspectors = inspectors;
        }

        public IEnumerable<IHttpResponseInspector> Inspectors { get; private set; }

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            Exception lastExcpetion = null;
            int i;
            var maxRetries = MaximumRetries + 1;
            for (i = 0; i < maxRetries; i++)
            {
                var retryRequired = false;
                HttpResponseMessage result;
                try
                {
                    result = await base.SendAsync(request, cancellationToken);
                }
                catch (Exception ex)
                {
                    lastExcpetion = ex;
                    continue;
                }
                foreach (var inspector in Inspectors)
                {
                    var inspectionResult = await inspector.Inspect(result);
                    if (inspectionResult == InspectionResult.Retry)
                    {
                        retryRequired = true;
                        if (inspector.MaxRetries < maxRetries)
                        {
                            maxRetries = inspector.MaxRetries + 1;
                        }
                    }
                }
                if (!retryRequired)
                {
                    return result;
                }
            }

            throw new ServiceRetryLimitExceededException(string.Format("Retry count exceeded, attempted call {0} times", i), lastExcpetion);
        }
    }

You’ll see you can pass in your own ‘Response Inspectors’ which can vote as to whether they want to retry or abort the call.  We use this to handle seamlessly re-logging in a user when their cookie expires.  Something which would be good to do is have different max retries for different inspectors – but we haven’t needed it yet.

We wrapped this up in a simple factory for creating a HttpClient.

public class HttpClientFactory : IHttpClientFactory
{
    private readonly CookieContainer _cookieContainer = new CookieContainer();

    public HttpMessageHandler CreateHandler()
    {
        return CreateHandler(new IHttpResponseInspector[0]);
    }

    public HttpMessageHandler CreateHandler(IEnumerable<IHttpResponseInspector> responseInspectors)
    {
        return new RetryingMessageHandler(_CreateHttpClientHandler(), responseInspectors);
    }

    HttpMessageHandler _CreateHttpClientHandler()
    {
        return _ConfigureClientHandler(new HttpClientHandler());
    }

    private HttpClientHandler _ConfigureClientHandler(HttpClientHandler handler)
    {
        handler.CookieContainer = _cookieContainer;
        handler.AllowAutoRedirect = false;
        return handler;
    }
}

public static class HttpClientFactoryExtensions
{
    public static HttpClient Create(this IHttpClientFactory httpClientFactory)
    {
        return new HttpClient(httpClientFactory.CreateHandler());
    }
}

All in all it’s pretty simple to extend the WebAPI and the delegating handler is a simple AOPish method for adding generic behaviour to all service calls.

Posted in Uncategorized | Tagged , , | Leave a comment

Handling gestures in C# WinRT using a behaviour

We’re using the WinRTBehaviors as WinRT doesn’t have them built in.  Behaviours (with a u sorry, I am English) are great and I’m really pleased that someone has ported them across – one less thing for us to do – thanks!

So gestures are cool but not massively easy to add in.  It isn’t complicated but it’s repetitive event wire up stuff.  It would be nice to wire up a cross swipe to a command on the view model.  To facilitate this we created a behaviour to encapsulate the gesture event wire up and expose a command for each gesture we support (at present we only need cross swipe and tap).

Note:  The cross swipe gesture ends in a tap event so if you want to do one thing on tap and another on cross swipe then you’ll have to do all the event handling via the gesture otherwise you will always run the tap action when cross swiping.  This is why it is useful for us to encapsulate all gestures in a single behaviour.

Here’s the behaviour:

public class GestureBehavior : Behavior<FrameworkElement>
{
    GestureRecognizer _pageGesture;

    public static readonly DependencyProperty CrossSwipeCommandProperty =
        DependencyProperty.Register("CrossSwipeCommand", typeof(string), typeof(GestureBehavior), new PropertyMetadata(default(string)));

    public static readonly DependencyProperty TapCommandProperty =
        DependencyProperty.Register("TapCommand", typeof(string), typeof(GestureBehavior), new PropertyMetadata(default(string)));

    public string CrossSwipeCommand
    {
        get { return (string)GetValue(CrossSwipeCommandProperty); }
        set { SetValue(CrossSwipeCommandProperty, value); }
    }

    public string TapCommand
    {
        get { return (string)GetValue(TapCommandProperty); }
        set { SetValue(TapCommandProperty, value); }
    }

    protected override void OnAttached()
    {
        AssociatedObject.AddHandler(PointerPressedEvent, (PointerEventHandler)_OnPointerPressed, true);
        AssociatedObject.AddHandler(PointerReleasedEvent, (PointerEventHandler)_OnPointerReleased, true);
        AssociatedObject.AddHandler(PointerMovedEvent, (PointerEventHandler)_OnPointerMoved, true);
        AssociatedObject.AddHandler(RightTappedEvent, (RightTappedEventHandler)_OnRightTap, true);
        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        if (_pageGesture != null && _pageGesture.IsActive)
        {
            _CompleteGesture();
        }
        AssociatedObject.RemoveHandler(PointerPressedEvent, (PointerEventHandler)_OnPointerPressed);
        AssociatedObject.RemoveHandler(PointerReleasedEvent, (PointerEventHandler)_OnPointerReleased);
        AssociatedObject.RemoveHandler(PointerMovedEvent, (PointerEventHandler)_OnPointerMoved);
        AssociatedObject.RemoveHandler(RightTappedEvent, (RightTappedEventHandler)_OnRightTap);

        base.OnDetaching();
    }
    private void _OnPointerPressed(object sender, PointerRoutedEventArgs e)
    {
        _pageGesture = new GestureRecognizer
        {
            CrossSlideHorizontally = true,
            ShowGestureFeedback = true,
            CrossSlideThresholds = new CrossSlideThresholds { RearrangeStart = 0, SelectionStart = 5, SpeedBumpStart = 0, SpeedBumpEnd = 0 },
            GestureSettings = GestureSettings.CrossSlide | GestureSettings.Tap
        };
        _pageGesture.CrossSliding += _PageGestureOnCrossSliding;
        _pageGesture.Tapped += _TappedButDidNotSwipe;
        _pageGesture.ProcessDownEvent(e.GetCurrentPoint(AssociatedObject));
    }

    private void _OnPointerMoved(object sender, PointerRoutedEventArgs e)
    {
        if (_pageGesture != null)
        {
            try
            {
                _pageGesture.ProcessMoveEvents(e.GetIntermediatePoints(AssociatedObject));
            }
            catch
            {
                _CompleteGesture();    
            }
        }
    }
        
    private void _OnPointerReleased(object sender, PointerRoutedEventArgs e)
    {
        if (_pageGesture != null)
        {
            try
            {
                _pageGesture.ProcessUpEvent(e.GetCurrentPoint(AssociatedObject));
            }
            catch
            {
            }
            finally 
            {
                _CompleteGesture();
            }
        }
    }
        
    private void _CompleteGesture()
    {
        _pageGesture.CompleteGesture();
        _pageGesture.CrossSliding -= _PageGestureOnCrossSliding;
        _pageGesture.Tapped -= _TappedButDidNotSwipe;
        _pageGesture = null;
    }

    private void _PageGestureOnCrossSliding(GestureRecognizer sender, CrossSlidingEventArgs args)
    {
        if (args.CrossSlidingState == CrossSlidingState.Completed && CrossSwipeCommand != null)
        {
            AssociatedObject.ExecuteCommand(CrossSwipeCommand);
        }
    }
                
    private void _TappedButDidNotSwipe(GestureRecognizer sender, TappedEventArgs args)
    {
        if (TapCommand != null)
        {
            AssociatedObject.ExecuteCommand(TapCommand);
        }
    }
        
    private void _OnRightTap(object sender, RightTappedRoutedEventArgs e)
    {
        if (CrossSwipeCommand != null)
        {
            AssociatedObject.ExecuteCommand(CrossSwipeCommand);
        }
    }
}

Here is how it’s used in XAML:

<ListView ... >
                <b:Interaction.Behaviors>
                    <i:GestureBehavior CrossSwipeCommand="DoSomething" TapCommand="DoSomethingElse" />
                </b:Interaction.Behaviors>
....

We have other behaviours which execute commands and we’ve encapsulated some of that command execution behaviour in the following code:

public static void ExecuteCommand(this FrameworkElement associatedObject, string commandName)
{
    if (associatedObject.DataContext == null) return;
    
    new CommandProxy(associatedObject.DataContext, commandName).Execute();
}

public class CommandProxy
{
    readonly string _commandName;
    readonly ICommand _command;

    public CommandProxy(object dataContext, string commandName)
    {
        _commandName = commandName;
        _command = _ExtractCommand(dataContext, commandName);
    }

    ICommand _ExtractCommand(object dataContext, string commandName)
    {
        var commandProperty = dataContext.GetType().GetRuntimeProperty(commandName);
        if (commandProperty == null)
        {
            return null;
        }

        return (ICommand)commandProperty.GetValue(dataContext);
    }

    public bool FoundCommand
    {
        get { return _command != null; }
    }

    public bool Execute()
    {
        if (!FoundCommand)
        {
            throw new NullReferenceException(string.Format("Cannot execute the command as no command named {0} could be found on the instance.", _commandName));
        }
        if (!_command.CanExecute(null))
        {
            return false;
        }
        _command.Execute(null);
        return true;
    }
}

I really should set up a git repo for all the WinRT stuff discussed in the blog – hopefully I’ll get some time once the project is done.

One thing we don’t like, but couldn’t find a way around, was handling exceptions when the GestureRecognizer fires events.  We were seeing odd behaviour when beginning a gesture on an empty list then populating the list.  The gesture wouldn’t complete and would fire more events but then throw exceptions (about not having same pointer id or different frame…).  With this here the app doesn’t crash and gestures still work ok.

Posted in Uncategorized | Tagged | Leave a comment

Machine.Specifications (mspec) only output errors

Our team is very command line oriented, we’ll often run our test suit from the command line.  A typical workflow would be to commit, pull build then push (assuming we didn’t break the build!).

You’ll notice that when you run mspec from the command line you get a lot of output.  You can turn off ALL output other than the summary at the end but that doesn’t help when you want to know which tests have failed.

We use psake for our build, Adrian has already posted about integrating mspec with psake.  We made the following tweak to our build to only show test failures (we parse the XML output generated by mspec):

task MSpecUnitTests -depends Compile -description "MSpec unit tests" {
  $testDlls = ls "$srcDir\*\bin\$buildConfiguration" -rec `
    | where { $_.Name.EndsWith(".Tests.dll") } `
    | where { (Test-Path ([System.IO.Path]::GetDirectoryName($_.FullName) + "\Machine.Specifications.dll")) -eq $True } `
    | foreach { $_.FullName }

  $mspecExePath = Join-Path $packagesDir "Machine.Specifications.0.5.8\tools\mspec-clr4.exe";

  if($env:TEAMCITY_VERSION -ne $Null)
  {
      exec{ & $mspecExePath $testDlls --teamcity }
  }
  else
  {
    $mspecOutputPath = Join-Path $buildDir 'mspec.xml'
    try{
      exec{ & $mspecExePath $testDlls -s --xml $mspecOutputPath }
    }
    catch {
      [xml]$testOutput = Get-Content $mspecOutputPath
      Select-Xml "//context[specification/@status='failed']"; $testOutput | % {
        Write-Host "> " -NoNewLine
        Write-Host $_.Node.name -NoNewLine -foregroundcolor "yellow"
        Write-Host " failed the following specifications:"
        foreach ($spec in $_.Node.specification) {
          if ($spec.status -eq 'failed') {
            Write-Host ">> " -NoNewLine
            Write-Host $spec.name -NoNewLine
            Write-Host " (" -NoNewLine
            Write-Host $spec.error.message.innerText -NoNewLine -foregroundcolor "red"
            Write-Host ")"
          }
        }
      }
    }
  }
}
Posted in Uncategorized | Tagged | Leave a comment

WPF DataGrid moves input focus and selection to the wrong cell when pressing tab

You’d expect that when you hit tab in the last cell the WPF data grid it would create a new row and put your focus in the first cell of that row.  It doesn’t, depending on how you have KeboardNavigation.TabNavigation set it’ll jump off somewhere you don’t expect, like the next control or back to the first item in the grid.

I was sure I was doing something wrong because it can’t behave like this, it’s just plain unusable.  But after some time I found this which suggests it’s a bug.  So, given that it didn’t look I was missing something obvious I wrote this behavior to solve the problem:

public class NewLineOnTabBehavior : Behavior<DataGrid>
{
    private bool _monitorForTab;
 
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.BeginningEdit += _EditStarting;
        AssociatedObject.CellEditEnding += _CellEnitEnding;
        AssociatedObject.PreviewKeyDown += _KeyDown;
    }
 
    private void _EditStarting(object sender, DataGridBeginningEditEventArgs e)
    {
        if (e.Column.DisplayIndex == AssociatedObject.Columns.Count - 1)
            _monitorForTab = true;
    }
 
    private void _CellEnitEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        _monitorForTab = false;
    }
 
    private void _KeyDown(object sender, KeyEventArgs e)
    {
        if (_monitorForTab && e.Key == Key.Tab)
        {
            AssociatedObject.CommitEdit(DataGridEditingUnit.Row, false);
        }
    }
 
    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.BeginningEdit -= _EditStarting;
        AssociatedObject.CellEditEnding -= _CellEnitEnding;
        AssociatedObject.PreviewKeyDown -= _KeyDown;
        _monitorForTab = false;
    }
}

 

You use it like this:

<DataGrid ItemsSource="{Binding Stuff}" CanUserAddRows="True" CanUserDeleteRows="True" 
    AutoGenerateColumns="false" KeyboardNavigation.TabNavigation="Contained">
    <i:Interaction.Behaviors>
        <Infrastructure:NewLineOnTabBehavior />
    </i:Interaction.Behaviors>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Something}" />
        <DataGridTextColumn Binding="{Binding SomethingDifferent}" />
    </DataGrid.Columns>
</DataGrid>

 

I found that setting the KeyboardNavigation.TabNavigation to Contained behaved quite nicely.

If anyone has a better approach please let me know.  If not, I hope this saves you some time!

Posted in Uncategorized | Tagged | 5 Comments

How to create a new instance of the view for a tab item in the WPF TabControl

By default the WPF TabControl will not create a new instance of the content control inside the ContentTemplate for each Item (Tab).  All it does is just change the DataContext.  This is fine if all your state is on your ViewModel.  But I had a problem as I was hosting WinForm controls inside the tabs.  So I really want a new control for each tab.  I don’t have that many tabs.  So I’m not worried about virtualization, well yet.

The simplest thing I could think of was use a Content control, set the content to the DataContext (thus it will change each time you switch tabs) and use a Converter to return the correct view.

public class NewViewForEachInstanceConverter : IValueConverter
{
    private readonly IDictionary<object, object> _views = new Dictionary<object, object>();

    public Type ViewType { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null) return null;
        object view;
        _views.TryGetValue(value, out view);
        if (view != null) return view;

        view = Activator.CreateInstance(ViewType);
        _views.Add(value, view);

        return view;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

 

<DockPanel>
    <DockPanel.Resources>
        <Infrastructure:NewViewForEachInstanceConverter 
            x:Key="NewControlForEachInstanceConverter" ViewType="{x:Type Views:SomeView}" />
    </DockPanel.Resources>
   .....
    <TabControl ItemsSource="{Binding ThingsIWantToBeTabs}">
        <TabControl.ContentTemplate>
            <DataTemplate>
                <ContentControl Content="
                    {Binding Converter={StaticResource NewControlForEachInstanceConverter}}" />
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</DockPanel>

Note:  This implementation here is very simple and doesn’t deal with the fact that later you might well remove tabs.  This will leak because the view / view model will stay in the dictionary.  Not a problem for me yet, I’ll solve it when it becomes one.  Do the simplest thing and all.

I thought I’d share it as I saw a few people having the same problem when I double checked there wasn’t a built in way.  Hope it helps.

Posted in Uncategorized | Tagged | Leave a comment

Silverlight DataGrid RowDetailsTemplate data context issue

I spent a bit of time last week wondering why I was having issues with my bindings.  Hopefully this will help someone who finds the same issue…

Here’s a simple example of the problem I was having:  I had a data grid showing a summary of the customers, it could be expanded to see the detail of the customer.  My detail view was a user control already written which required it’s data context set correctly; it assumed it was bound to the CustomerDetail object, not the CustomerSummary.

Here’s the XAML I wrote:

<Grid x:Name="LayoutRoot" Background="White">
    <Controls:DataGrid ItemsSource="{Binding }" AutoGenerateColumns="False">
        <Controls:DataGrid.Columns>
            <Controls:DataGridTextColumn Header="Title" Binding="{Binding Title}" />
        </Controls:DataGrid.Columns>
        <Controls:DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <Grid DataContext="{Binding Detail}">
                    <TextBlock Text="{Binding Description}" />
                </Grid>
            </DataTemplate>
        </Controls:DataGrid.RowDetailsTemplate>
    </Controls:DataGrid>
</Grid>

 

Imagine the Grid inside the DataTemplate of the RowDetailsTemplate is my CustomerDetail user control.  As you can see I’ve set the DataContext to the Detail.  But when I expand it I get a binding error:

System.Windows.Data Error: BindingExpression path error: 'Description' property not found on 'Example'  ....

 

After some investigation I found that the grid propagates the data context to the root element in the data template by setting it to the data context of the row you’ve expanded.  However, if you’ve already set a data context it will not propagate it.  So changing the RowDetailsTemplate to this, it works:

<Controls:DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <Grid>
            <Grid DataContext="{Binding Detail}">
                <TextBlock Text="{Binding Description}" />
            </Grid>
        </Grid>
    </DataTemplate>
</Controls:DataGrid.RowDetailsTemplate>

 

The superfluous Grid has no data context, so it is automatically propagated.  I can put my user control in that grid and set the data context as I required.  I’m pretty sure this is a bug but it’s easy enough to work around.  Once you figure out what’s going on!

Posted in Uncategorized | Tagged | 1 Comment

Silverlight GotoStateAction not setting state on load

I can’t decide if this is how it’s meant to work or not.  It feels wrong…  Jason and I spent a fair amount of time today in reflector because I was having some strange behaviour in a list box.  The items didn’t have the correct visual states until I scrolled through them.

The reason why it doesn’t change visual state on load is because the StateTarget property of the GotoStateAction is null at the time the DataTrigger fires.

Once I found this out I was able to do a bit more targeted Googling…  My Google-fu was off and I couldn’t find anything to start off with.  I found this article which points out that the Style Manager in WPF and Silverlight is imperative.  The way they work around it is to create an attached property which can set the state.

You don’t notice this behaviour all the time because a lot of the time the control you’re binding to is already loaded…  If you call a service you’ll set the values once the service call completes, well after the view has loaded.  But when you’re calling a service and adding items to a list the list item hasn’t been loaded yet.  So I think it’s nasty behaviour (at least in this context), especially when in a virtulising list and it unloads / reloads the items thus changing the state!  Bug, I’m not sure…  Annoying, certainly!

What I’ve done to work around it (yet to do exhaustive testing on this but I don’t see many issues with it) is create a new trigger.  I’ve derived DataTrigger and overloaded attach / detach.  In attach I hook up to the Loaded event and call EvaluateBindingChanged.  This invokes all the attached actions and this time the StateTarget will be set.  I did think about extending GotoActionState but I thought that other actions might suffer the same problem…

So if you want to have your DataTriggers fire on load, try the code below.  I’m going to give it a go and I’ll report back any problems I find…

public class DataTriggerWhichFiresOnLoad : DataTrigger
{
    protected override void OnAttached()
    {
        base.OnAttached();
 
        var element = this.AssociatedObject as FrameworkElement;
        if (element == null)
        {
            return;
        }
        element.Loaded += InvokeActionsOnLoad;
    }
 
    protected override void OnDetaching()
    {
        var element = this.AssociatedObject as FrameworkElement;
        if (element != null)
        {
            element.Loaded -= this.InvokeActionsOnLoad;
        }
        base.OnDetaching();
    }
 
    private void InvokeActionsOnLoad(object sender, RoutedEventArgs e)
    {
        this.EvaluateBindingChange(null);
    }
}
Posted in Uncategorized | Tagged | 7 Comments