1

我正在尝试创建一个RESTful Web服务,该服务返回使用ASP.NET MVC4 Web API的产品列表。这里是我的控制器类ASP.NET MVC4 Web API控制器序列化

public class ProductController : ApiController 
{ 
    public IEnumerable<Product> GetProducts() 
    { 
     WebCatalogContext dbcontext = DatabaseConfig.Instance.Context; 
     List<Product> plist = dbcontext.Products.ToList(); 
     return plist; 
    } 
} 

当我跑我的服务,并从我的浏览器中调用以下URL:/ API /产品,我得到System.Runtime.Serialization.SerializationException。我看着我的plist物体,它没有问题。

这里是我的数据模型:

[DataContract(Name = "p")] 
[Serializable]  
public class Product 
{ 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    [DataMember(Name = "id")] 
    public int Id { get; set; } 

    [Required, MaxLength(50)] 
    [DataMember(Name = "ti")] 
    public string Title { get; set; } 

    [Required] 
    [DataMember(Name = "de")] 
    public string Description { get; set; } 

    [Required] 
    [DataMember(Name = "ph")] 
    public string PhotoURL { get; set; } 

    [DataMember(Name = "ca")]   
    public virtual ProductCategory Category { get; set; } 
} 


[DataContract(Name="pc")] 
[Serializable] 
public class ProductCategory 
{ 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    [DataMember(Name="id")] 
    public int Id { get; set; } 

    [DataMember(Name="nm")] 
    public string Name { get; set; } 
} 

当我从我的产品类中删除提及产品分类,所有工作的事情就好了。但是,当我包含它时,我得到以下异常。

Type 'System.Data.Entity.DynamicProxies.Product_664E9A0AA1F165A26C342B508BFFF1279FD3FE059285225BDA19F407A29A9CAD' with data contract name 'Product_664E9A0AA1F165A26C342B508BFFF1279FD3FE059285225BDA19F407A29A9CAD: http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies ' 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.

约我缺少的是什么你知道吗?

问候

回答

1

实体框架已经包裹你的POCO与EF代理POCO,因此它能执行延迟加载 - 这个使用Virtual属性来创建一个“懒加载”导航属性。我期望这是序列化错误的来源。

您可以创建一个新类并将POCO映射到该类 - 然后从控制器传递DTO样式类。我从来没有直接从API返回EF对象(我总是映射一些其他的东西),所以我不知道另一种选择。

EF POCO到DTO(数据传输对象)相对无痛如果你使用像http://valueinjecter.codeplex.com/http://automapper.org/

+0

感谢您的回答,非常有帮助 – Furkan 2013-03-14 08:47:55

1

工具为了支持迟缓装载的用于其被声明为virtual导航属性,EF将生成的任何模型的代理其导航属性会导致这种异常。

对于非常简单的应用程序,您可以使用EF中的模型作为DTO(如果没有导航属性),但对于复杂的应用程序,您应该单独区分DTO和域模型。它不应该在DTO和域模型之间映射1:1。

因此,在你的情况下,你为Web API层创建更多的DTO模型,它会没事的。