Избегайте сериализации определенных свойств в службах REST - PullRequest
3 голосов
/ 23 сентября 2010

У меня есть приложение .Net, разделенное на стороны клиента и сервера, и сервер предоставляет услуги REST (с использованием WCF).У меня есть определения служб, подобные этим:

[WebGet(UriTemplate = "/Customers/{id}")]
Customer GetCustomerById(string id);

[WebGet(UriTemplate = "/Customers")]
List<Customer> GetAllCustomers();

Класс Customer и его друзья сопоставляются с базой данных с помощью Fluent NHibernate с Lazy Loading.Если я вернусь из службы за пределами Session-scope, вызов службы завершится неудачно, поскольку он не сможет сериализовать ссылочное свойство отложенной загрузки Orders (см. Определение класса в конце).Проблема в том, что мне нужно, чтобы это было лениво загружено, так как я не хочу, чтобы мой GetAllCustomers -сервис извлекал все указанные Заказы.Поэтому я хочу как-то уведомить сериализатор, чтобы он не пытался сериализовать Orders на GetAll.Но обратите внимание, что одно и то же свойство должно быть сериализовано в GetCustomerById - поэтому я должен указать это для службы.Можно ли это сделать ?!

Классы:

public class Customer
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Order> Orders { get; set; }
}

public class Order
{
    public virtual int Id { get; set; }
    // ++ 
}

Ответы [ 4 ]

3 голосов
/ 23 сентября 2010

Если вы используете сериализацию WCF по умолчанию - что, я думаю, вы делаете - вы бы явно отметили свойства, которые вы хотите отправить по проводам, и оставили остальные.Это делается с помощью [DataMember], который, как я полагаю, вы делаете:

[DataContract]
public class Customer
{
    [DataMember]
    public virtual int Id { get; set; }

    [DataMember]
    public virtual string Name { get; set; }

    // not decorate 
    public virtual IList<Order> Orders { get; set; }
} 

ОБНОВЛЕНИЕ ОК, вам нужно отправлять иногда, а не отправлять в другое время.Очевидно, что у вас может быть класс CustomerBase (без заказов), а затем Customer (заказы не оформлены) и CustomerWithOrders (оформленные заказы).Отправьте каждую из ваших операций.

Если это вас не устраивает, взгляните на пользовательскую сериализацию, используя DataContractSerializerOperationBehavior и IDataContractSurrogate здесь:

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.idatacontractsurrogate.aspx

http://msdn.microsoft.com/en-us/library/system.servicemodel.description.datacontractserializeroperationbehavior_members.aspx

2 голосов
/ 23 сентября 2010

Иметь разные DTO для разных сценариев, а затем использовать Automapper для переноса ваших объектов nhib в DTO - таким образом, у вас есть специализированный граф объектов для каждого случая, и нет никакого способа, которым вы могли бы его иттерировать и, таким образом, гидрировать коллекции, которые вы не хочу.

1 голос
/ 23 сентября 2010

Я бы либо вернул другой контракт с данными для услуги GetAllCustomers.Например,

[DataContract]
public class CustomerSummary
{
   // Have properties that represent the summary of the customer
}

WebGet(UriTemplate = "/Customers/{id}")]    
Customer GetCustomerById(string id);    

[WebGet(UriTemplate = "/Customers")]    
List<CustomerSummary> GetAllCustomers();

или используйте EmitDefaultValue при применении атрибута DataMember к свойству Orders:

[DataContract]       
public class Customer       
{       
   [DataMember]       
   public virtual int Id { get; set; }       

   [DataMember]
   public virtual string Name { get; set; }       

   [DataMember(IsRequired = false, EmitDefaultValue = false)]
   public virtual IList<Order> Orders { get; set; }       
}

, а затем просто оставьте свойство Orders как нулевое, когдаGetAllCustomers возвращает данные.

0 голосов
/ 23 сентября 2010

Ленивая загрузка работает только в рамках сеанса гибернации. Нет шансов сделать это по проводам. Вам нужно срочно получить коллекцию или использовать наследование ООП и вернуть из веб-метода класс, у которого этой коллекции нет вообще, особенно если она не нужна пользователям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...