Spring Validation - BindingResult - spring

I am trying to understand what BeanPropertyBindingResult does in the following code. Unfortunately, the javadoc is quite useless.
Please take a look at the following code:
BeanPropertyBindingResult errors = new BeanPropertyBindingResult(item, "item");
validator.validate(item, errors);
My questions are:
As far as I can see, BeanPropertyBindingResult is basically some kind of a Map that can contain key/value pairs of (field name, error text). Is this correct, or is the truth more complicated?
When I create a new BeanPropertyBindingResult, why do I need to provide it (as the constructor's first parameter) with the object I am going to validate? As far as I can see, in the second line above, validator.validate(item, errors); the validator gets the object anyway.. so why doing it twice?
The javadoc says about the constructor's second parameter:
objectName - the name of the target object
yes, but why do I need that name? What am I supposed/able to do with it...?

1) Yes, that is my understanding too, even if it is technically a list. -- The most importent part is List<ObjectError> errors defined in the superclass AbstractBindingResult.
2) Because it is demanded by the BindingResult Interface. -- I know this is not a good answer, but If this interfaces requires that method, then ther is no otherway to implement it BTW: I think I have seen some example before where the Autor used null for that field, but I am not 100% if it works correct, but most of the code seams to be able to handle the null value.
3) If you use that binding result for example in a jsp to show the error messages for different input fields, then this must match the model attribute name.
Assume you have a command object with a field name. And a JSP page where the input filed is associated to myCommand.name. Then you need the name myCommand as some kind of prefix for the binding errors. -- It is hard to explain, I hope you understand what I mean

Related

How are request parameters mapped into RenderingModel of magnolia?

Im using Magnolia RenderingModel in combination with Freemarker.
I have URLs like the following:
http://anyPath/context?productTypes=XXXXX&productTypes=YYYYY
my rendering model class looks like:
class MyModel extends RenderingModelImpl {
...
private String[] productTypes;
...
}
However the mentioned array contains only the first value, but not the second.
I checked the behaviour of template directives like ctx.getParameters(). This shows the same behaviour, I get only the first value returned. But if im using ctx.getParameterValues(paramName), it returns both values.
This leads me to following questions:
How would I go, if I want to lookup how the request parameters are mapped into the rendering model, or better:
How can i change the behaviour of that ?
Can anyone acknowledge, that this behaviour is wrong ?
It used to be mentioned in documentation and I believe it still is - if you use .getParameters() you get only first value for multivalue parameter. If you want to get all the values, you need to use .getParameterValues(String param).
From what I understand reasons for that were backward compatibility.
As for changing the behavior, you would need to write your own renderer (e.g. by extending default FreemarkerRenderer and override info.magnolia.rendering.renderer.AbstractRenderer.newModel(Class<T>, Node, RenderableDefinition, RenderingModel<?>) method which instantiates and populates the model class.
Alternatively you can provide fix for above set population method and submit it to Magnolia as a patch. While the .getParameters() behavior is iirc on purpose, the model param population might not be, so you have high chance of getting that changed.

Get Class of Map in FreeMarker

I want to get a variable's class type in freemarker, used var.class.simpleName;
but if var is a Map, freemarker will process class as a key to find value in var.
it throw exception. how can I do this ? thanks for any suggestion.
First I have to ask why do you need that, because FreeMarker templates aren't supposed to know even if var is Map at all. Maybe your data-model is not what the template needs.
Anyway, for now, I would write a custom TemplateMethodModelEx for this purpose, something that you can use like ${classOf(var)}. Inside the TemplateMethodModelEx implementation you will receive a TemplateModel as the argument value, and then you can check if it's an AdapterTemplateModel, and if so you can get back the original object and get its class. (If it's not a AdapterTemplateModel, then it perhaps isn't even a wrapped Java object, so it doesn't make sense to ask what the class of the original object is.) However, the DefaultObjectWrapper with incompatibleImprovements set to less than 2.3.22 doesn't give AdapterTemplateModel to wrapped Map-s... so in 2.3.21 you will still have to use BeansWrapper, but you can at least set simpleMapWrapper to true.
In 2.3.22 it will be actually possible to write ${var?api.class}... you might use the nightly build. Though it only supposed to solve the problem where you can't access business methods because the primary type of the business class is Map.

ASP.NET MVC 3: how to get parameters the action method was called with?

How do you get the object parameters, which action method was called with at run-time, to accomplish something to the effect of the following
public ActionResult Index(Int32? x, Int32? y, DateTime? z, NumberStyles n) {
this.RouteData.Values["x"] = x
this.RouteData.Values["y"] = y
this.RouteData.Values["z"] = z
this.RouteData.Values["n"] = n
return View();
}
It seems like it should be a possible to the names and values of each parameter without this kind of tedious code.
Sometimes you can get the parameters which the action method was called with, by looking in RouteData, but this isn't always the case, particularly if the action method was invoked with an ajax request, the parameters may not show up in the RouteData, and instead show up in the Request Params.
What I'm looking for, is a generic way to get each parameter that is defined in the action method signature at run-time, and gets the parameter's actual object, run-time value, not just a string. Further more, it should work no matter how the action method was invoked, whether it may be the result of ChildActionExtensions.Action or an ajax callback.
RouteData and Request Params don't seem to have what I'm looking for.
Your code sample is setting values back into the RouteData collection. Are you trying to pass parameters to your view using the RouteData collection? That's not what it exists for, you might consider using ViewBag instead.
Or, create a POCO which contains all your properties and let the data binder do all the work (so use #model YourType in your view and pass a single argument to your view. The default model binder will map the individual argument values for you).
As far as the input value collections are concerned, there's a good reason why the value is not to be found consistently in the collections you've mentioned.
Perhaps the trick here is to clarify what's going on prior to your action being invoked. The arguments to your action method can come from more than one source. For example, it may come from:
The URL Path
The URL query string (eg: in a GET, the parameters after the question mark ?)
POSTed form data
Explicit arguments from another action
In your code sample above, the RouteData collection will only contain the value of "x" if your route has a matching parameter name.
For example: "{controller}/{action}/{x}". (this is a custom route pulling "x" from the path)
Failing that, the values will be resolved using the default model binder and will be pulled from either the query string parameters or POST data as the case may be.
The route value will take precedence. So if the above custom route was applied, the following URL:
http://www.example.com/Something/Index/1?x=2
would invoke your action with x=1. The 1 would then be found in the RouteData as pulled from the URL path and the x=2 found in the Request.QueryString would be ignored.
If you are concerned with how x got its value, then you must take into account all of the above so you know where to look. There is also the question of which route is applied to the request, but that's another topic altogether.
All the input came across the wire as text.. it was the model binder that examined your action signature and converted to the types you specified (wherever that is possible).
So, I don't think what you are asking for exists even conceptually in this setting.

MVC3 query string parameter and input field share same name

I have a queryparameter named "from" (a from date)
and also a input which binds to a property named From
In my ViewModel contructor i set the From property to a date...
This works if the query parameter name and the property name are different, but if they are same MVC3 with some magic takes whatever value there are in the query param and binds against that, it does not care what value are in the From property.. Why? this atuomagic is so wrong on so many levels! How do I disable it?
edit: It doesnt matter what value the Property gets, if a querystring exists with the same id as the input MVC automatic takes that value and assign it to the input element
You need to call
ModelState.Clear();
Before returning from your controller action.
The issue is that the ModelState has the value from the query string, and that takes precedence over the value in your model when binding occurs.
Whether this is a bug or a feature depends on your point of view... http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx
MVC works by convention, and binds values to the model by names. To understand what is happening, I suggest you read this blog article from Phil Haack: What’s the Difference Between a Value Provider and Model Binder?
It is bad practice to have two unrelated elements with identical names in the same request, as a name collision is very likely to cause unexpected problems. Best practice is to rename one of these elements so that you eliminate the name collision.

How Does Queryable.OfType Work?

Important The question is not "What does Queryable.OfType do, it's "how does the code I see there accomplish that?"
Reflecting on Queryable.OfType, I see (after some cleanup):
public static IQueryable<TResult> OfType<TResult>(this IQueryable source)
{
return (IQueryable<TResult>)source.Provider.CreateQuery(
Expression.Call(
null,
((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(
new Type[] { typeof(TResult) }) ,
new Expression[] { source.Expression }));
}
So let me see if I've got this straight:
Use reflection to grab a reference to the current method (OfType).
Make a new method, which is exactly the same, by using MakeGenericMethod to change the type parameter of the current method to, er, exactly the same thing.
The argument to that new method will be not source but source.Expression. Which isn't an IQueryable, but we'll be passing the whole thing to Expression.Call, so that's OK.
Call Expression.Call, passing null as method (weird?) instance and the cloned method as its arguments.
Pass that result to CreateQuery and cast the result, which seems like the sanest part of the whole thing.
Now the effect of this method is to return an expression which tells the provider to omit returning any values where the type is not equal to TResult or one of its subtypes. But I can't see how the steps above actually accomplish this. It seems to be creating an expression representing a method which returns IQueryable<TResult>, and making the body of that method simply the entire source expression, without ever looking at the type. Is it simply expected that an IQueryable provider will just silently not return any records not of the selected type?
So are the steps above incorrect in some way, or am I just not seeing how they result in the behavior observed at runtime?
It's not passing in null as the method - it's passing it in as the "target expression", i.e. what it's calling the method on. This is null because OfType is a static method, so it doesn't need a target.
The point of calling MakeGenericMethod is that GetCurrentMethod() returns the open version, i.e. OfType<> instead of OfType<YourType>.
Queryable.OfType itself isn't meant to contain any of the logic for omitting returning any values. That's up to the LINQ provider. The point of Queryable.OfType is to build up the expression tree to include the call to OfType, so that when the LINQ provider eventually has to convert it into its native format (e.g. SQL) it knows that OfType was called.
This is how Queryable works in general - basically it lets the provider see the whole query expression as an expression tree. That's all it's meant to do - when the provider is asked to translate this into real code, that's where the magic happens.
Queryable couldn't possibly do the work itself - it has no idea what sort of data store the provider represents. How could it come up with the semantics of OfType without knowing whether the data store was SQL, LDAP or something else? I agree it takes a while to get your head round though :)

Resources