What I don’t like about Castle Validator

April 12th, 2007

The more I push this thing into broader scenarios, the more I’m disappointed. The biggest flaw lies within its interaction with FormHelper under some scenarios. For example, you can have an entity like

public class Order
{
  private Customer owner;

  public Customer Owner
  {
    ...
  }
}

public class Customer
{
  private int id;

  public int ID
  {
    ...
  }
}

So far, so good. Now suppose you want to render a form where the Order’s owner can be changed. You’d use a select form element to do that. You also demand that an order has an owner so you use the ValidateNonEmpty attribute:

public class Order
{
  private Customer owner;

  [ValidateNonEmpty]
  public Customer Owner
  {
    ...
  }
}

And now you render the form using the FormHelper to have the “auto-wired” validation:

$Form.FormTag("%{action='SaveOrder'}")

$Form.HiddenField("order.id")

$Form.LabelFor("order.owner.id", "Owner:")
$Form.Select("order.owner.id", $customers, "%{text='Name', value='Id'}")

$Form.EndFormTag()

As you see we have to bind the Owner.ID property, so when the DataBinder starts to populate the Order instance it will instantiate a new Customer class and fill the ID property with whatever was chosen on the select form element. The good news that we kept the validation logic in a declarative format, and tight to our domain model, instead of scattering it throughout the layers. The bad new is that it doesn’t work.

“Why?” - you might ask. Fair question. The responsible to output the validations is the FormHelper. It works collaboratively with the ValidatorRunner to collect and apply the validations as it navigates through the properties. Using our example:

$Form.Select("order.owner.id", $customers, "%{text='Name', value='Id'}")

In this case the FormHelper will try to collect validators for the ID property. And obviously it won’t find anything useful there.

Possible solutions?

Collect the validators in a chain

Using the same example:

$Form.Select("order.owner.id", $customers, "%{text='Name', value='Id'}")

If we use a chain, the FormHelper could try to grab validators (using the runner) for the Owner property and then for the Id property, which, in this case, would result in the expect behavior.

The first time I thought about this solution I quickly bumped into a situation that invalidated it. However I can’t remember it. So, assuming that people that read this entry to this point have a brain bigger that this pea-sized brain here, would you mind sparing a minute of thinking to check if my solution would be enough or if there’s a better alternative? Thanks in advance!

Categories: Castle | Top Of Page | |

7 Responses to “What I don’t like about Castle Validator”

Ayende Rahien Says:

Assume that Customer has and address component, where you may have an address (valid) or not at all:
public class Address
{
[ValidateNonEmpty]public string City{…}
}

$Form.InputText(”customer.Address.City”, “”)

Now what happens?

Ernst Naezer Says:

Perhaps we can extend the validator so you can add target specific runners… in this case there could be an Active Record processor that can recognize a Primary key and apply the owner’s validation ?

goodwill Says:

I really agree I dont like Validator- not that extreme on hating it, but there are some scenarios that really breaks the game. e.g. What ayende did for multi field validation would not work for ARDataBind, and the case you have mentioned.

For your question- let me try to think about it after I get some decent sleep :P

hammett Says:

Ayende, this is fine. The runner will try to collect validation for the Address property and for the City property. This is OK…

Ernst, I’m not sure this would be the best solution. The more ‘agnostic’ the validation is about the underlying model (and its persistence) the better.

goodwill, I’m sure it’s not perfect, and I dont like that too. But I’m asking for help here. I think if we put some effort together we can make it better than it is today, which is good for everyone.

I am Shawn Carr Says:

AR Meets SQL Server Compact Edition

As I talked about in Castle's Active Record continues to Impress Me I am using Active Record along

I am Shawn Carr Says:

Active Record - My Thoughts after 3 months of usage

So a little over three months ago I started using CastleProject's Active Record (AR) for a WebSite

MonoRail and Castle Validator « Random Code Says:

[…] a good extensibility mechanism, however there are a few gotchas (even Hammett outlines a few here), the key is to be aware of what is happening and […]

Leave a Reply