Andy @ Work

Tuesday, November 29, 2005

Pandora

Have you checked out Pandora yet? If not … do it now. Simply amazing.

Traps to look out for when implementing IXmlSerializable for a Web Service

I’ve been working on this new project in .Net 2.0, and am loving the flexibility that the IXmlSerializable interface gives me. Before this interface, I either had to let the XmlSerializer dictate the design of some of my business layer classes, or create very a series of Data Transfer Objects (DTO’s). Most of the time I've gone down the DTO path so that other users of my business layers didn’t accidentally start using methods that were not designed for them to use.

Anyway. After implementing a couple IXmlSerializable interfaces on what I would consider complex types (not very complex ~ just not simple) I have come across the following traps/tricks.

  • WriteXml When you implement this method, make sure you include the default namespace in your Write... methods. This has caused me so many hassels in the past. Its easy to forget, but if you don't do it you won't be able to send serialized types to your consumers.

  • DateTimesWhen serializing and deserializing DateTime’s you normally use the XmlConvert class. Make sure you use the ToDateTime method that will take a XmlDateTimeSerializationMode enum as a parameter, and set that enum to RoundtripKind. Otherwise you will get a lot of FormatExceptions when deserializing a Datetime on your side of the webservice.

  • Try to avoid using attributes in your schema over elements. Personally I think that attributes look neater than a whole string of xml elements, but its easier to read elements using the XmlReader than it is to using Attributes.


If I have time I would like to investigate that third point a little more to confirm that there is problem with the order in which enum elements in the schema are defined.

Wednesday, November 23, 2005

Problems with InternalsVisibleToAttribute?

Have you ever had this error when using the InternalsVisibleToAttribute?

Friend assembly reference 'UnitTest' is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations.

BUT the assembly which contains the attribute isn’t being strongly signed?

More than likely you are dealing with some code that was ported from Visual Studio 2003. If you look at your AssemblyInfo file you will likely see the following attributes:


[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]


If you remove these three attributes your code will once again compile. It appears that if the compiler see any of these three attributes it thinks that the assembly must be strongly signed.

Had me scratching my head for quite some time.

Thursday, November 03, 2005

You know that your loved when...

How's this.

Two of the guys who work for/with me have been playing Battle for Middle Earth after hours in the office.

I have occasionally joined in a game at lunch if one of the two is out. So today one goes out for lunch and brings back a copy of the game as a gift.

Brings a tear to ones eye.

A partial solution to ObjectDataSource

It took a compromise, but I'm finally happy with my ObjectDataSource model.

After realising that I couldn't just bind the ObjectDataSource to my Business Object for updates and inserts I decided went down the path of creating two static methods on each BO. One for insert and one for update.

But it really grinded on me. ObjectDataSource wants the parameter names to be the same as the BO properties being bound to ~ hence if I bind to the User object's Username property, both my Insert and Update have to have 'Username' parameters. Except my companies parameter naming convention would have the parameter named 'p_username' (I won't go into the details for the p_. I like it and thats all there is to it.)

So to keep my naming convention I handled both the Updating and Inserting events and renamed the parameters in the InputParameters collection so that each parameter started with a p_ + lowercase letter.

But I started thinking about how many times I was going to have to write code like this. I'm lazy and I hate plumbing. But I'm also a bit of a perfectionist (a combination that makes someone look for the easiest right way to do something - which are often mutually exclusive).

I also didn't like my Business Objects design being dictated by the website. So in the end I created a series of ObjectDataSource helper classes. They have the horrible parameter naming convention, and the equally horrible lengthy parameter lists, and just wire up calls to the BusinessObjects. Oh and they're nicely tucked away in the web App_Code folder where hopefully noone besides control/page authors will ever think to use them.

I only wish that I had come up with this solution a couple of days ago.

ObjectDataSource control

I've been working with on a live project using Asp.Net 2. 0 for about four weeks now, and I must say that I'm largely impressed with the improvements that have been made.

I had to do up an Admin console for this web project, to allow an Admin to change things like user details and plans etc etc. So I came accross the ObjectDataSource. I was immediatly amazed. This thing rocked! So easy to select values from a Business Object without having to write a whole bunch of plumbing code.

That was until I tried to ues the ObjectDataSource (ODS) to perform an update.

I like how the ODS can determine if the Select method is static or instance etc. Very clever. But what I don't like is why the Update method has to fall into one of two categories:
  1. For each field that is bound, the Update method must have a parameter with the same name; OR
  2. The Update method can take a single parameter who's type must be constructable using a public parameterless constructor and contain a public Property for every bound field.
I don't understand why the designer's didn't provide a third option. Why not allow the Update method to take no parameters, and the ODS will just set the properties of the BO that was bound to in the first place.

All of my BO's have this sort of form:

public class User
{
public static User FindUserByUserId(int userId) {//...}

public string Name {get;set;}
public string Surname {get;set;}

private User(DataRow row){//...}

public void Commit()
{
// Use dataadapter to commit changes made to the datarow
}

public void Delete()
{
// Use dataadpater to delete this row from the DB
}
}

So when an update is performed via an ODS, I just want it to set the value's of the properties bound to from the Select command (eg FindUserByUserId), and then to call my parameterless Commit() method.

I know that ODS's don't maintain state, but surely the Update procedure could be changed to retrieve an object using the original select parameters and then update the values of that object.

Seems that databinding from Microsoft has a history of being almost there - but not quite.