How to internationalise #Pattern(regexp="(^$|[0-9]{10})") in bean validation? - bean-validation

I am using bean validation to validate my entity,
it works fine according to different locales and it shows region-specific error messages, but I want to internationalize a field 'ContactNo' according to the region like my error messages #NotBlank(message="{contactNo.size}").
So how to achieve
#Pattern(regexp="(^$|[0-9]{10})")
private String contactNo;`
where the regexp value changes according to the region?

The the value for the regexp attribute has to be constant i.e. it needs to be available at compile time. So, either it needs to be a string literal as you do now or externalized into a static final variable.
I guess what you need has to be implemented in a custom Bean Validation constraint.

Related

No setter/field for isCreator found on class

When trying to access a Firestore database using Kotlin, the error quoted in the title is thrown. The fields of my model class exactly match the Firestore documents I'm trying to access. Why does Android Studio say there is no setter/field?
There is another field in the same class, which apparently works correctly, no error has been thrown. Even their type is the same, both are Boolean. The only difference is in their names, isCreator and admin (the working one).
The problem was with the properties' names. When a property's name starts with "is", one has to explicitly annotate the property's getter the following way:
#get:PropertyName("isCreator")
val isCreator: Boolean
If your property is mutable (aka var), you also have to annotate the setter;
#get:PropertyName("isCreator")
#set:PropertyName("isCreator")
var isCreator: Boolean

Should default POJO parameter resolution add the parameter to the model?

I just spent some time troubleshooting an aspect of Spring MVC's default handler method parameter resolution and I'd like to ask those closer to the project if this behavior is intended or if it'd be reasonable to open a ticket suggesting a change.
The issue has to do with the default resolution of POJO-style objects in method parameters like this:
#RequestMapping("/endpointwithparams")
public String endpointWithParams(EndpointParams params) {
// Do some stuff
return "viewname";
}
With no annotations or custom argument resolvers, Spring will attempt to bind the EndpointParams object by matching request parameters to its field names. It will even run validators if any are configured. This seems great - it lets me write simple POJO objects to organize related sets of parameters without having to have a custom argument resolver for each one.
The part that throws me off is that after the EndpointParams object is created it will also be automatically added to the model. This is because the actual resolver of this parameter will be a ModelAttributeMethodProcessor with its "annotationNotRequired" flag set to true. I don't want this parameter added to the model - its presence causes some trouble down the line - and it certainly wasn't intuitive to me that I should expect that addition to happen for a parameter that wasn't annotated with #ModelAttribute.
This behavior is also inconsistent with what happens when you have a "simple" request parameter like this:
#RequestMapping("/endpointwithparams")
public String endpointWithParams(String param) {
// Do some stuff
return "viewname";
}
In the above example, the String param will be resolved by the RequestParamMethodArgumentResolver, which will not add anything to the model.
Would it be reasonable to suggest that better default logic for non-annotated POJO parameters would be the same binding and validation that currently occurs, but without the automatic addition to the model? Or is there some context I'm missing that makes the full #ModelAttribute behavior the best default choice?

Constraints configuring for Beans Validation via a properties file

I'd like to configure bean validation (JEE6) constraints via a properties file or database.
So for instance the Max value below would get pulled from the properties file or database.
Is this possible in ?
#Max(value = 1)
private int elvis;
Any suggestions on a possible approach.
It is not possible via standard Bean Validation. The default as per specification are annotations or as alternative XML.
In theory, Hibernate Validator has the (internal) concept of a MetaDataProvider and one could think of plugging in a DbMetaDataProvider. However, that would be quite some work and I am not sure that it would be worth the effort.
What is you use case anyways? Why don't you use XML?
You can write your own constraint and validator for that. The constraint’s argument could be some identifier of the validation parameters stored in database and the validator could query database for these parameters to validate a value according to them.
Some hints:
See this validator for an idea how to reuse existing validators from your “über validator”.
See this question and this answer for a hint how to inject bean to a validator.

Model Binding and Validation Errors

I am using asp.net MVC3 and I am very new to this technology.
My models are designed in such a way that the properties will throw validation errors if the data is invalid. In this case, the properties are not set with invalid data.
When I redisplay my editing-view, validation error messages are shown; however the values that the user previously entered are gone because the model that it is bound to only contains the old-valid data.
For example, say I had a Person class and the Name property cannot be a null or empty string otherwise it throws a validation exception and prevents the property from being set. Now say the user removes the value from the Name property and tries to save the Person from the web. A validation exception will be thrown and handled properly to add the error to the ModelState so that it is displayed on the screen; however the old value for the Name is redisplayed since the invalid, empty string never made it into the property.
I do not know how to solve this problem and any advice on the issue would be greatly appreciated.
My advise is allow invalid data but use validation attributes. You wont save invalid entities so there is no problem and this is the standard approach these days. If you don't want do that, there is no easy solution. Most simple solution would be using the info from Request.Form
You should implement IValidatableObject to performe this kind of validation at server side.
From MSDN IValidatableObject Interface:
Provides a way for an object to be invalidated.
Theres an exemple here Using IValidatableObject Custom Validation, also from MSDN.
The solution to this problem was to create a ViewModel that allowed invalid data to be entered into this. This solution also simplified my ModelBinder classes because it took on most of the work.

Getting the actual field data from a Linq Expression

I'm working on an ASP.NET MVC3 application and I annotated my model with an attribute that specifies what roles can change specific fields for any possible status the model is in. Take this as an example:
public class Model
{
[RoleLimiter(
new[]{Role.Admin, Role.BasicUser, Role.Validator}, // for draft
new[]{Role.Admin, Role.BasicUser, Role.Validator}, // for awaiting validation
new[]{Role.Admin})] // for published etc
public string Subject {get;set;}
}
It looks a bit messy, sure, but it's very easy to change if needed. Now once I have this, it's easy to check for each field the current status and then get the list of roles that can change it. If the current role isn't in it, I'll add a disabled class to the control.
What I wanted to do next is to make a HtmlHelper extension that has the same syntax as the normal EditorFor (or even a straight-forward TextBoxFor), but does this extra check and automatically adds the attribute behind the scenes, but I'm stuck on getting the field info from the expression, ie:
How do you get from
HtmlHelper.TextBoxWithRoleLimitationsFor(x=>x.Subject);
to the attribute attached to x.Subject?
You fetch the LambdaExpression.Body and check whether it's a MemberExpression. You can then get the Member of the MemberExpression and get the custom attributes from that.

Resources