Quickstart for castle?

Mar 13, 2009 at 10:41 PM
Thanks for great work on xVal.

Could we have a quickstart demo for Castle Validatior setup?

Thanks.
Coordinator
Mar 14, 2009 at 12:06 AM
Hi Waveyus

That's definitely something we'll create documentation for as soon as possible. For now, you can use the Bookings demo from my blog and adapt it to work with Castle Validator as follows:

[1] Replace the Booking model attributes with Castle ones, such as [ValidateNonEmpty] instead of [Required]
[2] Replace the server-side validation runner with one that calls Castle, such as:

internal class CastleValidationRunner
{
    private static readonly CachedValidationRegistry registry = new CachedValidationRegistry();

    public static IList<ErrorInfo> GetErrors(object instance)
    {
        var result = new List<ErrorInfo>();
        var runner = new ValidatorRunner(registry);
        if (!runner.IsValid(instance)) {
            var errorSummary = runner.GetErrorSummary(instance);
            result.AddRange(from prop in errorSummary.InvalidProperties
                            from err in errorSummary.GetErrorsForProperty(prop)
                            select new ErrorInfo(prop, err));
        }
        return result;
    }
}

[2] Reference xVal.RulesProviders.CastleValidator.dll and then enable it in your Global.asax.cs file as follows:

protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
    xVal.ActiveRuleProviders.Providers.Add(new CastleValidatorRulesProvider());
}

I hope this is enough to get you started for now. Documentation is one of the main priorities as we work towards a 1.0 release.
Mar 14, 2009 at 9:01 PM
Thanks!
It works like a charm.
Mar 15, 2009 at 10:41 PM
Edited Mar 15, 2009 at 10:47 PM
I have written an CachedMetadataValidationRegistry, which allows to put attributes of Castle Validation on a metadataclass.
Server side validation seems to work, however, when I try to add client validation, the application fails to start.
I added the xVal.ActiveRuleProviders.Providers.Add(new CastleValidatorRulesProvider()); to my global.asax but when
I start the web app, I get an error on Html.ClientSideValidation :

[MissingMethodException: Method not found: 'Castle.Components.Validator.IValidator[] Castle.Components.Validator.IValidatorRegistry.GetValidators(Castle.Components.Validator.ValidatorRunner, System.Type, Castle.Components.Validator.RunWhen)'.]
   xVal.RulesProviders.CastleValidator.CastleValidatorRulesProvider.GetRulesFromTypeCore(Type type) +0
   xVal.RuleProviders.CachingRulesProvider.GetRulesFromType(Type type) +227
   xVal.<>c__DisplayClass1.<GetRulesForType>b__0(IRulesProvider p) +15

Server validation works by calling ValidatorHelper.Validate(this); which is implemented like this:
    public class ValidatorHelper
    {
        public static void Validate(object model)
        {
            if (model == null) return;
            var runner = new ValidatorRunner(new CachedMetadataValidationRegistry());
            if (runner.IsValid(model) || !runner.HasErrors(model)) return;

            var summary = runner.GetErrorSummary(model);
            throw new RuleViolationException(summary);
        }
    }


Population ModelState is done by using a static MvcValidatorHelper:
    public class MvcValidatorHelper
    {

        public static void PopulateModelStateWithErrors(object model,
                                           ModelStateDictionary modelState,
                                           RuleViolationException ex)
        {
            var modelType = model.GetType();
            var summary = ex.ErrorSummary;
            foreach (var invalidProperty in summary.InvalidProperties)
            {
                foreach (var errorMessage in summary.GetErrorsForProperty(invalidProperty))
                {
                    modelState.AddModelError(invalidProperty,
                                             errorMessage);
                }
            }
        }
    }


This is used in the controller, when catching the RuleViolationException
            catch (RuleViolationException ex)
            {
                MvcValidatorHelper.PopulateModelStateWithErrors(p, ViewData.ModelState,ex);
                return View(p);
            }


CastleRulesProvider doesn't seem to provide for a way to customize the registry, so I can not replace it by my CachedMetadataValidationRegistry
Mar 27, 2009 at 6:56 PM
I too am having the same issue with Castle and the client side validation.

I'm running a trunk build of the castle project with the release version of MVC.
Apr 30, 2009 at 9:24 AM
Edited Apr 30, 2009 at 9:29 AM
Hi,
I'm trying to use xVal in a Monorail project, together with Castle.Components.Validator.
I've registered the provider in App_Start, I've copied all the dll and js files as described in the howto, i've created the CastleValidationRunner.

Now, where do I use the CastleValidationRunner class and how do I "fire" the validation?

I've seen that for MS MVC I have to use Html.ClientSideValidation<Booking>("booking"), but I can't use it in a MR view.

Thank you,
Dan
May 1, 2009 at 1:54 PM
Hi,

The problem with MissingMethodException when using Castle Validators can be resolved by recompiling xVal with an up-to-date version of Castle.  To do this simply replace the 'Castle.Components.Validator.dll' in 'xVal\RulesProviders\CastleValidator\ExternalAssemblies' and rebuild in VS.

HTH,
Simon.
Jul 30, 2009 at 9:38 PM

Same problem here.  @Simon, tried your suggestions, no luck.  I downloaded the trunk from the Castle repository  I still get

Method not found: 'Castle.Components.Validator.IValidator[] Castle.Components.Validator.IValidatorRegistry.GetValidators(Castle.Components.Validator.ValidatorRunner, System.Type, Castle.Components.Validator.RunWhen)'.'

Any other ideas? 

Thank you

Jul 30, 2009 at 9:48 PM

Ok, got it now.  I neglected to copy over the new xVal.RulesProviders.CastleValidator.dll to my solution. 

Jul 31, 2009 at 11:30 AM

Glad you've sorted it shanabus.

Sep 30, 2009 at 8:34 AM

Hi,

I have downloaded xVal1.0 and am attempting to use it with CastleValidator.

I have  referenced the following dlls in both my DomainModel and MVC Project just to be sure.

xVal.dll
xVal.RulesProviders.CastleValidator.dll
Castle.Components.Validator.dll

I too am getting the following message:

Method not found: 'Castle.Components.Validator.IValidator[] Castle.Components.Validator.IValidatorRegistry.GetValidators(Castle.Components.Validator.ValidatorRunner, System.Type, Castle.Components.Validator.RunWhen)'.

The version of Castle Validator that I am using is 1.0.3.0.   I have checked in Reflector and it appears that this version matches what xVal 1.0 is using.  Please advise.

Thanks,
Mark

Sep 30, 2009 at 4:29 PM

Hi again,

1) I downloaded the xVal1.0 source from CodePlex.

2) Opened to CastleValidator Project within xVal1.0.

3) Replaced the project's Castle.Components.Validator reference with mine

4) Recompiled the CastleValidator project. 

5) This generates the assembly named  "xVal.RulesProviders.CastleValidator".   

6)  I placed this assembly into  both my Domain and MVC projects. 

7)  xVal1.0 now works.

Mark