POCO class not returned from WCF

c# entity-framework entity-framework-6 poco wcf

Question

I'm working on three things:

  1. In the DAL class library, I'm using EF 6.1.
  2. service library for WCF
  3. WPF client program

The WCF project is referenced as a service in the WPF application. When I tried anything like this, I ran into trouble:

public List<DbTable> GetItems()
{
    try
    {
        IQueryable<DbTable> items;
        using (var dbContext = new MyEntities())
        {                                        
            items = dbContext.Items.Select(a => a);
            return items.ToList();  
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex);
        return null;
    }
}

I was receiving the general HTTP not set correctly error message and no results were being returned by the WCF Service.

I created POCO classes in the WCF service after reading some, and this worked.

using (var dbContext = new MyEntities())
{
   var items = dbContext.Items.Select(a =>
       new MyPocoClass
       {
           ItemId = a.ItemId,
           Name = a.Name
       });
   return items.ToList();
}

I want to know if I have to create POCO classes to transfer the data back and forth or can I just return the entity framework object. If I do, am I doing something wrong?

This is what I get when I try to return any EF object:

like return dbContext.Items.ToList();

I can only get it to operate by use a POCO class.

enter image description here

Update:

This is my service configuration file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="MyProject.WebService.MyWebService">
        <endpoint address="" binding="basicHttpBinding" contract="MyProject.WebService.IMyWebService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/Design_Time_Addresses/MyProject.WebService/MyWebService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

And my customer:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IMyWebService" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"/>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8733/Design_Time_Addresses/MyProject.WebService/MyWebService/" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyWebService" contract="ServiceReference.IMyWebService" name="BasicHttpBinding_IMyWebService" />
    </client>
  </system.serviceModel>
</configuration>

Re-Update-

Inner Exception:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
1
2
3/23/2014 5:43:24 AM

Accepted Answer

ZZZ_tmp
2
9/29/2016 6:44:23 AM

Popular Answer

As your model becomes more sophisticated, Lazy Loading causes all kinds of issues if you try to return the things directly, hence I believe you should preserve the DTO layer (POCOs) (depending on your data structure). If your relationship arrangement is quite typical, for instance:

  • A client has numerous contacts.
  • A Contact has numerous Orders.
  • Many Line Items are in a single Order.
  • One Line Item has numerous entries for Store Inventory Level.
  • A Line Item with Numerous Photographs
  • etc.

    public class Client
    {
      public int ClientId { get; set; }
      public string ClientName { get; set; }
      public IList<Contact> Contacts { get; set; }
    }
    
    public class Contacts
    {
      public int ContactId { get; set; }
      public string ContactName { get; set; }
      public IList<Order> Order { get; set; }
    }
    

The serializer will access all of the entity's properties when you attempt to transmit a client object over the WCF boundary and load any relevant entities (Contacts, Orders, Line Items, Store Inventories, Photograhs).

This could result in a massive data loading cascade or fail because of circular references.

However, there are a number of other benefits to not passing things around, such as avoiding the need to rebuild client apps in the event that your database schema changes. If you stop lazy loading, your object will be filled with nulls.

If you find it time-consuming to create the DTO -> Entity -> DTO mapping, check out AutoMapper, which can handle this.

Writing a unit test for this mapping using AutoFixture and DeepEqual is beneficial in my opinion.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow