I want to validate the details provided by the user before taking them into the processing. My UIs have Text boxes, Combos mainly. In some fields, user must provide data, in some fields only certain type of data may will be accepted like texts, Dates/times, numbers etc. When it comes to date/ time we should check whether the provided values are in the valid range.
My question are
Q1. Where to do validation in MVP pattern?
My options are
Q2. How to do the validation.
My options are
i. All controllers like text boxes in the View are encapsulated in properties (Getters / Setters)
public string Age
{
get { return txtAge.Text; }
set { txtAge.Text = value; }
}
ii. UI fires the event Validate(sender, e)
iii. Presenter listen and hook it up to the handler which then invokes Validate() method
iv. In Validate() method it'll detect the controller raised the event (sender) and read the corresponding property to get the value in the controller.
v. Then it will check the type against the type in the model and decide the validity and then alert the user
The problem here is that I may have to expose all controllers through string properties as other wise it will give exceptions when the user enters an invalid type.
If I do something like this
public int Age
{
get { return Convert.ToInt32(txtAge.Text); }
set { txtAge.Text = Convert.ToString(value); }
}
Then the problem would be the presenter cannot do the validation as already its converted to int?
Where to do validation in MVP pattern
- Implement validation as a service available to Presenters. (Through DI for ex.)
- Do the validation in the UI itself in a event like KeyPress.
- Presenter itself handles the validation.
It depends - there is no "one size fits all", you have to make a decision for each kind of validation.
Think of what will happen if you change the View layer by a different one (with a different UI technology). This mental model helps to make the right decision, even if you use only one kind of UI. If the validations could be done in the presenter, they will available for every kind of view, without the need of reimplementing them. On the other hand, it is not wise to make too many assumptions in your presenter layer about the available events of the specific UI.
So as a general rule: put the validations into the view which depend on the specific UI (for example, validating directly for each "KeyPress" is a typical candidate for validation in the view). Put validations in the presenter which will be the same for each different View layer (type checking is an edge case, see below). If you have validation code which might be reused between different presenters, put that code into a helper class or service. And if this has to be a service provided by "DI" depends mainly if it is a very complex validation which needs to access the database or something like that.
Q2. How to do the validation. [in case of type conversions]
Actually, if possible, avoid the necessity of doing type checking at the presenter level by restricting what the user can enter at the UI level. Most modern UIs (desktop and web as well) provide mechanics to forbid the entering of data if the data does not match a certain type. For example, use a specific number edit field. If such a thing is not available in the specific UI technology, you could still implement a type validation mechanics for each edit field only at the UI level, without involving the presenter. So I see this best handled at the View level.
Of course, similar types of validation (like a range check) might be better handled at the presenter level, since the test would be always the same, whatever View implementation you have. So they are better placed at the presenter level. But a range check does not provide you with the type conversion problem given in your question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With