DefaultModelBinder: IList vs List - asp.net-mvc

I'm not sure if this is a bug, or a feature. I have an action param that takes a ListRequest object with a few string properties. .NET MVC dutifully maps the query string params of the same name to the ListRequest objects' properties.
I add a ListRequest.Filters property, which is to be a list of strings taken from the querystring: ?filter=foo&filter=bar
If I declare .Filters as a Get/Set of type List(Of String), DefaultModelBinder does exactly what you would expect. However, if I declare .Filters as a Get/Set of IList(Of String) instead, DefaultModelBinder stops binding values to that property completely.
Is this a feature, or a bug?

Sounds like a feature to me. The model binder needs concrete types to bind to.
If you tell it to bind to an interface it can't do anything because it can't instantiate an interface to bind to.
EDIT: Interesting
Judging by the source code, it seems that it will bind to a model that is a generic type of IEnumerable, ICollection, IList or IDictionary BUT it won't bind on a model's property that is of a generic type.
So I wouldn't say it's a bug... I'd just say that it's a feature that they have overlooked. :-)

Related

Why is Dart's Datetime.parse not a factory constructor?

Dart's Datetime class has a number of named constructors, but DateTime.parse() is not one of them. Instead, DateTime.parse() is a static method which returns a DateTime. To me, it makes sense as a constructor (since you are generating a new DateTime object in a manner not too different from the Datetime.utc() constructor).
Theories I've come up with are to mirror the fact that int.parse is not a constructor or to allow easier chaining (you don't need to use the cascade operator with a static method). But maybe there is another reason that I'm not thinking of. Does anyone know why they didn't make it a named constructor?
More explanation for the same change for Uri.parse: http://permalink.gmane.org/gmane.comp.lang.dart.general/17081
"parse" is special. The question is: do you see parsing as an
operation that does something and ends up giving you the result, or do
you see the string as data to construct a new element. If you see it
as the earlier, then "parse" should be a static function. If you see
the string as the data, then it should be a named constructor.
And then, of course, there is consistency.

difference between wrapper class and primitive type definition

I am working on Struts 2 and using Eclipselink JPA.
In my entity classes, I have defined a variable of primitive type, i.e private int ductRun; and other one of wrapper class type i.e private Integer ductQty.
On the JSP page, if user submit the form leaving both the fields blank, the primitive type variables(ductRun) gets initialize automatically to "0", and wrapper type variable (ductQty) remain null. And the validation required of struts for field ductRun is not working.
Now I want to know the reason behind it, where is initializing the ductRun and whether it is a good approach to define all the variables in entity class of primitive type.
Hope it is understandable.

displaytag in Struts2 is unable to find the properties with capitalized first letter

When I'm displaying the properties with name user_id its perfectly showing. But If I want to display the values like "User_id " its prompting to cant find the property (NOMETHODFOUND EXCEPTION)
and also Inappropriate OGNL expression: (d - 49216) - s
This is not related to Struts2, and definitely not related to DisplayTag.
This is about OGNL and JavaBeans Naming Conventions.
As described in the JavaBeans PDF by SUN,
8.3 Design Patterns for Properties
8.3.1 Simple properties
By default, we use design patterns to locate properties by looking for methods of the form:
public <PropertyType> get<PropertyName>();
public void set<PropertyName>(<PropertyType> a);
If we discover a matching pair of “get<PropertyName>” and
“set<PropertyName>” methods that take and return the same type, then
we regard these methods as defining a read-write property whose name
will be “<propertyName>”. We will use the “get<PropertyName>”
method to get the property value and the “set<PropertyName>” method
to set the property value. The pair of methods may be located either
in the same class or one may be in a base class and the other may be
in a derived class.
If we find only one of these methods, then we regard it as defining
either a read-only or a writeonly property called “<propertyName>”
By default we assume that properties are neither bound nor constrained
(see Section 7).
So a simple read-write property “foo” might be
represented by a pair of methods:
public Wombat getFoo();
public void setFoo(Wombat w);
8.3.2 Boolean properties
In addition, for boolean properties, we allow a getter method to match
the pattern:
public boolean is<PropertyName>();
This “is<PropertyName>” method may be provided instead of a
“get<PropertyName>” method, or it may be provided in addition to a
“get<PropertyName>” method.
In either case, if the
“is<PropertyName>” method is present for a boolean property then we
will use the “is<PropertyName>” method to read the property value.
An example boolean property might be:
public boolean isMarsupial();
public void setMarsupial(boolean m);
Please read about Java Naming Conventions and CamelCase practice too.
That said, your property user_id (that should be named by convention userId), has a getter like public String getUser_id() (if it is a String, but an ID should not be a String);
this means that you get it from OGNL with "user_id", and not with "User_id".
If the result you are trying to achieve is to capitalize the CONTENT of user_id variable,
then you should go for another way (another getter with capitalized result, like getUser_idCapitalized, or a static call from OGNL to a funcion like WordUtils.capitalize(str) by Apache, like described here, etc...

Serializing Interface objects to JSON

I have a number of interfaces I use to pass business objects around in my application. Using Ninject, I can do whatever I want with them without needing to know the type of the actual object; in this case, most of them are actually various Linq to Sql objects that implement the interface.
For example, I have a Linq to Sql object called Listing that implements IListing.
Where I've run into a problem is with serialization. I've tried using the built in JsonResult and JsonNet. Both of them attempt to serialize the actual Linq to Sql object, not just the properties defined in the interface type. This leads to circular reference issues, but the larger problem is that I only want the properties defined in the interface being serialized and passed around.
So, is there an elegant way to serialize just the properties defined in an instance of an interface that I pass to a serializer?
You could define a new transport type containing only the properties you need and then use AutoMapper to convert between your domain object to this type which will be used for serialization.

How to cast IQueryable to IQueryable<T> when I don't know the T in advance?

I have an asp.net mvc view, which is using Telerik's grid.
Html.Telerik.Grid(Model.Items)
Model.Items is IQueryable, but the Grid requires me to cast it:
For example:
Html.Telerik.Grid((IQueryable<Product>)Model.Items)
The problem is: I don't know what type is in Model.Items (it can be IQueryable<Product>, IQueryable<Book> and many others).
What I also have is Model.ItemsType, which can have following values: typeof(IQueryable<Product>), typeof(IQueryable<Book>)...
How can I cast the IQueryable to IQueryable<T>, when I don't know the type of T in advance?
Generic types need to be known at compile-time, not determined at run-time.
What is the type of Model.Items? If it's derived from IEnumerable<T> then assuming you have a reference to System.Linq then you should be able to call the AsQueryable() extension method.
You're going to need to use reflection to invoke the Grid method when you don't know the T ahead of time, because there's no way to do it at compile time. If Model.Items actually is an IQueryable, then you don't need to cast it; just pass it along as the parameter during the reflection-based invocation (which takes all parameters as type object anyway).
Perhaps you can try binding to IEnumerable. Check the 'Binding to a collection of dynamic objects with MVC3 Razor' code library entry.

Resources