Red Swan
Red Swan

Reputation: 15545

Error while using Linq "Include" method with Entity framework 4.1, Bug?

I am using SQL Azure as database with code first technique of Entity framework 4.1. I'm accessing EF from WCF as middle tier and providing the service reference to ASP.NET MVC 3.

The relational scenario in EF is A->B->C so as usual I tried to get A including B including C with few possibilities:

db.A.Include("B").Include("B.C")
db.A.Include("B").Include("C")

But in the Service itself running perfect. Since adding the reference to the web application it attempts to serialize and throws the exception below. I tried to make true-false lazy loading also without success.

"The underlying connection was closed: The connection was closed unexpectedly"
Stack Trace found:
 at System.Net.HttpWebRequest.GetResponse() at
 System.ServiceModel.Channels.HttpChannelFactory.
     HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

I visited this page to resolve, and added the suggested attributes in web.config. Now I'm suddenly getting error:

The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error

I thought it might be issue of some tag/atrribute mismatch in client and service web.configs but everything is right there. One thing I could not get to passing the List of objects with loading of its entire cllection properties, from wcf service to web application is found very heavy and low in performance. still facing the above issues to get the loaded list at web application in above explained architecture. can some body help here....

Upvotes: 0

Views: 1507

Answers (2)

Red Swan
Red Swan

Reputation: 15545

hey Thanks Kirk Broadhurst , By this I could track the Issue. and searche around it. I got the solution. I added this class in my project

public class ReferencePreservingDataContractFormatAttribute : Attribute, IOperationBehavior
        {
            #region IOperationBehavior Members
            public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
            {
            }

            public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
            {
                IOperationBehavior innerBehavior = new ReferencePreservingDataContractSerializerOperationBehavior(description);
                innerBehavior.ApplyClientBehavior(description, proxy);
            }

            public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
            {
                IOperationBehavior innerBehavior = new ReferencePreservingDataContractSerializerOperationBehavior(description);
                innerBehavior.ApplyDispatchBehavior(description, dispatch);
            }


            public void Validate(OperationDescription description)
            {
            }
            #endregion
        }

        class ReferencePreservingDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior
        {
            public ReferencePreservingDataContractSerializerOperationBehavior(OperationDescription operationDescription) : base(operationDescription) { }
            public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
            {
                return CreateDataContractSerializer(type, name, ns, knownTypes);
            }

            private static XmlObjectSerializer CreateDataContractSerializer(Type type, string name, string ns, IList<Type> knownTypes)
            {
                return CreateDataContractSerializer(type, name, ns, knownTypes);
            }

            public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
            {
                return new DataContractSerializer(type, name, ns, knownTypes,
                0x7FFF /*maxItemsInObjectGraph*/,
                true/*ignoreExtensionDataObject*/,
                true/*preserveObjectReferences*/,
                null/*dataContractSurrogate*/);
            }
        }
    }

And Added just : [ReferencePreservingDataContractFormat] as an attribute with the method definition where i wanted to use the "Include". thats it worked for me. This might be helpful for other needy people.

Upvotes: 2

Kirk Broadhurst
Kirk Broadhurst

Reputation: 28728

This is a very common WCF exception and can be any number of things. There are hundreds of hits on StackOverflow for this problem.

https://stackoverflow.com/search?q=%22The+underlying+connection+was+closed%22

Are you new to WCF? Do any service calls work? It could be something as simple as maxMessageSize exceeded.

I'd suggest you implement logging on your service - add some diagnostics tags to your configuration file.

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData="c:\log\Traces.svclog"  />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

Upvotes: 0

Related Questions