Tuesday, August 31, 2010

404 errors and the XamWebSpellChecker dictionary file

I added Infragistics' XamWebSpellChecker control to one of my Silverlight 4 data entry user controls and it worked like a charm.

Well, it worked on my machine.

Once I got the application on a server spell checking stopped working: a progress dialog would briefly appear and nothing else. Fiddler revealed that when my app was trying to check spelling and requesting the download of a dictionary it was only receiving a 404 response. First I checked the server to make sure that the file had been properly deployed to the IIS6 host. Check. I then reviewed the instructions regarding the usage of the dictionary file and it appeared that I had used the correct file. I started thinking about the binary dictionary file, which had a ".dict" extension. How would IIS know what to do with a .dict file? I logged on to the server and added a new entry: Files with a .dict extension are of "application/octet-stream" MIME type. I issued an iisreset command.

Then with great trepidation I tried to check spelling again...

BAM! Adding the MIME entry was the solution. The spell checker control was functional again. I could rest easy, knowing that no misspelled words would be allowed ever again!

At least not on a single data entry form in a departmental content management system. You've got to start somewhere.

Tuesday, August 24, 2010

Swiss Army Knife of ASP.NET MVC apps (Part 1)

My company has a couple of departments with sometimes conflicting goals and objectives. Let's call them BBU Ostrich and BBU Peacock. (BBU is an acronym for Battlin' Business Unit, a term coined by the Dilbert comic strip.)

Alteration of the code will allow each BBU to do what they want with the information without interfering with the other one's processes. It will also allow one of the BBU Ostrich's current processes to continue unchanged while adding new features and capabilities. There is also an issue with reaching consensus between the two business units that prevents progress regarding a unified solution.

Meeting these various needs has been much easier than I had expected and I have been able to use a wide variety of technologies.
Entity Framework 4
WCF RIA Services
SQL Server 2008 R2
Spark View Engine

It might seem to the casual observer that some of the items above might have been used purely for the sake of using every cool current .NET technology, but they actually each play a role. Here are a few usage examples:

WCF RIA Services exposes a JSON endpoint to a site built on the LAMP stack.
XHTML is exposed so that our site can be efficiently scraped.
I was initially using Ninject while waiting for a database to become available, but it was so easy to work with that I expanded its usage.
Automapper is used for easy data transfer across layers.
I had a couple of partial views had become tag soup disasters so I turned to the Spark View Engine. Spark restored order and maintainability.

There's also a Silverlight 4.0 administrative tool based on the MVVM Light Toolkit involved. It also uses WCF RIA Services, Automapper, and Ninject. Automapper is available for Silverlight version 3 but not 4, so I had to compile the source code for Silverlight 4. I'm going to cover that in a future post because of a couple of issues that I encountered.

Monday, August 9, 2010

Silverlight Neophyte 1: Include the Include Attribute

Use the Include attribute on related types that should be returned to the client.

RIA Services supposedly simplify and accelerate n-tier ASP.NET and Silverlight development. I don't have an opinion on the matter yet because I haven't finished my Silverlight 4 application yet. I think that I'm making good progress on my project for a Silverlight neophyte. That being said, I've spent a few too many hours on problems stemming from my Silverlight / RIA Services ignorance or poor or non-existent documentation. I'm sharing these gotchas as I encounter them.

I inherited a poorly designed legacy database that Entity Framework 4 nicely abstracts. Two of the tables, TableA and TableB, really should be a single table because they merely partition a single, cohesive set of data into two different, um, parts. There are several legacy applications that operate against TableA and TableB or this design would have been changed years ago. I've created a couple of views that nicely unify the tables, and these views work well for read operations.

My Silverlight application needs to edit these tables, and that requirement is where today's topic originates. As you expect, my entity model contains types that represent TableA and TableB, and each of these types (EntityTypeA and EntityTypeB) have navigation properties related to the other type. With that in mind, I added a new method to my domain service that returned a single EntityTypeA. My thinking was that I could then use the navigation property value (EntityTypeA.EntityTypeB) to get the complete set of data.

So no big deal here. My ViewModel called the DomainContext.Load method and I got back an instance of EntityTypeA. But EntityTypeB was null. OK, I thought, I've probably not configured the loading operations properly, I'll set ObjectContext.ContextOptions.LazyLoadingEnabled = false and everything will be alright. Nope, still a null EntityTypeB. I must have done something else wrong. Fine, I'll change my query from

EntityTypeA entityA = this.ObjectContext.EntityTypeA.Include("EntityTypeB").FirstOrDefault(oo => oo.ID == Id);
EntityTypeA entityA = this.ObjectContext.EntityTypeA.FirstOrDefault(oo => oo.ID == Id);
if (!entityA.EntityTypeBReference.IsLoaded)

Still no related entity, and I could see that the property was getting successfully set on the server. It just wasn't making it back to the client.

I was able to finally conjure the correct Google search incantation and found Vincent Leung's post regarding the Include attribute. As soon as I set that in EntityTypeA's DomainService metadata class on the EntityTypeB property my problem was solved. I was able to change my code back to the following more concise format:

EntityTypeA entityA = this.ObjectContext.EntityTypeA.Include("EntityTypeB").FirstOrDefault(oo => oo.ID == Id);

That is all.

Google query

RIA Services Reference

Tuesday, August 3, 2010

Silverlight 4 "Value does not fall within the expected range"

I ported some WPF code to Silverlight 4 and started to receive a System.ArgumentException with the following message:
Value does not fall within the expected range.
Various posts indicated that this typically occurs when you dynamically add child objects with the same names to a container. However, I wasn't dynamically adding anything. After selectively commenting out portions of my XAML I was able to determine that the culprit was a DataGridTextColumn that had no binding attribute declared at all. Example:

<sdk:DataGridTextColumn Header="Pending Time" IsReadOnly="True" />
What surprised me was that when I specified a fictional binding ({Binding Foo}) I got a nice, easy to understand exception:
System.Windows.Data Error: BindingExpression path error: 'Foo' property not found on...
Granted, I am not a Silverlight expert so I might be posting something obvious. I hope that this saves someone some time.