accessing dataannotations display name in a business rule

accessing dataannotations display name in a business rule

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


Ranjini posted on Tuesday, December 14, 2010

I was wondering if from within a business rule, it would be possible to access the given input/affected property's dataannotation provided display name to help make my error message more meaningful and user friendly.

I understand from this post http://forums.lhotka.net/forums/p/8660/41322.aspx that Csla looks at dataannotations display name to generate its default error messages but what if i wanted my own error message but still wanted to use datannotations display name ?

Would appreciate any help!

Thanks

Ranjini

JonnyBee replied on Tuesday, December 14, 2010

I assume you are using CSLA 4.x?

If you register a propertyinfo with lambda expression without friendly name then the default PropertyInfoFactory will actually try to get the Display DataAnnotation attribute and insert this value as FriendlyName.

    public static PropertyInfo<string> CustomerNameProperty = RegisterProperty<string>(p => p.CustomerName);

    [Display(Name = "Customer name")]
    public string CustomerName
    {
      get { return GetProperty(CustomerNameProperty); }
      set { SetProperty(CustomerNameProperty, value); }
    }

So in your own custom rule you should be able to get it straight from the IPropertyInfo.FriendlyName.

 

Ranjini replied on Tuesday, December 14, 2010

Thanks for your response.

I am using CSLA 4.x and doing exactly what you have shown , but in my custom business rule, IPropertyInfo.FriendlyName still shows as "CustomerName" and not "Customer name"

 

Ranjini replied on Tuesday, December 14, 2010

Just to support what i said, here are peices of my code

Property Registration -

 public static PropertyInfo<double?> _rawUnitsAtFullScaleProperty = RegisterProperty<double?>(c => c.RawUnitsAtFullScale);
        [Display(Name = "Raw Units At Full Scale")]
        public double? RawUnitsAtFullScale
        {
            get { return GetProperty(_rawUnitsAtFullScaleProperty); }
            set { SetProperty(_rawUnitsAtFullScaleProperty, value); }
        }

Business Rule -

public class CheckIfValid : Csla.Rules.BusinessRule
        {
         
            public CheckIfValid (IPropertyInfo primaryProperty)
                : base(primaryProperty)
            {
             
                if (InputProperties == null) InputProperties = new List<IPropertyInfo>();
                InputProperties.Add(primaryProperty);
             
            }
            protected override void Execute (RuleContext context)
            {
      string ErrMsg = PrimaryProperty.FriendlyName + " has to be greater than zero ";
               
                    if (context.InputPropertyValues[PrimaryProperty] != null)
                    {
                        if (((double)context.InputPropertyValues[PrimaryProperty]) <= 0)
                            context.AddErrorResult(ErrMsg);
                    }
                    else
                        context.AddErrorResult(ErrMsg);


            }
        } 

Adding BusinessRule to Property -

protected override void AddBusinessRules ()

{

 

 

 

base.AddBusinessRules();

BusinessRules.AddRule(

 

new CheckIfValid(_rawUnitsAtFullScaleProperty));

}

 Result

and here is the snapshot of what friendlyname returns on the propertyinfo in the business rule - https://docs.google.com/leaf?id=0B-Qwbn69ZX90YzVjMWQ4NGYtMTVkYi00ZmE0LWEwNGUtMDE0ZTZhODhlYzIx&hl=en&authkey=CNSbnaUJ

JonnyBee replied on Tuesday, December 14, 2010

Which version of Csla and framework (Net/SL) are you using?

Checked in NET4 with latest CSLA 4.1 Beta code in repository and it works just fine.

Ranjini replied on Tuesday, December 14, 2010

Mine is a silverlight app and uses CSLA 4.0.1

JonnyBee replied on Tuesday, December 14, 2010

Hmmm, I'm running the latest Csla 4.1 Beta and in SL I get:

    public static PropertyInfo<string> CustomerNameProperty = RegisterProperty<string>(p => p.CustomerName);

    [Display(Name = "Customer name xyz")]
    public string CustomerName
    {
      get { return GetProperty(CustomerNameProperty); }
      set { SetProperty(CustomerNameProperty, value); }
    }
and I get:
?CustomerNameProperty
{Csla.PropertyInfo<string>}
_defaultValue: ""
_friendlyName: "Customer name xyz"
_index: -1
_name: "CustomerName"
_relationshipType: None
Csla.Core.IPropertyInfo.DefaultValue: ""
Csla.Core.IPropertyInfo.Index: -1
DefaultValue: ""
FriendlyName: "Customer name xyz"
Name: "CustomerName"
RelationshipType: None
Type: {System.String}

And error string for Required rule contains "Customer name xyz is required".

BTW:This is the SimpleNTier sample in the Samples download and CustomerName property is in Order.cs.

Could you try your code with the latest Beta?

 

 

 

RockfordLhotka replied on Wednesday, December 15, 2010

I actually just added a unit test for this, and the test passes.

I have a TestValue property with a Display(Name="Test value") attribute. This test works

    [TestMethod]
    public void DisplayName()
    {
      var obj = new Single();
      Assert.AreEqual("Test value"Single.TestValueProperty.FriendlyName);
    }

JonnyBee replied on Wednesday, December 15, 2010

Hi,

This is caused by a bug in BusinessBase in Silverlight that would not use the PropertyInfoFactory.

http://www.lhotka.net/cslabugs/edit_bug.aspx?id=803 and was fixed on 6. september 2010.

The fix was made after  Csla 4.0.1 was released so your options is to either update BusinessBase.cs in Csla.Siverlight or upgrade to the latest beta.

 

 

 

Ranjini replied on Wednesday, December 15, 2010

Thanks much for the thorough followup! Since I am not in a position to use the beta version, I just recompiled csla with the bug fix in businessbase.cs and it works.

Thanks again!

Copyright (c) Marimer LLC