Validation check and code-saving
Creating a custom validator class for each field in each class could potentially lead to bloated code, while you will not get much out of this.

Your model does not support user feedback. All it does is generate exceptions, and Exceptions are not suitable for representing error messages which are displayed to the user. You can catch these exceptions and display the messages to user, but you would abuse the exception mechanism that way. The rule is - never display exception content to users. It's a potential security hole.

Your model supports only a detection of the first error - an exception is thrown, and no further analysis can run. This way you can't provide a complete report of what's invalid in the model.

Initialization of static rule objects in model constructor is suboptimal - you are creating lots of these objects any time a constructor called. Simply making these static would optimize memory usage.

I would suggest returning a custom result object containing the status of the operation and a collection of rule violations from a 'Save' method, instead of throwing and catching exceptions. This way you would not abuse the exception handling mechanism with logic that is not exceptional - for example having an incorrectly entered string field is a normal situation, not an exception.

UPDATE (based on comment):
As for the displaying exception contents to UI, a better approach would be separate save and validate operation, and use validation result to change UI state, so the Save operation is not allowed in the first place when model is not valid. For example, you could disable the save button. Then you don't need to handle validation exception in Save method. I strongly encourage you to reconsider the practice of displaying exception contents to user. Let me reiterate - non-valid user input should be considered as normal program flow, not en exceptional situation.
Consider the following:
Is it a vulnerability to display exception messages in an error page?

So i would recommend the following workflow:
When initializing a form, update the ui based on validation result.
Handle every change to the model in the ui:
If model is not valid based on current user input - update UI with validation result, such as a Save button, display validation summary as text to the user, highlight form controls containing invalid values and so on.
If model is valid for particular operation - enable the UI controls which allow this operation (the 'Save' button), and clean validation summary and the highlights from user screen.
When Save button is pressed, you already sure that the model is valid, you don't need a check, because you have already sure you enabled it because of successful validation result, and it would be disabled on failed validation result.