ASP.NET MVC 4 only attribute-based broken rules displaying

ASP.NET MVC 4 only attribute-based broken rules displaying

Old forum URL: forums.lhotka.net/forums/t/12055.aspx


Michael posted on Wednesday, July 03, 2013

Only attribute-based broken rules are being displayed by Html.ValidationSummary(false), all rules added via AddBusinessRules are not displayed.

For example, when I use the [Required] attribute, the rule is executing and the broken rule is displayed. When I comment it out and replace it with BusinessRules.AddRule(new Required(EmailAddressProperty)) in AddBusinessRules() the broken rule is not displayed. There is a broken in the BrokenRulesCollection, it's just not displayed.

I am using the CslaModelBinder and Csla.Web.Mvc.Controller, CSLA 4.5.30.30.

Thanks in advance.

Michael replied on Wednesday, July 03, 2013

Rocky? Jonny? Anyone?

I've uploaded a sample application showing the problem:

http://www.softbiz.com.au/temp/MvcApplication1.zip

JonnyBee replied on Thursday, July 04, 2013

It is because the initial Create method you only set Model - you must also set ModelState to get the initial validation errors:

 

        public ActionResult Create()
        {
            var c = Customer.NewX();
 
            ViewData.Model = c;
            var modelState = ViewData.ModelState;
 
            var errors = from r in c.BrokenRulesCollection
                         where r.Severity == Csla.Rules.RuleSeverity.Error
                         select r;
 
            // set property errors
            foreach (var item in errors)
               ViewData.ModelState.AddModelError(item.Property, item.Description);
 
            // set summary for entire object 
            ViewData.ModelState.AddModelError("", c.BrokenRulesCollection.ToString());
 
            return View();
        }

The ModelBinder is only used in a postback to bind input values to your model
(and the automatically update the ModelState dictionary).

Michael replied on Thursday, July 04, 2013

Thanks for the reply, Jonny.

Yes, that code displays the initial errors immediately, but it still doesn't show new broken rules after a property has changed, unless it is a rule declared via a DataAnnotations attribute.

What is the difference between [Required] and BusinessRules.AddRule(new Required(EmailAddressProperty))? Are they treated differently? Why don't normal business rules appear in the validation summary?

After you click Create in the sample to force the validation summary to refresh, none of the broken rules added via AddBusinessRules() get displayed.

JonnyBee replied on Thursday, July 04, 2013

The difference is that JQuery and ASP.NET MVC understands the DataAnnotation rules (ie JQuery has the same rules defined and activated based on DataAnnotations) to run as javascripts in the browser. 

See the tutorials and documentation on ASP.NET:

How to: Validate Model Data Using DataAnnotations Attributes
How to: Implement Remote Validation in ASP.NET MVC

More generally speaking - the main issue/problem with regards to implement this in CSLA is that several types (including IClientValidatable) is defind in System.Web.Mvc and this cannot be added to CSLA business rules. 

So your rules (business library) must have a reference to System.Web.Mvc and matching javascripts in order to perform validation on the client. 

On the last part  -  i  believe this is how the CslaModelBinder is meant to work (and maybe somewhat differently from standard).

ValidationSummary is added as PropertyName = "" (in CslaModelBinder as the ObjectLevel broken rules). This may be altered to show a summary of ALL broken rules tho'.

Michael replied on Thursday, July 04, 2013

OK, that makes sense.

Adding System.Web.Mvc to the business assembly... this seems so horrible. It's a shame Microsoft didn't make some interfaces for Remote validation.

JonnyBee replied on Friday, July 05, 2013

Hi,

Just to be very clear on this subject.

DataAnnotation rules is implemented in System.ComponentModel.DataAnnotations and Validation attributes is how you define/register that this field has that rule (like f.ex RequiredAttribute) .

Csla.Core.BusinessBase has this code:

    protected virtual void AddBusinessRules()
    {
      BusinessRules.AddDataAnnotations();
    }

And this method will wrap all ValidationAttributes with a Csla.Rules.CommonRules.DataAnnotation rule that will call the actual implementation in System.ComponentModel.DataAnnotations.

The standard Csla.CommonRules is fully implemented in Csla only. So we have support for different implementations.

It is a shame that not all interfaces (especially IClientValidatable)  made it into System.ComponentModel.DataAnnotations assembly and rather ended up in System.Web.Mvc. This result is that in order to create custom business/validation rules that can be called from javascript - via the Controller class in MVC - your rules assembly must have a reference to the correct assembly of System.Web.Mvc.

 

Copyright (c) Marimer LLC