I have the following in one of my view models:
public char? MyChar { get; set }
I noticed there appears to be no client-side validation on the textbox for MyChar, and it's possible for a user to submit a string that is too long for this char to my controller (it simply doesn't bind and remains null).
So, I added the [MaxLength] annotation. Client-side validation now works as expected, but when I submit a valid value to the server, I get the following exception in my event logs:
Exception information:
Exception type: InvalidCastException
Exception message: Unable to cast object of type 'System.Char' to type 'System.Array'.
at System.ComponentModel.DataAnnotations.MaxLengthAttribute.IsValid(Object value)
How can I validate the max length of a char correctly both client-side and server-side?
What I've Tried
For now, I've created my own MaxLength attribute for it to work with char types, but it feels like a heavy approach.
Related
I have an enum that I am validating like this:
#EnumValueValidator(enumClass = MyEnum.class)
String value
It's a string field, but it is validated against a list of enums. However, once the validation is completed, and I know the field is valid, I want the getter to return the enum.
So I added a getter like this
public MyEnum getValue()
return MyEnum.valueOf(value)
The problem is if the value is not one of the valid enum types, the validation doesn't issue the proper error message, because it gets an exception calling the getter on the invalid type. I don't want the validation to use the getter. It should use the field directly. The getter() should only be used by explicit calls in the business logic. Is there a way to do this?
I have a viewmodel with a property of type int?.
If the send value is an integer or is empty it works fine. When the value is a string an exception is thrown 'Could not convert string to integer'
Would it be possible to change the behavior of the binding that instead of throwing a error it would bind the null value ?
I've created a modelbinder class for typeof(int?), but the ModeBind function doesn't get called. I guess the validation happening before the model binding.
Any ideas ?
When you say you have a view model are you referring to the parameter that is being passed to your action method? E.g.
public Foo Bar(MyViewModel vm)
If so then your modelbinder should be of type MyViewModel. You can additionally use a ValueProvider to extract an int from a random string to override the default value provider functionality.
I'm using Spring form tags for filling form with values.
I have form backing object:
public class FormInfo {
public enum Status {ON, OFF}
private Satus status;
//getter setter
...
}
And in JSP Status enum presented like this:
<form:form commandObject="formInfo " ...>
<form:select path="status">
<form:option value="null" label="Please select"/>
<form:options/>
</form:select>
</form:form>
All works fine, i.e. default message and enum values are presented in <select>.
But the status field is not required, so I want allow user to leave Status field unselected. But if form submitted without selecting status field, then I get error:
error in object 'formInfo' on field 'status': rejected value [null];
How I can set enum to null when no values is selected?
Please note I'm using JSR 303 validation. And error described above is not happens automatically, I get this error message manually from following method BindingResult#getFieldErrors().
This is my controller code:
public void myMethod(#Valid #ModelAttribute("formInfo") FormInfo sourcingDetail, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
log.error("Error during validation is occurred." + bindingResult.getFieldErrors().toString()); // <-- this is error message
}
...
}
Also please note, I didn't set any JSR-303 annotation (like #NotNull) on status field.
UPDATE:
Almost full error message which I get from calling this method BindingResult#getFieldErrors() (explained above):
Error during validation is occurred.[Field error in object 'formInfo'
on field 'status': rejected value [null];
...
[Failed to convert property value of type 'java.lang.String' to
required type 'com.my.project.model.Status' for property 'status';
nested exception is java.lang.IllegalStateException: Cannot convert
value of type [java.lang.String] to required type
[com.my.project.model.Status] for property 'status': no matching
editors or conversion strategy found],
Looks like you have the same problem as i!.
There is a method in the controller that serves as a hook where you could specify how to transform the String values, that came from the HTTP request, to a concrete object!.
The method is called initBinder, and there you attach the right behavior to do the conversion properly. I am still researching, but so far, looks good.
Take a look at this :
Form Values to be Null instead of "" in Spring
http://kaushalyas.blogspot.com.ar/2011/02/data-binding-in-spring-mvc.html
Hope it helps to found the solution!
Greetings
Victor.
I am getting an exception on my server at the datacenter, BUT I am not getting the error on my dev box, nor on my server in our offices.
Here is my contoller method
[HttpPost]
public ActionResult Index(IndEvent[] events)
I have a bunch of checkboxes on my view that mvc then gives me an array of IndEvents and the checkboxes are bound to a bool.
If the user does not check any boxes, I get a full array with the bool being false.
At the datacenter when the user does not check any of the boxes, I get back a string[], not an IndEvent[].
Message: The parameters dictionary contains an invalid entry for
parameter 'events' for method 'System.Web.Mvc.ActionResult
Index(MAC.Common.WebMACTexas.Areas.IndustryEvent.Models.IndEvent[])'
in
'MAC.Common.WebMACTexas.Areas.IndustryEvent.Controllers.RegisterController'.
The dictionary contains a value of type 'System.String[]', but the
parameter requires a value of type
'MAC.Common.WebMACTexas.Areas.IndustryEvent.Models.IndEvent[]'.
MVC Version locally: 3.0.11209.0
MVC Version at DataCenter 3.0.11209.0
++in case you didn't read the first line of this post here it is:
I am getting an exception on my server at the datacenter, BUT I am not getting the error on my dev box, nor on my server in our offices.
There is now way u will pass a object(s) via the webrowsers. You can only pass strings your Index should look something like
public ActionResult Index(string somepropetry)
{
using(var context = new SiteContext())
{
var events = context.IndEvents.where(e=>e.property.equal(someproperty).toList();
return View(events)
}
}
depending on how u want to filter it
I have some issue with validation of parameters passed to a controller method.
Following the suggestion from the tutorial, I am using the same controller method for "save" and "create new" of an entity. See example in
http://www.playframework.org/documentation/1.2.4/guide9
So, my controller method looks like:
public static void saveEntity(long l, Long itemId,
#Required(message="error.shouldspecifyname") String name,
#Required(message="error.shouldspecifycategory") String category)
If 'itemId' is not part of the data sent via an HTTP request - it is supposed to be set to 'null'.
Unfortunately, it seems like "Play" is automatically adding a validation error on the "missing" parameter.
When looking into the validation errors' list, every time 'itemId' is 'null' - I am getting an error Incorrect value for field itemId
Is it a documented behavior? Any way to override it, or "get rid" of the error.
I am handling the errors simply using redirection, like:
if(validation.hasErrors() )
{
validation.keep();
showSomePage();
}
So the errors are displayed "out of the context" they get generated. This is the reason the "automatic" error bothers me.
Thanks for any hint.
Most likely it fails to validate itemId because it's declared as Long, are you sure you have "Long" there ant not just "long"? We are using validation with controllers every where and it works with #Required and passed "null" to "Long" values.
Worst case you can remove error from validation object based on "itemId" key, also if you're using controller to save model object, you might want to use:
public static void saveEntity(#Required #Valid MyEntity entity) {
if(validation.hasErrors() ) {
validation.keep();
showSomePage();
}
entity.save();
}
It will automaticly hook your changes inside existing entity if you pass ID from page with:
<input type="hidden" name="myEntity.id" value="${myEntity.id}">