【问题标题】:how to access EF navigation properties via WCF SOAP service?如何通过 WCF SOAP 服务访问 EF 导航属性?
【发布时间】:2020-09-06 15:47:29
【问题描述】:

我正在为这个 WCF 错误苦苦挣扎一段时间,但没有任何运气。基本上我想通过 WCF 服务获取具有导航属性和连接对象的实体 Poco。我的 EF v6 代码成功地从数据库中获取了带有所有相关实体的 poco

Poco debug view

但当我尝试通过 WCF 服务访问此实体时,我看到以下错误 -

接收到http://localhost:8734/Design_Time_Addresses/BusinessLogicServicesLayer/userServices/ 的 HTTP 响应时出错。这可能是由于服务端点绑定未使用 HTTP 协议。这也可能是由于服务器中止了 HTTP 请求上下文(可能是由于服务关闭)。有关更多详细信息,请参阅服务器日志。 服务器堆栈跟踪: 在 System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException,HttpWebRequest 请求,HttpAbortReason abortReason) 在 System.ServiceModel.Channels.HttpChannelFactory1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout) at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout) at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at IuserServicesQuery.getCompleteUserSnapshot(String emailAddress) at IuserServicesQueryClient.getCompleteUserSnapshot(String emailAddress) Inner Exception: The underlying connection was closed: An unexpected error occurred on a receive. at System.Net.HttpWebRequest.GetResponse() at System.ServiceModel.Channels.HttpChannelFactory1.HttpRequestChannel.HttpChannelRequest.WaitForReply(时间跨度超时) 内部异常: 无法从传输连接读取数据:现有连接被远程主机强行关闭。 在 System.Net.Sockets.NetworkStream.Read(字节 [] 缓冲区,Int32 偏移量,Int32 大小) 在 System.Net.PooledStream.Read(字节 [] 缓冲区,Int32 偏移量,Int32 大小) 在 System.Net.Connection.SyncRead(HttpWebRequest 请求,布尔 userRetrievedStream,布尔 probeRead) 内部异常: 现有连接被远程主机强行关闭 在 System.Net.Sockets.Socket.Receive(Byte[] 缓冲区,Int32 偏移量,Int32 大小,SocketFlags socketFlags) 在 System.Net.Sockets.NetworkStream.Read(Byte[] 缓冲区,Int32 偏移量,Int32 大小)

我的 AppConfig 文件如下所示 -

<endpoint address="" behaviorConfiguration="MyBehavior" binding="basicHttpBinding"
          bindingConfiguration="IncreasedTimeout" name="BasicHttpEndpoint"
          contract="BusinessLogicServicesLayer.IuserServicesQuery" listenUriMode="Explicit">
          <identity>
            <dns value="localhost" />
          </identity>
</endpoint>

&&

 <bindings>
      <basicHttpBinding>
        <binding name="IncreasedTimeout"
          openTimeout="12:00:00"
          receiveTimeout="12:00:00" closeTimeout="12:00:00"
          sendTimeout="12:00:00">
        </binding>
      </basicHttpBinding>
    </bindings>

。 .

<behaviors>
  <endpointBehaviors>
    <behavior name="MyBehavior">
      <dataContractSerializer maxItemsInObjectGraph="2147483646" />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>

有人可以帮忙或指出正确的方向

【问题讨论】:

  • 你要直接返回 poco 类吗?
  • 是的,因为没有 DTO 对象。将 POCO 对象直接发送给客户端
  • 最好使用单独的模型来输出...无论如何,某些导航属性无法填充,可以延迟加载,因此您可以在返回对象之前获取数据...尝试使用 var result = poco.ToList() 或类似的东西来返回 poco 对象中的所有数据

标签: wcf


【解决方案1】:

这是因为返回数据时,序列化失败,导致WCF服务自动停止。

解决方案:

我们可以在返回数据之前将代理类序列化成我们需要的实体。

这是一个演示,学生类包含其他实体的导航属性:

            public Student Getstu()
    {
        CodeFirstDBContext codeFirstDBContext = new CodeFirstDBContext();
        Student student =codeFirstDBContext.Student.Find(1);
        var serializer = new DataContractSerializer(typeof(Student), new DataContractSerializerSettings()
        {
            DataContractResolver = new ProxyDataContractResolver()
        });
        using (var stream = new MemoryStream())
        {

            serializer.WriteObject(stream, student);
            stream.Seek(0, SeekOrigin.Begin);
            var stu = (Student)serializer.ReadObject(stream);
            return stu;
        }


    }

这是客户端将调用的方法。

     ServiceReference1.ServiceClient serviceClient = new ServiceReference1.ServiceClient();
        var stu = serviceClient.Getstu();

客户端会调用成功。

更新禁用加载加载也解决了这个问题:

      public class CodeFirstDBContext : DbContext
{
    public CodeFirstDBContext() : base("name=DBConn")
    {
        this.Configuration.ProxyCreationEnabled = false;
        this.Configuration.LazyLoadingEnabled = false;
        Database.SetInitializer(new CreateDatabaseIfNotExists<CodeFirstDBContext>());
    }
 }

【讨论】:

  • 为什么不只是在 EF 中禁用惰性,并避免所有这些代码?
  • 嗯..这可能对我有用......谢谢。不知何故,我觉得 DataContractSerializer 很烂.......我有 2 个选项 1. 将 DTO 对象传递给客户端,2. 改为尝试 XMLSerializer。我目前正在探索选项 1。
  • Ricado 如何禁用延迟加载来解决这个问题?这是一个序列化问题。只是好奇想知道。顺便说一句,这是我完整项目的 git 存储库,以防你想看看 github.com/gauravrajminhas/BookMeProjectDotNetFramework.git
猜你喜欢
  • 1970-01-01
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-10
  • 2010-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多