简体   繁体   English

WCF 测试客户端错误无法调用服务(通过 WCF 发送实体时)

[英]WCF Test Client Error Failed to invoke the service ( while Sending Entities Through WCF)

I have a Service where all methods work fine except one which returns a list<Module>我有一个服务,除了一个返回list<Module>方法外,所有方法都可以正常工作

My Module Class (An Entity) is as follow我的模块类(一个实体)如下

[DataContract(IsReference = true)] //prevents Infinite loop
[KnownType(typeof(SubModule))]
public class ModuleMst 
{
    public ModuleMst ()
    { }

    [Key]
    [DataMember]
    public int moduleid { get; set; }

    [StringLength(100)]
    [DataMember]
    public string modulename { get; set; }

    [StringLength(1)]
    [DataMember]
    public string status { get; set; }

    [DataMember]
    public string crby { get; set; }

    [DataMember]
    public DateTime crdt { get; set; }

    [DataMember]
    public string modby { get; set; }

    [DataMember]
    public DateTime moddt { get; set; }

    //[DataMember]
    public virtual List<SubModule> SubModules { get; set; }

}

The Exception WcfTestClient shows as异常 WcfTestClient 显示为

An error occurred while receiving the HTTP response to http://localhost:8888/ArchService/. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.

Server stack trace: 
   at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
   at System.ServiceModel.Channels.HttpChannelFactory`1.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 IArchService.GetAllModules()
   at ArchServiceClient.GetAllModules()

Inner Exception:
The underlying connection was closed: An unexpected error occurred on a receive.
   at System.Net.HttpWebRequest.GetResponse()
   at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

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)
   at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)

Inner Exception:
An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)

The Configuration being配置是

  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="LargeSettingsWS" maxBufferPoolSize="524288" maxReceivedMessageSize="6553600">
          <readerQuotas maxDepth="32" maxStringContentLength="100000" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None" />
        </binding>
      </wsHttpBinding>
      <netTcpBinding>
        <binding name="LargeSettingsTcp" maxBufferSize="524288" maxBufferPoolSize="524288" maxReceivedMessageSize="524288">
          <readerQuotas maxDepth="32" maxStringContentLength="100000" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="Transport" >
            <transport clientCredentialType="Windows" />
            <message clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
      <netNamedPipeBinding>
        <binding name="LargeSettingsPipe" maxBufferSize="524288" maxBufferPoolSize="524288" maxReceivedMessageSize="524288">
          <readerQuotas maxDepth="32" maxStringContentLength="100000" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="Transport" />
        </binding>
      </netNamedPipeBinding>
    </bindings>
    <services>
      <service name="AppService.ArchService">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8808/ArchService" />
            <add baseAddress="net.pipe://localhost/ArchService/" />
            <add baseAddress="http://localhost:8888/ArchService/" />
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="LargeSettingsWS" contract="AppService.IArchService">

          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="LargeSettingsTcp" name="netTcpEndPoint" contract="AppService.IArchService" listenUriMode="Explicit">
          <identity>
            <certificateReference storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectDistinguishedName" />
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="NetSvc" binding="netNamedPipeBinding" bindingConfiguration="LargeSettingsPipe" name="netPipeEndPoint" contract="AppService.IArchService" />

        <endpoint address="mex" binding="mexTcpBinding" name="MetadatEndpointTcp" contract="IMetadataExchange" endpointConfiguration="" />
        <endpoint address="mex" binding="mexNamedPipeBinding" name="MetadatEndpointNetPipe" contract="IMetadataExchange" />
        <endpoint address="mex" binding="mexHttpBinding" name="MetadatEndpointHttpDual" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <dataContractSerializer maxItemsInObjectGraph="2147483646" />

          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />

          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

The Exception is not being very helpful.例外不是很有帮助。

Also All of the bindings fail with this particular method.此外,此特定方法的所有绑定均失败。

What did i miss ?我错过了什么 ?

EDIT编辑

It seems like any method that tries to return a List (where T can be any entity )fails with the error An existing connection was forcibly closed by the remote host似乎任何尝试返回列表(其中 T 可以是任何实体)的方法都失败并显示错误An existing connection was forcibly closed by the remote host

EDIT编辑

Client Configuration is as follow客户端配置如下

<bindings>
  <netNamedPipeBinding>
    <binding name="netPipeEndPoint" maxBufferPoolSize="524288" maxReceivedMessageSize="6553600" >
      <readerQuotas maxDepth="32" maxStringContentLength="100000" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="Transport" />
    </binding>
  </netNamedPipeBinding>
  <netTcpBinding>
    <binding name="netTcpEndPoint" maxBufferPoolSize="524288" maxReceivedMessageSize="6553600">
      <readerQuotas maxDepth="32" maxStringContentLength="100000" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="Transport" />
    </binding>
  </netTcpBinding>

  <wsHttpBinding>
    <binding name="WSHttpBinding_IArchService" maxBufferPoolSize="524288" maxReceivedMessageSize="6553600">
      <readerQuotas maxDepth="32" maxStringContentLength="100000" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="None" />
    </binding>
  </wsHttpBinding>
</bindings>




<client>
  <endpoint address="http://localhost:8888/ArchService/" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IArchService" contract="ServiceReference.IArchService" name="WSHttpBinding_IArchService">
    <identity>
      <dns value="localhost" />
    </identity>
  </endpoint>
  <endpoint address="net.tcp://localhost:8808/ArchService" binding="netTcpBinding" bindingConfiguration="netTcpEndPoint" contract="ServiceReference.IArchService" name="netTcpEndPoint">
    <identity>
      <dns value="localhost" />
    </identity>
  </endpoint>
  <endpoint address="net.pipe://localhost/ArchService/NetSvc" binding="netNamedPipeBinding" bindingConfiguration="netPipeEndPoint" contract="ServiceReference.IArchService" name="netPipeEndPoint">
    <identity>
      <userPrincipalName value="SYS1\deb" />
    </identity>
  </endpoint>
</client>

EDIT 3编辑 3

My Other Related Entity Classes are causing the error.我的其他相关实体类导致错误。 I dont know why.我不知道为什么。 Here are they他们在这里

[Table("SubModuleMst", Schema = "setp")]
[DataContract(IsReference = true)] //prevents Infinite loop
[KnownType(typeof(ModuleMst))]
[KnownType(typeof(List<PageMst>))]

public class SubModule
{
    public SubModule()
    { }

    #region SubModule

    [Key]
    [DataMember]
    public int submoduleid { get; set; }
     [DataMember]
    public int moduleid { get; set; }
    [DataMember]
    [StringLength(100)]
    public string submodulename { get; set; }
    [DataMember]
    public int orderno { get; set; }
    [DataMember]
    [StringLength(1)]
    public string status { get; set; }
    [DataMember]
    public string crby { get; set; }
    [DataMember]
    public DateTime crdt { get; set; }
    [DataMember]
    public string modby { get; set; }
    [DataMember]
    public DateTime moddt { get; set; }
    #endregion

    [DataMember]
    public virtual ModuleMst Module { get; set; }
    [DataMember]
    public virtual List<PageMst> Pages { get; set; }
}

[Table("PageMst", Schema = "setp")]
[DataContract(IsReference = true)] //prevents Infinite loop
[KnownType(typeof(SubModule))]
public class PageMst
{
    public PageMst()
    { }

    #region PageMst

    [Key]
    [DataMember]
    public int pageid { get; set; }
    [DataMember]
    [Required]
    [ForeignKey("SubModule")]
    public int submoduleid { get; set; }
    [DataMember]
    [StringLength(1000)]
    [Required]
    public string pagename { get; set; }
    [DataMember]
    [StringLength(1000)]
    public string pageurl { get; set; }
    [DataMember]
    public int orderno { get; set; }
    [DataMember]
    [StringLength(1)]
    public string menuitm { get; set; }
    [DataMember]
    public int rptparentid { get; set; }
    [DataMember]
    [StringLength(1)]
    public string alertflag { get; set; }
    [DataMember]
    [StringLength(1)]
    public string status { get; set; }
    [DataMember]
    public string crby { get; set; }
    [DataMember]
    public DateTime crdt { get; set; }
    [DataMember]
    public string modby { get; set; }
    [DataMember]
    public DateTime moddt { get; set; }
    [DataMember]
    [StringLength(200)]
    public string paramids { get; set; }
    [DataMember]
    [StringLength(500)]
    public string repurl { get; set; }
    #endregion

    [DataMember]
    public virtual SubModule SubModule { get; set; }
}

EDIT 4编辑 4

Now I am confirmed that the error is due to The Proxy created by EF are Not Serializable as such According to this MSDN Article https://msdn.microsoft.com/en-us/library/ee705457(v=vs.100).aspx And Also according to this SO Article现在我确认错误是由于EF 创建的代理不可序列化,因此根据这篇 MSDN 文章https://msdn.microsoft.com/en-us/library/ee705457(v=vs.100)。 aspx并且也根据这个 SO 文章

Since nobody answered my question, I am posting here what i did to make it work in the hope that it will help somebody else like me.由于没有人回答我的问题,我在这里发布了我为使其工作所做的工作,希望它能帮助像我这样的其他人。

It turns out that the POCO proxy type cannot be directly serialized or deserialized by the Windows Communication Foundation (WCF) as per this MSDN Article .事实证明, 根据此 MSDN 文章,Windows Communication Foundation (WCF) 无法直接序列化或反序列化 POCO 代理类型。

This is because EF creates a Wrapper around the POCO for Entity Tracking which is not the same class as the POCO class and hence WCF can not serialize it since it can only serialize known Types.这是因为 EF 在实体跟踪的 POCO 周围创建了一个 Wrapper,它与 POCO 类不是同一个类,因此 WCF 无法序列化它,因为它只能序列化已知类型。

So in order to make entities Serializable through WCF one of the following needs to be done.因此,为了通过WCF使实体可Serializable ,需要执行以下操作之一。

  1. Disable Proxy creation in the DBContext Configuration.DBContext配置中禁用代理创建。 ( See this ) 见这个
  2. Use .AsNoTracking() ( See this SO Post )使用.AsNoTracking()请参阅此 SO 帖子
  3. Use an Attribute to decorate your service methods that return Entities using ProxyDataContractResolver (See above MSDN article for a Walkthrough)使用属性来装饰使用ProxyDataContractResolver返回实体的服务方法(有关演练,请参阅上面的 MSDN 文章)

I used the 3rd approach and my service returns POCO Entities finally.我使用了第三种方法,我的服务最终返回了 POCO 实体。 The code in the walkthrough article is self explanatory so not posting here.演练文章中的代码是不言自明的,因此不在此处发布。

And at last i think DTOs are the best way to go as far as EF is considered.最后,我认为 DTO 是考虑 EF 的最佳方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM