Служба WCF REST не возвращает объект DataContract

У меня есть простая служба WCF, определенная следующим ServiceContract:

[ServiceContract]
public interface IInventoryService
{
  [OperationContract]      
  Item GetItemFromBarcode(string barcode);

  [OperationContract]
  string Test(string testString);
}

С Item, определенным следующим образом:

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

  <Snip>
}

И фактическая служба реализована таким образом:

public class InventoryService : IInventoryService
{
  [WebGet(UriTemplate = "/Barcode/{barcode}/Item", ResponseFormat = WebMessageFormat.Json)]
  public Item GetItemFromBarcode(string barcode)
  {
     var item = (from b in repository.Query<ItemBarcode>()
             where b.BarcodeData == barcode
             select b.Item).FirstOrDefault();
     return item;

  }

  [WebGet(UriTemplate = "/Test/{testString}",ResponseFormat=WebMessageFormat.Xml)]
  public string Test(string testString)
  {
     return testString;
  }
}

Со следующим в app.config для программы, в которой размещена служба:

<system.serviceModel>      
  <behaviors>
     <serviceBehaviors>
        <behavior>
           <serviceMetadata httpGetEnabled="true"/>
        </behavior>
     </serviceBehaviors>
     <endpointBehaviors>
        <behavior name="RESTFriendly">
           <webHttp />
        </behavior>
     </endpointBehaviors>
  </behaviors>
  <services>
     <service name="InventoryService">            
        <endpoint address="/Inventory" behaviorConfiguration="RESTFriendly" binding="webHttpBinding" contract="IInventoryService"/>
        <host>
           <baseAddresses>
              <add baseAddress="http://localhost:8080/"/>
           </baseAddresses>
        </host>
     </service>
  </services>
</system.serviceModel>

Теперь, когда дамп кода убран, проблема: я могу просто вызвать метод Test с помощью curl или Fiddler, он возвращает сериализованную строку. Однако вызов метода, возвращающего объект, ничего не возвращает. Керл отплёвывает curl: (56) Failure when receiving data from the peer, а Скрипач отвечает ReadResponse() failed: The server did not return a response for this request.

Из того, что я читал, это должно просто работать (тм). Есть ли что-то очевидное, что я упускаю?


person Matt Sieker    schedule 19.01.2011    source источник
comment
Возможно ли, что в GetItemFromBarcode возникает исключение? Возможно изменение, чтобы просто вернуть созданный встроенный элемент, чтобы убедиться, что ваша конфигурация WCF верна, потому что обработка исключений в WCF REST немного запутана. В качестве альтернативы, что такое остальная часть класса Item, может быть, это проблема сериализации? Вы также можете включить трассировку WCF.   -  person James Webster    schedule 19.01.2011
comment
@James Webster, исключение, которое я могу найти, не выбрасывается (я сказал Visual Studio прерывать все исключения). На самом деле, я думаю, что только что понял проблему.   -  person Matt Sieker    schedule 19.01.2011


Ответы (1)


Итак, кажется, что у вас не может быть DataMember типа интерфейса, такого как IList<ItemBarcode>. Я надеюсь использовать объекты модели NHibernate в качестве DTO.

person Matt Sieker    schedule 19.01.2011
comment
Да, это правильно, я полагаю, потому что десериализатор не знает, какой конкретный тип создать. WCF может сделать предположение о том, какую реализацию использовать; но это, вероятно, нарушит ряд вариантов использования. Следовательно, WCF требует конкретных типов (в большинстве случаев). Я думаю, что использование объектов NHibernate в качестве DTO было бы проблематичным. Возможно, вам следует рассмотреть отдельный уровень DTO и использовать AutoMapper для упрощения сопоставления в обоих направлениях (может быть, даже сгенерировать код DTO с использованием T4?) - person James Webster; 20.01.2011