1

Я пытаюсь создать веб-службу RESTful, которая возвращает список продуктов с использованием ASP.NET MVC4 Web API. Вот мой контроллер классСериализация контроллера веб-API ASP.NET MVC4

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

Когда я удалить ссылку на 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.

Любая идея о том, что мне не хватает?

С уважением

ответ

1

Entity Framework обернул свой ПОКО с EF прокси POCO, чтобы он мог выполнять отложенную загрузку - это использует атрибут Virtual для создания «ленивый загружаемый» свойство навигации. Я ожидаю, что здесь возникает ошибка сериализации.

Вы можете создать новый класс и сопоставить POCO с этим - затем передать класс стиля DTO с контроллера. Я никогда не возвращал объект EF непосредственно из API (я всегда сопоставляю что-то еще), поэтому я не знаю другого варианта.

EF POCO в DTO (данные объекта передачи) является относительно безболезненно, если вы используете инструмент, как http://valueinjecter.codeplex.com/ или http://automapper.org/

+0

благодарит за ответ, очень полезно – Furkan

1

Для поддержки отложенной загрузки для навигационных свойств, который объявлен как virtual, EF будет генерировать прокси для любых моделей которые обладают свойствами навигации, что приводит к такому виду исключений.

Для очень простого применения вы можете использовать модель из EF в качестве DTO (если у нее нет свойств навигации), но для сложного приложения вы должны делать раздельные и отличаться между DTO и моделями доменов. Он не должен отображать 1: 1 между DTO и моделью домена.

Таким образом, в вашем случае вы создадите больше модели DTO для уровня веб-API, это будет нормально.

Смежные вопросы