I want to use the following pattern in my controllers:
api/{controller}/{id}/{collection}
Example: api/customers/123/addresses
But I want to return IQueryable Of T
from the corresponding Get action. I want something like this (simplified):
public IQueryable<????> GetCollection(int id, string collection)
{
switch(collection)
{
case "addresses":
return _addresses.AsQueryable();
break;
case "orders":
return _orders.AsQueryable();
break;
default:
throw new Exception(NotSupported);
}
}
Can this be done?
What would be the recommended approach?
@SLacks is correct that you should return IQueryable<object>
or IQueryable<someBaseType>
if you can.
The error your getting is a function of the DataContract Serializer. So you have a few options.
For the "teach" option, you can teach in two ways.
(A) leverage the [KnownType(typeof(...))]
attribute. Here's a post on the KnownType
attribute. It's for WCF but should get you started.
(B) use a data contract resolver. This post should get you started.
Expanding on what @Ebarr said, the easiest way to accomplish this is to update the various classes which you want to be able to return this way, and have them inherit from a common base class or interface.
Example:
[KnownType(typeof(Address))]
[KnownType(typeof(Order))]
public abstract class _BaseObject { }
public partial class Address : _BaseObject { }
public partial class Order : _BaseObject { }
Now you can have your controller method look like:
public IQueryable<_BaseObject> GetCollection(int id, string collection) {
switch(collection) {
case "addresses":
return _addresses.AsQueryable();
case "orders":
return _orders.AsQueryable();
default:
throw new NotSupportedException();
}
}
Note that the [KnownType]
attribute is in System.Runtime.Serialization
. You should also be aware that this method will result in exactly what you would expect with regards to JSON
serialization - but XML
serialization will generally result in tags which show your objects as the base class (because that's what you returned) rather than the sub-classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With