Thursday, 23 October 2014

ComboBox binding in Workflow activities

Today I was creating a simple activity with a couple of combo boxes, and came across a problem where the binding wasn’t working correctly (well, at all). I had an InArgument<string> property on my activity, and wanted to set this from a combo box on the design surface. I guess I haven’t done this before as it doesn’t work out of the box, and you need to write an IValueConverter to get it working. I’ve trodden this path before but this was a bit of a tricky beast.

After some wailing and gnashing I came up with the following base class converter…

public abstract class ComboBoxToModelItemConverter<T> : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
T retVal = default(T);

ModelItem mi = value as ModelItem;

if (null != mi)
{
var arg = mi.GetCurrentValue() as InArgument<T>;

if (null != arg)
{
var expression = arg.Expression;
var literal = expression as Literal<T>;

if (null != literal)
retVal = literal.Value;
}
}

return retVal;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return new InArgument<T>((T)value);
}
}





I then created a concrete class to bind to InArgument<string>…

public class ComboBoxStringToModelItemConverter : ComboBoxToModelItemConverter<string>
{
}



With that created I could then get the binding to work by adding the converter to the binding. I have a class that contains TemplateId and Name, I wish to show the Name on screen but store the TemplateId (and this is mapped to an InArgument<string> on the activity). The XAML is as follows…

<local:ComboBoxStringToModelItemConverter x:Key="comboConverter"/>


<ComboBox ItemsSource="{Binding Templates}" 
SelectedValue="{Binding ModelItem.TemplateId, Converter={StaticResource comboConverter}}"
SelectedValuePath
="TemplateId" DisplayMemberPath="Name" />



With that done it all works as expected. I’m surprised that a converter such as this doesn’t exist in the Workflow libraries – and also in the many, many years I’ve been playing with Workflow that I’ve not needed one. Anyhow, I hope this is of use to someone!

Tuesday, 30 September 2014

Fun with ExpressionTextBox

After a short hiatus doing other things (a lot of back-end services work) I’m back in the fray with Workflow.

Yesterday, a colleague asked me to help out with an activity he was building that works like a combination of an If and a ForEach. The basic premise is that we have a List<Something>, and want to iterate through that list until we find a match with a Predicate<Something>, in which case we then schedule a child activity.

So, I came up with the following…

image

Here we have a collection of Noodle’s (as an argument called Stuff), and we’re going to iterate through all elements in the collection until we find the first that matches the predicate (x => x.Name == “Sausages”). When found, we then execute the Body activity, with item as the variable holding the selected Noodle instance.

The activity code is fairly simple…

    public class Find<T> : NativeActivity, IActivityTemplateFactory
{
public InArgument<IEnumerable<T>> Values { get; set; }

public ActivityAction<T> Body { get; set; }

public InArgument<Predicate<T>> Match { get; set; }

protected override void Execute(NativeActivityContext context)
{
var match = this.Match.Get(context);

// Iterate through the collection and if we find a match, we're sorted...
foreach(var o in Values.Get(context))
{
if (match(o))
{
context.ScheduleAction<T>(this.Body, o);
break;
}
}
}

protected override void CacheMetadata(NativeActivityMetadata metadata)
{
...
}

public Activity Create(DependencyObject target)
{
...
}
}



The activity contains a collection of type T, a body that is passed the selected value from the collection, and a predicate that matches against the items in the collection. I’ve also overridden CacheMetadata to setup all of the arguments correctly, and in addition implemented IActivityTemplateFactory as there’s some setup that needs to be done when the activity is created in order to get it to work correctly. Full details are in the code download.


In the Execute method I iterate through the elements in the collection and execute the Match function against each. For the first that matches I then schedule the body activity, passing through the selected element. This then terminates the loop (that’s what we wanted, a more standard implementation might iterate though all matching elements in the collection.


The Designer


The important thing about the code is the designer (and that’s why I wrote the post in the first place). It’s fairly rudimentary, but there is something that might trip you up which is why I wrote this post.


The designer XAML contains a couple of ExpressionTextBox’s as shown in the image below…


image


The first is bound to the Values property on the activity, the second to the Match property. The important thing to note is that in order to get these to work properly you *must* use the ExpressionType property of the ExpressionTextBox…

    <sapv:ExpressionTextBox
Expression="{Binding ModelItem.Values, Mode=TwoWay,
Converter={StaticResource argToExpressionConverter}}"

OwnerActivity="{Binding ModelItem, Mode=OneWay}"
ExpressionType="{Binding ListType}"/>



Now, the type of items in the bound List is based on the type of element you choose to fill the list – in my case I have Noodles. So, the ExpressionType for the list would be IEnumerable<Noodle>, and the datatype for the predicate would be Predicate<Noodle>.


If you don’t use the ExpressionType property of the ExpressionTextBox then the text box will essentially be one-way, it will bind to values you set on the property grid, but won’t allow you to push values the other way (even if those values match 1:1 with what you type in the property grid). So, ExpressionType is mandatory, and has to be the right type.


In order to get the right type, I have created two properties on the Designer, and these call down to the underlying activity to get the actual type necessary. As an example here’s the code for the ListType…

    public Type ListType
{
get
{
if (null == _listType)
{
var findActivity = this.ModelItem.GetCurrentValue();

var valuesProp = findActivity.GetType().GetProperty("Values");

var args = valuesProp.PropertyType.GenericTypeArguments;

_listType = args[0];
}

return _listType;
}
}

private Type _listType;



This code gets the fund activity which is exposed through the ModelItem (which is a proxy object over the activity you are editing). I then lookup the Values property and return the first generic argument – in my example this will be IEnumerable<Noodle>. I have a similar property for the match predicate.


The Code


If you want to have look at the full code please click to download it…

Tuesday, 8 July 2014

Polling with Timeout in .NET 4.5

A couple of times recently I have needed to be able to wait (asynchronously) for something to happen, but also permit a timeout to occur. I wrote a version of this many moons ago that used wait handles and was pretty difficult to understand, now with async support in .NET I decided to rewrite it.

The basic premise is that I want to be able to call the following…

while (not done and not timedout)
{
if (signalFunc())
return (dataFunc());
else
wait a bit;
}


The signalFunc() is called to check that something has happened. The dataFunc() returns the actual data you are waiting for.

One of the places I need this is when trying to make a fully asynchronous pipeline in Azure look like a synchronous function to the caller. A request comes in, gets queued, gets processed, gets queued again, and gets processed again before being complete – and I want a way to hide all of this complexity from a caller so that we can provide an API that looks synchronous to the caller, but is actually asynchronous internally.


In this case I add a sentinel value to the database that the signalFunc() looks for, and then push the request into my Azure pipeline. The signalFunc() is polled repeatedly and, once the request has passed al the way through my request pipeline it updates the sentinel in the database. The signalFunc() will then report true and I can then execute the dataFunc() to find whatever it is the caller needs and return it to them.


So, after having rewritten this using async I have arrived at the following API…

public static Task<T> PollWithTimeoutAsync<T>(Func<bool> signalFunc, Func<T> dataFunc, int millisecondsBetweenPolls, int millisecondsToTimeout)



There’s also another one that includes a cancellation token. The signalFunc() is called repeatedly (with a delay of millisecondsBetweenPolls) and if true the dataFunc() is called to provide the data. The whole operation waits at most millisecondsToTimeout before throwing a TimeoutException.


The full code is as follows…

public static async Task<T> PollWithTimeoutAsync<T>(Func<bool> signalFunc, Func<T> dataFunc, int millisecondsBetweenPolls, int millisecondsToTimeout)
{
if (null == signalFunc) throw new ArgumentNullException("signalFunc");
if (null == dataFunc) throw new ArgumentNullException("dataFunc");
if (millisecondsBetweenPolls >= millisecondsToTimeout) throw new ArgumentException("The millisecondsBetweenPolls should be less than millisecondsToTimeout");

using (var cts = new CancellationTokenSource(millisecondsToTimeout))
{
bool done = signalFunc();

while (!done)
{
try
{
await Task.Delay(millisecondsBetweenPolls, cts.Token);
}
catch (TaskCanceledException)
{
throw new TimeoutException();
}

done = signalFunc();
}

return dataFunc();
}
}



It’s fairly terse (isn’t all good code like that?) and uses a feature of CancellationTokenSource which helps out a lot here, as the override I have used ensures that the token is cancelled after the period defined by the millisecondsToTimeout parameter. So, I setup a cancellation token source to go off in a few seconds, then loop calling the signalFunc() and if that reports false, use Task.Delay() to wait for a while before polling again. The beauty of Task.Delay is that it’s also cancellable by using a cancellation token, so if I’m in the middle of waiting and the overall timeout expires, the delay task will throw a TaskCancelledException, which I convert into a TimeoutException before throwing it up the chain.


Here I’m basically waiting in a loop, periodically calling the signalFunc(), but able to fail when the cancellation token timer fires. Simple and elegant!


If you want the version that also has a cancellation token then that’s here for you too…

public static async Task<T> PollWithTimeoutAsync<T>(Func<bool> signalFunc, Func<T> dataFunc, int millisecondsBetweenPolls, int millisecondsToTimeout, CancellationToken cancellationToken)
{
if (null == signalFunc) throw new ArgumentNullException("signalFunc");
if (null == dataFunc) throw new ArgumentNullException("dataFunc");
if (millisecondsBetweenPolls >= millisecondsToTimeout) throw new ArgumentException("The millisecondsBetweenPolls should be less than millisecondsToTimeout");

using (var cts = new CancellationTokenSource(millisecondsToTimeout))
{
using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancellationToken))
{
bool done = signalFunc();

while (!done)
{
try
{
await Task.Delay(millisecondsBetweenPolls, linkedCts.Token);
}
catch (TaskCanceledException)
{
// Was this a timeout?
if (cts.IsCancellationRequested)
throw new TimeoutException();
else
// No, it was most probably the outer cancellation token
throw;
}
done = signalFunc();
}

return dataFunc();
}
}
}



Hopefully someone will find this useful. If you want the code, complete with unit tests then please click here.

Wednesday, 4 June 2014

Using Data Annotations with Portable Class Libraries

I am currently writing an application that’s targeting multiple platforms – iOS, Android, Windows Phone as clients, and naturally .NET on the server which will be hosted in Azure. I’m making good use of portable class libraries, so that I can share as much code between my clients as possible (and I’m using Xamarin to make all this possible).

For my client projects I have two shared libraries – one with interfaces, another with implementations. As an example I have a DTO class on the client as follows…

public class AccountInformationRequest
{
public string Token { get; set; }

public string MSISDN { get; set; }

public string Carrier { get; set; }
}



This class is also used on the server in a controller method…

public async Task<AccountInformation> PostAccountInformation(AccountInformationRequest request)
{
return await _accountInformationService.GetAccountInformation(request);
}



On the server however I want to use data annotations to minimise the amount of code I need to write in order to validate the incoming request but this poses a problem – the AccountInformationRequest type is defined in a Portable Class Library, and if I update it to add on the data annotation attributes then my PCL will be re-targeted and won’t then run on all of my desired client platforms.


As usual in programming, another level of indirection solves every problem. Since .NET 1.0 we’ve had ICustomTypeDescriptor, and indeed one of the first articles I wrote online was about this interface (the article is long gone, it was written in 2001 ish). Since .NET 2 things have got measurably better for anyone wanting to do some spelunking with types, as it released the TypeDescriptor and TypeDescriptorProvider support. Fast forward a few more years and we now have a very simple way to augment one class with metadata from another – the massively named ‘AssociatedMetadataTypeTypeDescriptionProvider’.


What this class allows you to do is say “Hey, this class X provides metadata for that class Y”. Or more to the point for this article, “This server class which has all the attributes I need replaces the metadata for the PCL class”. All you need to do is create a second class which has all the metadata attributes you need (in my case just validation), then register it. My server side class is as follows…

public class AccountInformationRequestServer
{
[Required]
public string Token { get; set; }

[Required]
public string MSISDN { get; set; }

[Required]
public string Carrier { get; set; }
}



Then I can just register it inside Global.asax…

TypeDescriptor.AddProvider
(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(AccountInformationRequest),
typeof(AccountInformationRequestServer)),
typeof(AccountInformationRequest));



The registration looks a little cryptic, so I’ve altered it below to show the orginalClass (that being the class defined in the PCL) and the metadataClass (that being the one defined server side)…

TypeDescriptor.AddProvider
(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(originalClass), typeof(metadataClass)),
typeof(originalClass));



That’s all there is to it. Now I can make an API call from the client, and have API validation on the server, whilst still using the same datatypes in both PCL and full fat .NET.


You’ll find the AssociatedMetadataTypeTypeDescriptionProvider class defined within System.ComponentModel.DataAnnotations (in the assembly with the same name).


Wednesday, 9 April 2014

Altering the schema name of ASP.NET Identity tables

I like keeping my database schema as clean and readable as possible, and one of the things I do is use a schema name to group related functionality.

I’ve been doing a fair bit of work with ASP.NET Identity recently, and one of the things was to add the generated tables for identity into their own schema. Moreover, I also wanted to change the name of the tables. This is a snap using Code First – all you need to do (in your IdentityDbContext derived class) is the following…

    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<DbUser>().ToTable("Users", "AUTH");
    modelBuilder.Entity<IdentityUserRole>().ToTable("UserRoles", "AUTH");
    modelBuilder.Entity<IdentityUserLogin>().ToTable("ExternalLogins", "AUTH");
    modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaims", "AUTH");
    modelBuilder.Entity<IdentityRole>().ToTable("Roles", "AUTH");

Make sure you call the base class OnModelCreating method before including these changes. With that you’ll get a nice set of tables inside SQL server…

image

I realise that this will mean that I need to be careful when installing a new version of ASP.NET Identity (to ensure that the override still works), but I’d rather pay that price and have a ‘clean’ schema.

Monday, 7 April 2014

Optimizing ASP.Net Identity Database Access

I have to say I’m a bit obsessive about issuing SQL requests as they take time, and so the fewer requests I can make the better.

Recently I’ve installed the latest version of ASP.NET Identity (2.0.0.0) and whilst running SQL Profiler I noticed something odd being executed for every instance of my DbContext class. What I was expecting was one SQL statement (that being the one I was explicitly issuing), however what I actually saw in the profiler was three…


(1) SELECT Count(*) FROM sys.databases WHERE [name]=N'VPC'


(2) exec sp_executesql N'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME=@Table',N'@Table nvarchar(11)',@Table=N'AspNetUsers'


(3) SELECT
[Extent1].[PublisherId] AS [PublisherId],
[Extent1].[ApiKey] AS [ApiKey],
[Extent1].[Name] AS [Name],
[Extent1].[Description] AS [Description]
FROM [VPC].[Publisher] AS [Extent1]
ORDER BY [Extent1].[Name] ASC

The one I was expecting was #3, the other two were unexpected and also unwanted. So I had to find out where they were coming from.


When I start hunting I always think “it’s my fault, I’ve caused this somehow” – and to be honest it almost always is caused by my code. But I was pretty sure that this wasn’t my code – or at least, it wasn’t cause by my code directly. What followed was an hour or so of fruitless searching in my project – I began with an EF profiler, no change, then I added some extra debug, no change, wired up some logging for Owin to see if it was one of the bits of middleware added into the pipeline, still no change, none was telling me what I needed to know.


I then started hunting on the web, and happened to find just what I needed on www.symbolsource.org, specifically the code for the IdentityDbContext class (which was where I’d hazarded a guess the problem was). I was (as most people will do) deriving from IdentityDbContext<TUser> which I’d assumed was benign but it wasn’t. It contains the following code in the default constructor…

  public IdentityDbContext(string nameOrConnectionString)
: this(nameOrConnectionString, true)
{
}

And looking at the next constuctor...

  public IdentityDbContext(string nameOrConnectionString, bool throwIfV1Schema)
: base(nameOrConnectionString)
{
if (throwIfV1Schema && IsIdentityV1Schema(this))
{
throw new InvalidOperationException(IdentityResources.IdentityV1SchemaError);
}
}

Not much going on there - or is there?. If you look at the code for the IsIdentityV1Schema function it reveals all - it's checking if the database exists, and it's also doing the column name lookup.


So, to remove the two additional SQL statements from your code, you need to pass false as the second parameter to the IdentityDbContext constructor…

  public class DbApplicationRepository 
: IdentityDbContext, IDbApplicationRepository
{
public DbApplicationRepository(string connectionString)
: base(connectionString, false)
{
}

...
}

Hopefully this will help someone!

Friday, 7 March 2014

Your hosting provider does not yet support ASP.NET 4.5…

Oh yes it does, I’ve been using .NET 4.5 for *ages* on Azure. Well, it feels like it anyway, but today I got this error after adding an extra couple of dependencies in from NuGet.

It was a simple fix – the stuff I’ve added (Cross Origin Requests) has updated my project but not set it to .NET 4.5.1 which is necessary for it to work. A quick trip to settings land…

image

And now it’s working again. Phew!