How to personality error message for hibernate validator enum? - hibernate-validator

I have a Spring MVC web application that uses JSR303 validation:
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
class User {
#NotBlank(message = "user name is mandatory")
String userName;
public enum Color {RED, GREEN, YELLO}
#NotNull(message = "color is mandatory)
private Color color;
}
When my web controller validates User, it tells "color is mandatory" if this parameter has not been specified. This message is shown in the web form. However, if the string "BLUE" is passed to color (which is not one of the 3 enum options), I get a message as follows:
Failed to convert property value of type java.lang.String to required type User$Color for property color; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type #javax.validation.constraints.NotNull User$Color for value BLUE; nested exception is java.lang.IllegalArgumentException: No enum constant User.Color.BLUE.
This message is shown in the web form. How can I personalise the message?

Related

.NET Core WebApi Action is executed even with missing properties in the request body

My .NET Core 3.1 WebApi controller PUT action is found and execute even if it should not. I have request data object with 2 properties in [FromBody] parameter. But if I call this route with absolutely different properties in the request Body, or no properties at all - it stil seems to be OK and Action is executed, just properties have default values for its types. I expected 400 Bad Request.
public class UpdateLogRequestData
{
[Required]
public int Records { get; set; }
[Required]
public int LogStatusId { get; set; }
}
Controller Action:
[HttpPut]
[Route("{logId:int}")]
public IActionResult UpdateLog(
[FromRoute] int logId,
[FromBody] UpdateLogRequestData requestData)
{
if (!this.ModelState.IsValid)
{
return this.BadRequest(this.ModelState);
}
...
}
I tried to add [Required] attributes and ModelState validation later when I noticed the Action is executed even by "bad request" - ie request with incorrectly named properties. Properties in UpdateLogRequestData just have 0 as their values (int default value).
It is dangerous behavior since I update records in the DB. And now, if someone sends the request without Records and LogStatusId properties, database will be updated with zeroes.
Why controller doesn't check it? It's the first time I see something like this. Why no Bad Request happens in that case?
So after deep digging in the Microsoft documentation I have found that validation in Web API has been changed since version .NET Core 3. For those with the same problem here is how ti works.
Web API controllers don't have to check ModelState.IsValid if they
have the [ApiController] attribute. In that case, an automatic HTTP
400 response containing error details is returned when model state is
invalid. For more information, see Automatic HTTP 400 responses.
[Required] validation on the server. On the server, a required value is
considered missing if the property is null. A non-nullable field is
always valid, and the [Required] attribute's error message is never
displayed.
However, model binding for a non-nullable property may fail, resulting
in an error message such as The value '' is invalid. To specify a
custom error message for server-side validation of non-nullable types,
you have the following options:
Make the field nullable (for example, decimal? instead of decimal).
Nullable value types are treated like standard nullable types.
OR
Specify the default error message to be used by model binding, as
shown in the following example:
services.AddRazorPages()
.AddMvcOptions(options =>
{
options.MaxModelValidationErrors = 50;
options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
_ => "The field is required.");
});
services.AddSingleton<IValidationAttributeAdapterProvider,
CustomValidationAttributeAdapterProvider>();
See the line
options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
_ => "The field is required.");
Make those value types nullable so that they do not default to the non-null default values when omitted in the request body.
public class UpdateLogRequestData {
[Required]
public int? Records { get; set; }
[Required]
public int? LogStatusId { get; set; }
}

Set Default paging null

I use spring boot 2
Seem like spring boot put a default value for pageable, if user put nothing... I would like to get null or nothing...
#GetMapping(value = "networks")
public ResponseEntity<Page<Networks>> getNetworks(#RequestParam(required = false) String search, Pageable page) {
}
So I tried to put #requestparam with required=false:
#GetMapping(value = "networks")
public ResponseEntity<Page<Networks>> getNetworks(#RequestParam(required = false) String search, #RequestParam(required = false) Pageable page) {
}
but if user type
http://localhost:8080/networks?search=&page=0&size=10&sort=id%2Casc 50
I get
"Failed to convert value of type 'java.lang.String' to required type
'org.springframework.data.domain.Pageable'; nested exception is
java.lang.IllegalStateException: Cannot convert value of type
'java.lang.String' to required type
'org.springframework.data.domain.Pageable': no matching editors or
conversion strategy found", "path" : "/
If user type
http://localhost:8080/networks
that work

How to send boolean parameter from extjs request to server?

I want to send an extjs request to the server.One of the parameter in the extjs request is of the type boolean.
params:
{
name : 'John',
active : true/false
}
On the server side the action has a bean as a parameter (MyBean) which hold the values sent by the extjs request.
#RequestMapping(value = "save", method = RequestMethod.GET)
public void saveUser(MyBean bean) {
System.out.println("name : " +bean.getName());
System.out.println("active : "+bean.getActive());
}
Value Object is as follows :
public class MyBean
{
public String name;
public boolean active;
//getters & setters
}
The code bean.getActive() prints false even if the value sent by the extjs code is true.
Please tell me what is required to send a boolean value as parameter from the extjs code.
var myObjectToSend = {
"name": "jhon doe",
"active": true
}
Ext.JSON.encode(myObjectToSend);
Then you can receive it in java as a single object, decode it (with jackson for example) and then access the object atributes ... best regards

How to handle enum while transferring service layer to business layer?

I am using enum in my service layer. All doing good if i set value of enum vice versa i am not going to set its value than it gives me an error
Error :
The underlying connection was closed: The connection was closed unexpectedly.
I have used enum in DataContract Class which will be used while database operation.
I am using WCF Services to connect with DB with the use of Data Model. In some of the method i am using enum but in some methods i am not.
DataContract Class :
[DataMember]
public Enums.SearchType SearchType { get; set; }
Enum Declaration:
public enum SearchType
{
Search = 'S',
Export = 'E',
Undefined = 0
}
So what should i do in this case?? If anyone have any idea about this than please help me in this...
Thanx in Advance............
Ensure your enum type has a default value (0)
public SearchType
{
Undefined = 0,
...
}
Enums are Int32 (unless specified otherwise). default(Int32) is 0. default(Enums.SearchType) will also be 0. If 0 is not defined in the enum, data contract deserialisation will fail.

Why is IValidatableObject.Validate only called if property validation passes?

In my model, it seems that Validate() is only called AFTER both properties pass validation.
public class MyModel : IValidatableObject
{
[Required]
public string Name { get; set;}
[Required]
public string Nicknames {get; set;}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(Nicknames != null && Nicknames.Split(Environment.NewLine.ToCharArray()).Count() < 2)
return yield result new ValidationResult("Enter at least two nicknames, new [] { "Nicknames" });
}
}
When a user enters a single line of text in the Nicknames text area but leaves the Name text box empty, only the Required error message for the Name property is displayed. The error message that should be displayed from the Validate() function never shows up.
Only after entering a name in the Name text box and some text in the Nicknames text is the Validate() function called.
Is this how it's supposed to work? It seems odd that a user is shown an error message on a subsequent page when the error is being caused on the current page.
This is by design. Object-level validation does not fire until all the properties pass validation because otherwise it is possible that the object is incomplete. The Validate method is meant for thing like comparing one property to another. In your case you should write a custom property validator.

Resources