views:

84

answers:

4

hello,

thanks for your attention and time.

I want to implement validations in settter of properties. Here is an issue where your expert help is required please.

I have idea of how I will do validations before setting value. but not getting what to do if passed value is not correct. Just not setting is not a acceptable solution as I want to return an appropriate message to user (in a label in web form). My example code is:

private  int id;
public int Id
{
    get
    { return id; }

    set
    {
        bool result = IsNumber(value);
        if (result==false)
        {
            // What to do if passed data is not valid ? how to give a appropriate message to user that what is wrong ?
        }

        id = value;
    }
}

A thought was to use return but it is not allowed.

Throwing error looks not good as generally we avoid thorwing custom errors.

Please guide and help me.

thanks in anticipation

haansi

A: 
  1. If the check is only about number (type) then your property can very well handle the type safety. Eg. User wont be able to assign string to a property accepting int.

  2. I would suggest that if Property involves certaing computations, then one should consider using a method instead. In that case, you will option to get some text in return.

  3. One more option is to store all these validation checks in an instance collection (inside the same object). Like.

    private List _faileValdations;

//more code

    set
    {
    if (!IsNumber(value))
    {
    _faileValdations.Add("Invalid value for xxx. Expected... got..");
    }
    else{
        id = value;
    }
    }

And then, your GUI can read the FailedValidations collection in the end, and display it in a formatted way in some label.

Edit: one more option below.

  1. Sorry i forgot to mention about this before.

You can use an event driven approach also. You object can expose an event like "ValidationFailed", and all the GUI objects can subscribe to this event. The object will trigger this event in case any validation is failed in the setters.

    set {
    if (!IsNumber(value))
    {
    RaiseValidationFailed("some message");
    }
    else{
        id = value;
    }
    }

"RaiseValidationFailed" can collect the message, wrap it up in some event args and trigger "ValidationFailed" event with the message. Then GUI can react to this. {I can provide you a full code for this if its not clear}

Amby
Much Thanks Amby,Validation include both (type and calculations as well). I want to implement it from setter as it is automatically called every time a object is filled but method will need to call.By Using a list to hold all validation messages can be last solution as it will make it a little complex.any advice pleasethanks for your advice and precious time.
haansi
@haansi, Not very sure what do you mean by "as it is automatically called every time a object is filled". As long as its your object, you can decide how user will interact with your object. If you only expose methods to set values then the client will have no option to evade it.
Amby
+1  A: 

I think you'd better change to another example because:

public int Id
{
  get { ... }
  set 
  { 
      if (!IsNumer(value)) // changes to if (value>5)
      {
            //the code here will never be executed
           id = value;
      }
  }
}
Danny Chen
This seems to be dangerous. A property can not take a decision without raising an alert, this kind of code is very difficult to debug.
Amby
@Amby you are absolutely right. I raise this answer to your question. In fact I don't think checking the value when assigning is a good idea. All validations should be put in one place.
Danny Chen
A: 

I would argue that you should rethink your approach to validation. The approach that you are suggesting means that every time a property changes, a message will be generated.

How will these messages be collected, stored and presented? Especially if you decide to use your classes in a website?

What if you want to validate your class at any other time?

What if you want to use the same rules in client side validation?

I can understand the appeal of catching an invalid value as early as possible, but it is a lot easier to validate an entire class in one call such as a Validate() method. This way, you have full control over when the validation logic is run.

I would recommend you read up on the two leading approaches to property validation:

Data Anotations

Fluent Validation for >NET 3.0 and above

Fluent Validation for .NET 2.0

Both Data Annotations and FluentValidation are easy to use and they are able to generate well-tested client side validation on web forms and win forms.

In Data Annotations, the validation is added to the properties using attributes. If you prefer to keep your data classes as clean data transfer objects, Fluent validation involves the creation of easily readable rules in Validator classes.

Daniel Dyson
+1  A: 

You could consider throwing appropriate exception from property setter. That way it will be clear to the calling party what went wrong, especially assuming you have business rules with respect to setting properties. Of course you do expect the caller to do validations, if still there is a problem, then throwing exception doesn't seem that bad.

"It is valid and acceptable to throw exceptions from a property setter." Property design guidelines

Best practices: throwing exceptions from properties

What exception to throw from a property setter?

PRR