WCF方法抛出SerializationException

时间:2013-05-22 17:43:06

标签: c# wcf exception serialization

所以我自己托管WCF服务。当我通过客户端调用我的GetProject()方法时,我得到一个Unhandled CommuncationException,其InnerException为

  

"底层连接已关闭:发生意外错误   收到。"

那个InnerException:

  

"无法从传输连接读取数据:远程主机强行关闭现有连接。"

现在我知道这只是一个通用的信息,并没有告诉我多少。所以我配置了一个服务跟踪,这就是我得到的:

  

at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply(MessageRpc& amp; rpc)System.Runtime.Serialization.SerializationException:Type' System.FormatException'使用数据合同名称' FormatException:http://schemas.datacontract.org/2004/07/System'不是预期的。考虑使用DataContractResolver或将任何静态未知的类型添加到已知类型列表中 - 例如,使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。

所以我接受了这条消息并修改了我的代码,我相信我现在正确地做到了这一点。我已经遵循了几个教程,但我仍然在服务跟踪中得到这个例外。

在我ServiceContract我有以下内容:

[OperationContract]
Project GetProject(int id);

编辑已移除KnownTypeAttribute使用。在此处注释以反映更改。

这是我对Project类及其使用的类的实现:

    [DataContract]
    //[KnownType(typeof(Contact))]
    //[KnownType(typeof(ProjectDetails))]
    //[KnownType(typeof(CommercialEntity))]
    public class Project
    {
        [DataMember]
        public ProjectDetails details = new ProjectDetails();
        [DataMember]
        public List<Contact> contacts = new List<Contact>();
        [DataMember]
        public List<CommercialEntity> POs = new List<CommercialEntity>();
        [DataMember]
        public List<CommercialEntity> invoices = new List<CommercialEntity>();
        [DataMember]
        public List<CommercialEntity> quotes = new List<CommercialEntity>();
        [DataMember]
        public List<CommercialEntity> CRs = new List<CommercialEntity>();
    }

    [DataContract]
    public class ProjectDetails 
    {
        [DataMember]
        public int projectId { get; set; }
        [DataMember]
        public string name { get; set; }
        [DataMember]
        public int calYearId { get; set; }
        [DataMember]
        public string projectState { get; set; }
        [DataMember]
        public string reportTitle { get; set; }
        [DataMember]
        public int plantId { get; set; }
        [DataMember]
        public string holdNumber { get; set; }
        [DataMember]
        public string holdDescription { get; set; }
        [DataMember]
        public string remarks { get; set; }
        [DataMember]
        public string adminComments {get; set; }
        [DataMember]
        public int companyId { get; set; }
        [DataMember]
        public int customerId { get; set; }
        [DataMember]
        public string folderNumber { get;  set; }
        [DataMember]
        public int invoicedInFull { get; set; }
        [DataMember]
        public int approved { get; set; }
        }
    }

    [DataContract]
    public class CommercialEntity
    {
        [DataMember]
        public string number { get; set; }
        [DataMember]
        public DateTime date { get; set; }
        [DataMember]
        public string comments { get; set; }

        public CommercialEntity(string setNumber, DateTime setDate, string setComments)
        {
            number = setNumber;
            date = setDate;
            comments = setComments;
        }
    }

    [DataContract]
    public class Contact
    {
        [DataMember]
        public string firstName { get; set; }
        [DataMember]
        public string lastName { get; set; }
        [DataMember]
        public string emailAddress { get; set; }
        [DataMember]
        public string phoneNumber { get; set; }
        [DataMember]
        public int alert { get; set; }
        [DataMember]
        public int projectLead { get; set; }
        [DataMember]
        public int mainContact { get; set; }

        public Contact(string first, string last, string email, string phone, int alrt, int projLead, int mainCntct)
        {
            firstName = first;
            lastName = last;
            emailAddress = email;
            phoneNumber = phone;
            alert = alrt;
            projectLead = projLead;
            mainContact = mainCntct;
        }

        public Contact() { }
    }

我理解的漏洞在哪里?

以下是我在运行客户端时看到的内容:

  

有关调用实时的详细信息,请参阅此消息的结尾   (JIT)调试而不是此对话框。

     

** * ** 异常文字 ** * ****

     

System.ServiceModel.CommunicationException:发生错误   接收HTTP响应   myInternalIP:MyPort上/ ProjectService / ProjectService。这可能是   由于服务端点绑定不使用HTTP协议。这个   也可能是由于HTTP请求上下文被中止   服务器(可能是由于服务关闭)。查看服务器日志   更多细节。 ---&GT; System.Net.WebException:底层   连接已关闭:接收时发生意外错误。 ---&GT;   System.IO.IOException:无法从传输中读取数据   连接:远程强制关闭现有连接   主办。 ---&GT; System.Net.Sockets.SocketException:现有连接   被远程主机强行关闭

     

在System.Net.Sockets.Socket.Receive(Byte []缓冲区,Int32偏移量,Int32   size,SocketFlags socketFlags)

     

在System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,   Int32尺寸)

     

---内部异常堆栈跟踪结束---

     

在System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,   Int32尺寸)

     

在System.Net.PooledStream.Read(Byte []缓冲区,Int32偏移量,Int32大小)

     

在System.Net.Connection.SyncRead(HttpWebRequest请求,布尔值   userRetrievedStream,Boolean probeRead)

     

---内部异常堆栈跟踪结束---

     

在System.Net.HttpWebRequest.GetResponse()

     

at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan)   超时)

     

---内部异常堆栈跟踪结束---

     

服务器堆栈跟踪:
  at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException)   webException,HttpWebRequest请求,HttpAbortReason abortReason)

     

at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan)   超时)

     

在System.ServiceModel.Channels.RequestChannel.Request(消息消息,   TimeSpan超时)

     

at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message   消息,TimeSpan超时)

     

在System.ServiceModel.Channels.ServiceChannel.Call(String action,   Boolean oneway,ProxyOperationRuntime操作,Object [] ins,   对象[]出局,TimeSpan超时)

     

在System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage)   methodCall,ProxyOperationRuntime operation)

     

在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage   消息)

     

在[0]处重新抛出异常:

     

在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage)   reqMsg,IMessage retMsg)

     

在System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp;   msgData,Int32类型)

     

在IProjectService.GetQuerytoList(Int32 id)

     

在ProjectServiceClient.GetQuerytoList(Int32 id)中   C:\ Users \ drwill \ documents \ visual studio   2010 \ Projects \ ProjectBaseWCF \ ProjectBase \ generatedProxy.cs:第1065行   在ProjectWCFClient.MainForm.openToolStripMenuItem_Click(对象   发件人,EventArgs e)在C:\ Users \ drwill \ documents \ visual studio中   2010 \ Projects \ ProjectBaseWCF \ ProjectBase \ PBMain.cs:第961行

     

在ProjectWCFClient.MainForm.ProjectListBox_DoubleClick(对象发送者,   EventArgs e)在C:\ Users \ drwill \ documents \ visual studio中   2010 \ Projects \ ProjectBaseWCF \ ProjectBase \ PBMain.cs:第55行

     

在System.Windows.Forms.Control.OnDoubleClick(EventArgs e)

     

在System.Windows.Forms.ListBox.WndProc(Message&amp; m)

     

在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m)

     

在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp;   m)

     

在System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd,Int32)   msg,IntPtr wparam,IntPtr lparam)

这是我的客户端配置:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IProjectService" maxReceivedMessageSize="500000000" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://192.168.0.99:9000/ProjectService/ProjectService"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IProjectService"
                contract="IProjectService" name="BasicHttpBinding_IProjectService" />
        </client>
    </system.serviceModel>
</configuration>

这是我的服务配置:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true"/>
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="ProjectBaseWCFServiceLib.Service1Behavior" name="ProjectBaseWCFServiceLib.ProjectService">
        <endpoint address="" binding="basicHttpBinding" contract="ProjectBaseWCFServiceLib.IProjectService">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/ProjectBaseWCFServiceLib/Service1/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ProjectBaseWCFServiceLib.Service1Behavior">
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
          <serviceDebug includeExceptionDetailInFaults="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

此外,我以编程方式配置我的控制台应用程序主机:

     BasicHttpBinding binding = new BasicHttpBinding();
     binding.OpenTimeout = new TimeSpan(0, 10, 0);
     binding.CloseTimeout = new TimeSpan(0, 10, 0);
     binding.SendTimeout = new TimeSpan(0, 10, 0);
     binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
     binding.MaxReceivedMessageSize = 500000000;
     binding.MaxBufferSize = 500000000;
     binding.MaxBufferPoolSize = 500000000;

     selfHost.AddServiceEndpoint(typeof(IProjectService), binding, "ProjectService");

3 个答案:

答案 0 :(得分:3)

好。所以这有点晚了,但这就是它:

正在抛出的System.FormatException是由于我在调用它时int.Parse("0")方法中出现了GetProject(int id)

所以我通过调用更健壮的"0"来改变方法来处理Convert.ToInt32("0")案例。

我认为从这里学到的教训是,您应首先确保您正在执行的方法有效。然后,只有在那时你才开始询问DataContractSerializer是否不足以序列化你的类型。

答案 1 :(得分:0)

我认为你不需要KnownType - 可能有可能用DateTime解析错误。检查客户端和服务器计算机上的文化。

编辑:从提供的进一步信息来看,您的代理配置错误 - 与服务器上的绑定配置相比。使用“添加服务引用”或“SvcUtil.exe”重新创建代理

答案 2 :(得分:0)

尝试为CommercialEntity

添加无参数构造函数