Wednesday, 3 February 2016

Ignoring parameters in Swashbuckle

I’m working with a WebApi that is passed the HttpRequestMessage class which is always available in the ASP.NET WebApi pipeline. However, when the documentation is exposed in Swashbuckle, I get a textbox that shows up where it expects me to enter a value for this parameter.

The operation is defined as follows…

  public async Task Get(HttpRequestMessage request)

The problem is, when the documentation is emitted I end up with this ugly mess...

image

I set about finding a way to instruct Seashbuckle to ignore this parameter, and finding there isn’t anything in the box I set about writing a filter that would do this for me.

In Swashbuckle you can plug-in operation “filters” that can be used to alter the emitted data – the filter is passed the context of the operation being emitted, and you can monkey around with the data that pops out. All I had to do then was create a filter that would look for this datatype, and remove the corresponding data from the results. I ended up with this…

  public class IgnoreHttpRequestMessageOperationFilter : IOperationFilter
  {
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, 
                      ApiDescription apiDescription)
    {
      apiDescription.ParameterDescriptions
        .Where(desc => desc.ParameterDescriptor.ParameterType 
            == typeof(HttpRequestMessage))
        .ToList()
        .ForEach(param =>
        {
          var toRemove = operation.parameters
            .SingleOrDefault(p => p.name == param.Name);

          if (null != toRemove)
            operation.parameters.Remove(toRemove);
        });
    }
  }

With that class in place, I just needed to plug this in to the swagger config file as follows...

  c.OperationFilter();

And Bob's you're uncle...

image

Wednesday, 6 January 2016

Auth0 and 401 Unauthorized

Today was One of those days™ where things just didn’t work well, or rather at all. I’ve been working on an ASP.NET WebAPI that was working fine against Auth0, but needed to update it to use OWIN. It took a while to update everything and get the appropriate packages installed, and then I went through the code and ripped out the old and replaced with the new.

The API is called using a bearer token that is retrieved from Auth0 – example code below…

  var uri = ConfigurationManager.AppSettings["auth0:Domain"];
  var client = new HttpClient { BaseAddress = new Uri(uri) };
  var data = new LoginRequest
  {
    Username = model.Username,
    Password = model.Password,
    ClientId = ConfigurationManager.AppSettings["auth0:ClientId"],
    Connection = ConfigurationManager.AppSettings["auth0:Connection"],
    GrantType = "password",
    Scope = "openid"
  };

  var response = await client.PostAsJsonAsync<LoginRequest>("oauth/ro", data);

  if (response.IsSuccessStatusCode)
  {
    var result = await response.Content.ReadAsAsync<LoginResponse>();

    // Now use the response token...
  }

I’d written this code myself to call the Auth0 API as I couldn’t get the provided Auth0 code to work at all – the response I was getting back was always a null. The LoginRequest and LoginResponse objects simply mimicked the request and response data sent to and received from the Auth0 API that I was calling.

When I called this I received a token back – but then the problems started. Whenever I called my API, all I got back was a 401 Unauthorized response. It took me a long time to sort this, I even went to the bother of creating an entirely new solution with two web apps included, one to “login” to Auth0 and get a token, the other being the API I wished to call, so that I could raise a support incident with Auth0. I had a feeling that it must still be something I was doing wrong as I’ve used Auth0 for a while and to be fair it had previously been working fine until I did this upgrade.

It got to the point where I needed to get some help, and that came in the form of Reflector. I’m sure that Red-Gate should send me a free copy the number of times I’ve mentioned it in my blog. Not that I mind paying for it, it’s a fantastic tool. Anyhow, after some spelunking through the code I found that the Owin pipeline has a logging component, and also found out how to enable it. I added the following to my web.config (this was in the callee project)…

  <system.diagnostics>
    <switches>
      <add name="Microsoft.Owin" value="Verbose" />
    </switches>
  </system.diagnostics>

With that in place I then debugged my application and saw this in the debug output…

Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware Error: 0 : Authentication failed
System.IdentityModel.Tokens.SecurityTokenException: Issuer not known.
   at Microsoft.Owin.Security.Jwt.JwtFormat.Unprotect(String protectedText)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationTokenReceiveContext.DeserializeTicket(String protectedData)
   at Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationHandler.<AuthenticateCoreAsync>d__0.MoveNext()

Finally I had something to go on! I've worked a fair bit with JWT tokens over the last couple of years so happened to know that the issuer was one of the fields within the JWT, so then I knew that something was either not sending the right issuer, or when decoding the token on the API side the wrong issuer was being used. Now, just to be clear, I had made ZERO changes to my web.config between the old (non OWIN) version that worked, and this new version that didn't work. So I was suspicious to say the least.

So, I grabbed a copy of the token I was using and headed off to jwt.io which has a handy JWT decoder. You paste in the token and it will decode it for you, I saw this when I did mine…

HEADER:ALGORITHM & TOKEN TYPE

{
  "typ": "JWT",
  "alg": "HS256"
}

PAYLOAD:DATA

{
  "iss": "https://redacted.com/",
  "sub": "auth0|568bf53557c21c88287d9b03",
  "aud": "P7H7jdzZ4pSc9ifPU2XS7y03HXfcOYHG",
  "exp": 1452069269,
  "iat": 1452033269
}

The important part was that the issuer looked correct to me, so I then went looking at the API project to see what it was defined as there. In the web.config (which was simply copied from the Auth0 sample) I had this...

  <add key="auth0:ClientId" value="....." />
  <add key="auth0:ClientSecret" value="....." />
  <add key="auth0:Domain" value="redacted.com" />
  <add key="auth0:Connection" value="....." />

BINGO!

The auth0Domain value did not include the scheme or trailing slash, and this was being used by the Auth0 code as the issuer. With this knowledge I simply updated the web.config to https://redacted.com/ and sure enough my code started working again.

Hopefully this helps someone else, it took me quite a while to solve!

Thursday, 28 May 2015

Windows Live Writer no longer works with Blogger

I'm not a frequent blogger, so have only been bitten by this issue today - but checking the internet for clues it seems I'm not the only one. I wrote a long blog post in Live Writer and then tried to upload it, only to see this error message come up...

Being a geek I looked into this further and found that it was an issue with how Windows Live Writer authenticates (i.e. logs in) to Blogger. Google have disabled the mechanism that WLW was using, and so at this present moment (28th May 2015) you can't use WLW with a Blogger account. Pants.

There is currently no workaround (for WLW that is) - you simply cannot use it.

If you're on the Blogger platform you can use their tools to blog with (that's what I'm using here), or try out some other blog tools on the web. For now I'll limp along with the Blogger UI, it's OK - but nowhere near as easy to use as Windows Live Writer. Sadly it seems that Microsoft are no longer maintaining WLW, so you may be waiting a long while for a fix.

Adventures in Application Insights - Part 1

If, like I was, you’re struggling to get anything out of Azure Application Insights, I hope to be of some help.

It all started well enough – I added App Insights to a web app, this setup the ApplicationInsights.config file for me and boom, I had some data in App Insights on the web. Then I wanted to write a custom event to the cloud so I added the following code into the app…

  var tc = new TelemetryClient();
  tc.TrackEvent("Testing");
  tc.Flush();

I ran my app and imagine my dismay when nothing happened. I checked around in blog posts, looked at the official documentation, tried a bunch of things – but stubbornly the above lines of code simply didn’t want to work for me.

Instrumenting a Console App

The web project I’m adding this to isn’t the simplest, so rather than hack it around too much I then decided to create a simple Console App and debug through it to see what was happening. Here it is in its entirety…

using Microsoft.ApplicationInsights;
namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            var tc = new TelemetryClient();
            tc.TrackEvent("Testing");
            tc.Flush();
        }
    }
}

Not a great deal going on there! Having seen the ApplicationInsights.config file in the other project I added one to my console app too – well, I copied it from the web app to be fair. I ran the app and once again – nothing. At that point I decided it was time to do some debugging – but I couldn’t find symbols for Microsoft.ApplicationInsights.dll (and others from the App Insights stable), so I dragged out my trusty copy of Reflector and created some. If you didn’t already know, Reflector can generate missing PDB’s for you, it’s cooler than a penguins chilly bits and well worth the cost.

With a .pdb in hand I then stepped into the TrackEvent method and further down the call chain until I got to this point in the code…

[EditorBrowsable(EditorBrowsableState.Never)]
public void Track(ITelemetry telemetry)
{
  if (this.IsEnabled()
  {
    string instrumentationKey = this.Context.InstrumentationKey;
    if (string.IsNullOrEmpty(instrumentationKey))
    {
      instrumentationKey = this.configuration.InstrumentationKey;
    }
    if (!string.IsNullOrEmpty(instrumentationKey))
  ...

When I inspected the instrumentationKey it was empty - and this indicated to me that despite having an ApplicationInsights.config file, this wasn't actually being picked up. A quick look on disk and I saw that the file wasn't in the same directory as my .exe, so I went back to the app and set the properties of the file as shown below...

The main thing to note is that I changed Copy To Output Directory. With that altered I ran the app again and this time Boom, it threw an exception…

Drilling down on the exception the root cause was this…

{"Type 'Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry.RemoteDependencyModule, Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry' could not be loaded."}

The Config File

This alerted me to the content of the .config file that I'd blatantly copied and pasted from the web project, and opening it up it was evident what was happening - I'd 'told' it to load some types that didn't exist in my simple console app - or rather, the file I copied across included a bunch of types that were not referenced...

<?xml version="1.0" encoding="utf-8"?>
<?XML:NAMESPACE PREFIX = "[default] http://schemas.microsoft.com/ApplicationInsights/2013/Settings" NS = "http://schemas.microsoft.com/ApplicationInsights/2013/Settings" /><applicationinsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
  <!-- 
    Learn more about Application Insights configuration with ApplicationInsights.config here: 
    http://go.microsoft.com/fwlink/?LinkID=513840
    
    Note: If not present, please add <InstrumentationKey>Your Key</InstrumentationKey> to the top of this file.
  -->
  <telemetrymodules>
    <add type="Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.DiagnosticsTelemetryModule, Microsoft.ApplicationInsights"></add>
    <add type="Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry.RemoteDependencyModule, Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry"></add>
    <add type="Microsoft.ApplicationInsights.Extensibility.PerfCollector.PerformanceCollectorModule, Microsoft.ApplicationInsights.Extensibility.PerfCollector">
...

Here the TelemetryModules section is quite clearly defining a bunch of plug-ins, the first exists (as it's in Microsoft.ApplicationInsights which I have referenced), the second and third do not and sure enough the second is the subject of the exception I received. Armed with this knowledge I did a hatchet job on the .config file and removed anything I didn't have referenced from Nuget or directly. I then ran the app again and to my dismay - still nothing happened. I was expecting to see an HTTP Post request flying over the wire to Azure, but instead there was nothing.

Flush, aha, he saved every one of us!

(Sorry for the abysmal pun, I couldn’t help myself). I did a bit more digging on the TelemetryClient and found the Flush() method which I have added into the code samples above, but didn't have in my code at the time. With this added I was delighted to see a message show up inside Visual Studio that alerted me to the fact that I had managed to send an event to Azure..

I also saw this pop up in Fiddler...

So far so good. I then logged into Azure and lo and behold, I got my event!

I could even drill down and see “more” data about the event…

OK, so “more” data is somewhat subjective, but it did tell me that my event came from the UK which is correct. I have no doubt that I could augment the data being collected from my application so that the amount of detail here would be better.

Looking at what was sent to the server, it’s a simple JSON request as follows (I’ve blanked out my App Insights key, which I’m surprised to find twice in the content. If I’d designed this, the app insights key would have been a custom header, but that’s just an aside)…

And there you have it – one event in Azure, an hour or more messing around with it to understand what it’s doing, and I’ve got a load closer to working out why my web app wasn’t sending any telemetry (or rather, the custom telemetry I was expecting to send).

I hope that helps someone else! Next time I’ll see what’s up with my web app.

Sunday, 10 May 2015

Process Monitor saves the day

For some time now on my main development machine I’ve been having issues – Visual Studio has begun taking an extremely long time to load, and when running or debugging web apps these too have been taking too long to startup.

It’s one of those issues where you put off fixing it for a while as it’s not too bad, but then it gets to the point where it’s really hampering the dev/test/debug cycle, so this morning I set about working out what it could be. I disabled the extensions I have loaded and that made little difference, so then went to ProcessMonitor to see if I could work out what was happening.

In the case of Visual Studio, it would take around a minute to start a fresh copy. This was way too long. For websites, it was maybe 30 seconds or so – again, way too long. With process monitor running I created a new instance of Visual Studio, waited until it was done, and then paused event capture and went to have a look into the events.

It wasn’t long before I noticed a *lot* of files being written to the C:\logs directory – on my machine I keep this for one of two file types, actual log files from my code, and log files from the assembly log viewer, FusLogVw.exe. Smoking gun in hand I had a quick look at the size of the Logs directory and it was up to 8GB! Oops.

A small while later (after disabling FusLogVw.exe and deleting the files), I’m back to snappy performance with VS loading in about 4 seconds, and websites in a second or so.

Normal service resumed. Phew!

Wednesday, 28 January 2015

Xamarin Forms contacts search

I’m in the middle of writing a Xamarin Forms app and today I needed to add in a contacts search page, and remembered that James Montemagno had created a plugin that exposes contacts in a platform neutral manner so I downloaded it and used it in my app.

I also wanted to add a search bar, and again there’s a control in XF for that, so I ended up with (somewhat simplified) the following XAML…

  
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<SearchBar x:Name="search" Placeholder="Search">
</SearchBar>
<ListView Grid.Row="1" ItemsSource="{Binding FilteredContacts}"
IsGroupingEnabled="true" GroupDisplayBinding="{Binding Key}"
GroupShortNameBinding="{Binding Key}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" TextColor="Black"
Detail="{Binding PhoneNumber}" DetailColor="Gray">
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>

I have removed some of the XAML as it’s not that important to this post (it’s available in the download). Now, with that in place (and a load of code in the view model which I’ll get to in a minute) I got a UI as follows…


iOS Simulator Screen Shot 28 Jan 2015 22.32.19


So far so good. Then I needed to hook up the search box, and as I’m using XAML (and if you’re not, you should give it a try as it’s way easier to create UI’s using it) I needed a way to bind to the search box to that I could respond to the TextChanged event.


Another excellent package that you’ll want to use it the Xamarin.Behaviors package by Corrado – massive thanks to him for putting this together, it’s excellent!


Behaviors to the rescue


By adding a behavior into the XAML, I can handle an event – so in this case I added the following to the SearchBar…

  <SearchBar x:Name="search" Placeholder="Search">
<b:Interaction.Behaviors>
<b:BehaviorCollection>
<b:EventToCommand EventName="TextChanged"
Command="{Binding SearchTextChanged}"
CommandParameter="{Binding Text, Source={x:Reference search}}"/>
</b:BehaviorCollection>
</b:Interaction.Behaviors>
</SearchBar>

This hooks the TextChanged event of the search bar, calls the SearchTextChangedCommand on my view model, and passes through the value of the Text property of the search bar. Yay!.


Or not.


The problem I found was that my command was being passed a string, but it was the text before the ne character was entered, so say I pressed ‘X’ in an empty search bar, my code would be called with an empty string. Pressing ‘A’ next, my command would get ‘X’, and pressing ‘M” next, my code would get ‘XA’. I was always getting the data just prior to the new character – so I guess that the TextChanged event should be more clearly termed as the TextChanging event.


Anyway, I needed to fix this – so looked at the actual event and it contains two properties, the current text and the new value. All I needed to do was get the new vale of the event arguments and I’d be away.


To the best of my knowledge there is no way to bind to the event arguments, you need to write some additional code (this was true in WPF and Silverlight, I’ve done exactly the same there too). So, I cranked out a new behavior that attaches to the SearchBar’s TextChanged event, and calls the command with the new value of the text property. My XAML is therefore this…

  <SearchBar x:Name="search" Placeholder="Search">
<b:Interaction.Behaviors>
<b:BehaviorCollection>
<bh:SearchBarTextChanged Command="{Binding SearchTextChanged}"/>
</b:BehaviorCollection>
</b:Interaction.Behaviors>
</SearchBar>

Here I'm using my SearchBarTextChanged behavior to hook to the SearchTextChanged command, and sure enough now when I type in the search bar I get the desired effect. Excellent!


Filtering in code


In the view model I use James’ contacts plugin to select all contacts that have a mobile phone, and that have at least a forename or surname (my real code blew up on a colleagues iPhone as he has a contact with just a company name). I tuck this list away as the source, and then create a filtered collection from the source and the filter statement.

CrossContacts.Current.PreferContactAggregation = false;
var hasPermission = CrossContacts.Current.RequestPermission().Result;

if (hasPermission)
{
// First off convert all contacts into ContactViewModels...
var vms = CrossContacts.Current.Contacts.Where(c => Matches(c))
.Select(c => new ContactViewModel(c));

// And then setup the contact list
var grouped = from contact in vms
orderby contact.Surname
group contact by contact.SortByCharacter into contactGroup
select new Grouping (contactGroup.Key, contactGroup);

foreach (var g in grouped)
{
_contacts.Add (g);
_filteredContacts.Add (g);
}
}

The above code uses some Linq to select all contacts and group them by first character of their surname. I created a simple Matches(contact) function that checks that the contact has a mobile phone number and also that they have one of forename or surname.


Then I have the code that is called to filter the collection when you type text into the search bar...

private void FilterContacts(string filter)
{
_filteredContacts.Clear ();

if (string.IsNullOrEmpty(filter))
{
foreach (var g in this.Contacts)
_filteredContacts.Add (g);
}
else
{
// Need to do some filtering
foreach (var g in this.Contacts)
{
var matches = g.Where (vm => vm.Name.Contains (filter));

if (matches.Any())
{
_filteredContacts.Add (new Grouping (g.Key, matches));
}
}
}
}

This is a bit ropey but does the trick. As the collection is an ObservableCollection, any changes are shown in the UI immediately.


Code


I’ve created a simple example project (the one shown above) that you can download. Hopefully this will help someone out. I’ve not tried this on Android or Windows Phone as yet, but as none of the code is in the platform specific library I can’t see any reason for it not to work on those platforms too.


Bye for now!

Friday, 23 January 2015

Xamarin Forms Navigation–Dealing with Login

This is the third in a series of posts on Xamarin Forms – in this instalment I want to add login capability to my app, but this isn’t as simple as I thought it would be. I’m used to crafting interfaces with XAML in WPF and Silverlight, and have been doing so for several years now, but with Xamarin Forms things are a little different.

Here’s what I want to be able to do, courtesy of Visio…

image

When the app starts up I’ll check if the user has a valid token, and if so skip the login part and go straight to the main page.

If however the user hasn’t yet logged in I want to show a “carousel” where I can do some app advertising, then let them choose from one of the login providers I’ve integrated, and once logged in show the main form. The gnarly part here is the navigation support – once at the MainForm stage I don’t want to allow the user to “back out” into the login part, and so far on the intertubes I’ve not seen a clear way of doing this so looked into this myself.

I’m using Xamarin Forms 1.3 which has improved navigation support, so the first thing I tried was a main form that cleared out the navigation stack when it showed up. This worked to a fashion, in that the back-stack was cleared, but it left a “< Back” button on the navigation section when I arrived at the main form, and that was less than ideal.

After trying some other options (non of which panned out) I went back to first principles and looked at how the application startup sequence worked, and from that arrived at a simple solution – at the point where I need to display the main page, I simply call the following…

    var nav = new NavigationPage(new MainPage());
nav.BarBackgroundColor = Color.FromHex("#195174");
nav.BarTextColor = Color.White;

Application.Current.MainPage = nav;

And boom - the main page is shown and there's no previous pages that can be navigated to.

I’d originally created my main page and set that as the root, then coded the login forms as modal, and whilst that worked OK it had the undesired behaviour of showing the main form first (briefly), then navigating to the login page. That wasn’t particularly great as I want login to be the first thing seen when the application is run for the first time.

The downside of my approach here is that there’s no transition between the last login page and the main form, I haven’t found a way to do that at the moment.

I’m not sure if this is the best method either – however there doesn’t seem to be (or I cannot find) any alternatives that work quite how I want them to. I want to be able to use navigation during login, as I have a carousel page and then a provider selection page (and maybe more pages after that, once I’ve written them!), so using a Modal login page doesn’t suit my purposes.


Demo Code


If you would like to grab my example project please download it here. The structure is deliberately simple (I usually use Autofac and XAML in my projects, this has neither as there’s less to setup). When you run the app you’re on the carousel view which consists of three pages…


IMG_1304    IMG_1305    IMG_1306


I’m using a carousel here and a timer to move between the images, you can swipe too should you wish to. When you click on the “Providers” button a new page is shown, where you would ask the user to choose their login provider. I’ve cheated and just shown a login button…


IMG_1307


When the Login button is clicked I construct a new navigation page and the main page within it, and then set the application root page to this combination using the code shown above which gives the main page shown below.


IMG_1308




You can navigate elsewhere using the button…


IMG_1309  IMG_1310


And you can navigate directly back to the root page when you’re on the “At the end” page.


Conclusion


In this example I’ve attempted to show how you can “break out” of the navigation hierarchy and start a new navigation stack. There may be a better way to do this and if so please let me know!