Sprydon

Richard Harding's spot on the web

AspNet Web API 2.2 Odatav4, Swagger, Swashbuckle and Glimpse

Recording this here as I know I’ll hit this again on some other project…

I wanted to add Swagger api documentation to an existing OData v4 API, something I had done a couple of times before using the Swashbuckle and Swashbuckle.OData projects. But for some reason this time it would not work  - the json doc and the SwaggerUI were there but there was no content – the paths collection in the swagger doc was empty – I suspected it had something to do with the way Swashbuckle.OData was building the API descriptions but nothing looked odd in teh way I had configured the OData routes. In the end I cloned out the Swashbuckle.OData project and built locally so I could debug (this was further hampered by the project using Code Contracts – a good thing, but not currently supported in VS2017).

I quickly traced the problem to an extension method:

internal static IEnumerable<ODataRoute> GetODataRoutes(this HttpConfiguration httpConfig)
        {
            Contract.Requires(httpConfig != null);

            return FlattenRoutes(httpConfig.Routes).OfType<ODataRoute>();
        }

The route collection had a count of 12 but the call to select routes of type ODataRoute was returning zero results – when I examined the private field holding the collection the routes were all of type Castle.Proxies.RouteProxy – a quck Google search turned up the answer in this groups message – I had added Glimpse and in the version I had they replaced the routes with proxies  - this has been fixed in versions of Glimpse.AspNet later than 1.8.0 (the version I was on) – updating to a later version fixed my Swagger issues

IIS Express “Access Denied” Cryptographic Exception when creating X509 cert from file

Adding this here so I can find it when it happens again!

After a recent Windows 10 update (I’m in the insider fast ring so who knows what changed) I found that an ASP.Net MVC app no longer ran under IIS Express. As part of the app code it was creating an X509 Certificate by loading a pfx file from the file system

var signingCertPath = @"D:\FooCert.pfx";

var cred = new X509SigningCredentials(new X509Certificate2(signingCertPath, "FooPassword", X509KeyStorageFlags.MachineKeySet));

This was resulting in a Cryptographic exception being thrown with the message “Access Denied” and little else to go on.

I suspected is was permissions on the machine key folder (eg C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys) but adding my account to that folder with full control made no difference however, removing the MachineKeySet flag allowed the cert to be loaded.

I eventually resorted to using procmon (sysinternals procmon) to see what was generating the access error – it turned out to be the C:\ProgramData\Microsoft\Crypto\Keys folder — adding my account with full control on that folder allowed the cert to load (still no idea why an update had changed this)

DotNet Core testing local cli tools

The new xml project file format csproj includes the facility to restore a package for use in the build process (see docs here) it replaces the

When building a tool package that a project could use its not immediately obvious how to test the unpublished local version of the tool

Given an entry like

<ItemGroup>
  <DotNetCliToolReference Include="SpecFlow.NetCore" Version="1.0.0-rc8" />
</ItemGroup>

The build process will restore the SpecFlow.NetCore package from Nuget rather than use a copy on the local file system. The discussion on this issue and here on the cli github repo outlines the option I eventually ended up using

Pack the tool package under development specifying a suitable local area eg

dotnet pack -o ../mynugetcache

Then in the consuming project add a Nuget.Config file to add the local area as an addition feed eg

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="test-packages" value="../mynugetcache" />
  </packageSources>
</configuration>

I found that as my consuming projects had already installed the public version I needed to delete from my local cache

%UserProfile%\.nuget\packages

And also delete the lock files in the projects obj folder

Visual Studio 2017RC Unable to repair or uninstall a fix

Recently while trying to update from RC3 of Visual Studio 2017 to RC4 I managed to get into a loop whereby the installer (which is a vast improvement) could not repair or uninstall  VS2017 – even attempting to remove via the Control Panel – Programs and Features didn’t seem to work – each time I re-ran the installer to try and get the latest version it detected the existing broken install but was unable to repair or remove.

I found the answer on the forums here  - there is a tool InstallCleanup.exe which lives in C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\layout

I needed to run it as administrator  - the first attempt didn’t seem to work  - it seems to fail silently if it doesn’t have sufficient privileges to remove packages and registry keys. Once I ran it I could start the installer and carry out a clean install of RC4 – since RC3 I’ve been using it as my main IDE and seems pretty stable

Custom activity to tag sources in git from TFS

The problem

I want to be able to trace an assembly back to the source that was used to build it, the way I usually accomplish this is to have the continuous integration server set the assembly version (including file version) based on some auto incrementing build number and incorporate that same build number in a source control label. Then given an assembly I can use its version to pull the source that built it.

However while there is a built in activity to label workspace files for the TFS Source control repository it doesn’t seem to support the Git repository option which seems like a strange omission.

The TFS Community extensions don’t have anything suitable either

The Solution – Custom Activity & Libgit2sharp

I took a look at the source of the built in activities that interact with Git – especially the InitializeEnvironment activity that clones the repository. They all use the libgit2sharp library to interact with the TFS git repository, so using the examples on project wiki I put together a quick test to check I could apply and push a tag

   1:  using (var repo = new Repository(@"c:\repos\MyTestRepo"))
   2:              {
   3:                  var tagName = "MyTagName";
   4:                  var tag = repo.ApplyTag(tagName);
   5:                  var remote = repo.Network.Remotes["origin"];
   6:                  var pushOptions = new PushOptions { Credentials = new DefaultCredentials() };
   7:                  repo.Network.Push(remote, string.Format("refs/tags/{0}:refs/tags/{0}", tagName, pushOptions));
   8:              }

 

That worked, so the next step was to build a custom activity that I could add to a build template - Martin Hinshelwood has a great blog post that helped me to get started with the custom activity and again referring to the source of the built in activities helped with extracting some of the arguments like source directory paths and build numbers.

Once you have your activity you need to get it deployed to the build agents, the process is to add the assembly and any dependencies (in this case the libgit2sharp.dll and the native binaries it uses) to a Git repository and configure the Custom Assemblies property of the build agents – this process is well documented on the Community TFS Extensions codeplex site.

Logging

This of course did not work first time….so I needed to add some logging I copied the example shown in this forum post 

context.Track(new BuildInformationRecord<BuildMessage>
                              {
                                  Value = new BuildMessage
                                              {
                                                  Importance = BuildMessageImportance.High,
                                                  Message = message
                                              }
                              });

This threw up an odd situation  - its possible for the call to Network.Push method to fail and not throw an exception – in my case it was because the service account that the TFS Build agent was running under did not have the necessary Write permission to create the tag – the PushOption object has an event handler to catch errors  - use this to see these kinds of issues and log them to the diagnostics log for the build.

I’ve put together a sample activity and the source is on my GitHub

Developer Developer Developer South West 5

Some notes from this weekends DDDSW and to mostly fill in the gaps from Nathan Gloyn’s write up.

Sessions I attended:

Session 1: Steve Sanderson's  - Architecting large Single Page Applications with Knockout.js

Lots of interesting background on the use of Typescript on the new Azure management portal – main takeaways

Beware preloading large amounts of data and check for memory leaks

New components feature in Knockout - https://github.com/knockout/knockout/issues/1273

Use of Yeoman Steve has a generator for a Knockout based web app - https://github.com/SteveSanderson/generator-ko this was worth a look at as it uses a number of JavaScript libraries I’d not come across including JsSignal for messaging and crossroads for routing

Good demo of the Karma test runner – like NCrunch for JavaScript tests

Session 2: Marc Gravell — Redis cluster— everything you need to know

Nathan was in the same session – check out his write up

Except to note that there are Nuget packages for including a Redis server in an ASP,Net app or you can use chocolaty to install

Session 3: Phil Trelford — F# eye for the C# guy

A very entertaining presentation by Phil with some great pointers on how to get started with F#, Phil’s approach is to start with writing tests in F# and then move on to writing the domain layer. He gave a compelling demonstration of how terse the F# code is compared to its C# equivalent.

Worth taking a look at his version of SpecFlow – TickSpec

Also for getting started he suggests taking a look at the F# Koans on GitHub

He also has a book coming out soon - F# Deep Dives

Session 4: Gary Short — Hadoop and Big Data for Microsoft Developers

Big Data is all the rage right? – Gary went on to explain what Data Science is really about and that size is not all that counts.

A couple of good demos on how C# can be used to write Map Reduce implementations and make the hadoop command line easier to write!

Plus a demo on using PowerView in Excel to connect to a hadoop file system to query results

There are Microsoft authored packages on nuget

MS Supported Hadoop on windows server

Session 5: Mauro Servienti —​A gentle introduction to AngularJS

This was a good contrast to Steve Sanderson's talk in the first session with further clarification of when Angular is a good fit, impact on page size etc

Slides from the presentation

Mauro’s blog

Closing

All in all a great day and another year when I didn't win anything in the raffle Sad smile

Working with AChartEngine and Xamarain Android

I’m starting a new mobile project on android using Xamarin and needed a charting engine to display some data, there are a few existing component choices in the Xamarin component store one free one – bar chart but it (as the name suggests) only does bar charts and as far as I can tell can’t display multiple series at the same time. The other choices look great but cost real money and I needed to spike something without investing too much cash. A quick search for any open source options revealed a few options but none with any xamarin bindings as part of the existing code base leaving a final option of building a binding library myself.

According to the docs creating a binding library should be a fairly simple process but they do hint at having to fix up issues by hand which is where I ended up with AChartEngine – I downloaded the 1.1.0 jar file, created a new bindling library project, added the jar and build

At first it looked like I almost got away with it as I only had a single error

C:\Users\richard\Documents\GitHub\AChartEngine.Xamarin\AChartEngine.Xamarin\obj\Debug\generated\src\Org.Achartengine.Tools.Pan.cs(29,29): Error CS0542: 'Pan': member names cannot be the same as their enclosing type (CS0542) (AChartEngine.Xamarin)

So according to the docs I needed to do a bit of renaming using the metadata.xml file in the transforms folder so I added the following to the metadata mapping file to rename the event handler

<attr path="/api/package[@name='org.achartengine.tools']/class[@name='Pan']/method[@name='addPanListener']" name="eventName">PanEvent</attr>

and it turns out this is going to be an iterative process as it just allowed the compile to move into the next errors

obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(206,9,206,46): error CS0019: Operator '!=' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(208,8,208,160): error CS1502: The best overloaded method match for 'Android.Runtime.JNIEnv.StartCreateInstance(System.IntPtr, System.IntPtr, params Android.Runtime.JValue[])' has some invalid arguments

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(208,60,208,70): error CS1503: Argument 1: cannot convert from 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' to 'System.IntPtr'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(208,72,208,142): error CS1503: Argument 2: cannot convert from 'string' to 'System.IntPtr'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(208,144,208,159): error CS1503: Argument 3: cannot convert from 'Android.Runtime.JValue' to 'Android.Runtime.JValue[]'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(263,10,263,37): error CS0019: Operator '==' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(274,10,274,37): error CS0019: Operator '==' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(305,9,305,36): error CS0019: Operator '==' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(335,9,335,36): error CS0019: Operator '==' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

    obj\Debug\generated\src\Org.Achartengine.Renderer.XYSeriesRenderer.cs(369,9,369,36): error CS0019: Operator '==' cannot be applied to operands of type 'Org.Achartengine.Renderer.XYSeriesRenderer.FillOutsideLine.Type' and 'System.Type'

 

So after a bit of googling looks like all I need to do is remove the offending types from the binding library (at this stage I’m not sure whether I’ll need to instantiate these types from the c# side but I hope not) so I added a few more lines to the metadata

<remove-node path="/api/package[@name='org.achartengine.renderer']/class[@name='XYSeriesRenderer.FillOutsideLine']"/>

And this time it compiles with no errors – I ran a quick test project to prove I could make use of the library and it worked, its not clear yet whether I’m going to need that class exposed in the binding or if there was a better way to resolve the binding errors.

Find the source on github