ASP.NET Web API IQueryable<T> 挑战

4

我希望在我的控制器中使用以下模式:

api/{控制器}/{ID}/{集合}

例如: api/customers/123/addresses

但是我想从相应的Get操作返回IQueryable Of T。 我想要类似于以下内容(简化):

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);  
    }  
}   

这可以做到吗?
推荐采用什么方法?

3个回答

6
@SLacks是正确的,如果可以的话,您应该返回或。
您得到的错误是DataContract Serializer的函数。因此,您有几个选择。
  1. 切换到支持您想要的内容的备用xml序列化程序。
  2. 使用绕过所涉及的序列化程序的形式进行输出(例如JSON使用JSON.net)
  3. 教数据合同序列化程序如何使用
对于“教”的选项,您可以通过两种方式进行教学。 (A)利用[KnownType(typeof(...))]属性。这里是关于KnownType属性的帖子。它是为WCF而设计的,但应该能让您入门。

(B) 使用数据合同解析器。这篇文章应该可以帮助你入门


3

扩展@Ebarr所说的内容,实现这一点最简单的方法是更新您希望能够以此方式返回的各种类,并让它们继承自一个公共基类或接口。

示例:

[KnownType(typeof(Address))]
[KnownType(typeof(Order))]
public abstract class _BaseObject { }

public partial class Address : _BaseObject { }
public partial class Order : _BaseObject { }

现在您的控制器方法可以如下所示:
public IQueryable<_BaseObject> GetCollection(int id, string collection) {  
    switch(collection) {  
        case "addresses":  
            return _addresses.AsQueryable();
        case "orders":  
            return _orders.AsQueryable();
        default:  
            throw new NotSupportedException();  
    }  
}

请注意,[KnownType] 属性位于 System.Runtime.Serialization 中。您还应该知道,对于 JSON 序列化,此方法将产生您所期望的结果 - 但是,XML 序列化通常会导致将您的对象显示为基类的标记(因为这就是您返回的内容),而不是子类的标记。

0

只需返回非泛型的IQueryable
或通过协变性返回IQueryable<object>


很抱歉,这两个建议都失败了。在这两种情况下我都会收到一个异常。 - Jan Ove Halvorsen
IQueryable会出现以下错误:System.Runtime.Serialization.SerializationException: Type 'System.Linq.EnumerableQuery`1[[MvcApplication1.Controllers.Address, MvcApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' with data contract name 'ArrayOfAddress:http://schemas.datacontract.org/2004/07/MvcApplication1.Controllers' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer. - Jan Ove Halvorsen
  1. IQueryable<object> 报错:System.Xml.XmlException: 在写完本地名称为 '__type' 的属性后,必须写一个属性 'type'='object'。
- Jan Ove Halvorsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接