1

我正在尝试创建一个 RESTful Web 服务,它使用 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/Product 时,我得到 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; }
}

当我从 Product 类中删除对 ProductCategory 的引用时,一切正常。但是,当我包含它时,我得到以下异常。

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.

关于我缺少什么的任何想法?

问候

4

2 回答 2

1

实体框架使用 EF 代理 POCO 包装了您的 POCO,因此它可以执行延迟加载 - 这使用该Virtual属性来创建“延迟加载”导航属性。我希望这就是序列化错误的来源。

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

如果您使用http://valueinjecter.codeplex.com/http://automapper.org/之类的工具,EF POCO 到 DTO(数据传输对象)相对容易

于 2013-03-14T08:10:23.680 回答
1

为了支持声明为的导航属性的延迟加载virtual,EF 将为任何具有导致此类异常的导航属性的模型生成代理。

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

因此,在您的情况下,您为 Web API 层创建更多的 DTO 模型,就可以了。

于 2013-03-14T08:14:36.267 回答