2013-05-22 3 views
0

Таким образом, я сам предоставляю услугу WCF. Когда я вызываю метод моего GetProject() с помощью клиента я получаю Необработанное CommuncationException с InnerException изМетод WCF, выбрасывающий SerializationException

«Базовое соединение закрыто: Непредвиденная ошибка приема.»

И InnerException этого:

«Невозможно прочитать данные из транспортного соединения:. Существующее соединение было принудительно закрыто удаленным узлом»

Теперь я знаю, что это просто общее сообщение, которое не говорит мне многого. Поэтому я настроил Service трассировку и это то, что я получил:

на System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply (MessageRpc & Amp; RPC) System.Runtime.Serialization.SerializationException: Тип 'System.FormatException' с именем контракта данных «FormatException: http://schemas.datacontract.org/2004/07/System» не ожидается. Подумайте об использовании DataContractResolver или добавьте любые типы, не известные статически в список известных типов - например, с помощью атрибута KnownTypeAttribute или путем добавления их в список известных типов, переданных DataContractSerializer.

Итак, я принял это сообщение и изменил свой код, и теперь я верю, что делаю это правильно. Я следил за несколькими учебниками, но я все еще получаю это исключение в Service Trace.

В моей 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-запроса прерывается сервером (возможно, из-за отключения службы). Для получения более подробной информации см. Журналы сервера . ---> System.Net.WebException: Соединение было закрыто: произошла непредвиденная ошибка при получении. ---> System.IO.IOException: невозможно прочитать данные из транспорта соединение: существующее соединение было принудительно закрыто удаленным хостом. ---> System.Net.Sockets.SocketException: существующее соединение было принудительно закрыто удаленным узлом

на System.Net.Sockets.Socket.Receive (байты [] буфере, Int32 смещения, Int32 размера, SocketFlags SocketFlags)

на System.Net.Sockets.NetworkStream.Read (байт [] буфера, Int32 смещение, размер Int32)

--- Конец внутренней трассировки стека исключений ---

в System.Net.Sockets.NetworkStream.Read (байт [] буфер, смещение Int32, размер Int32)

на System.Net.PooledStream.Read (байт [] буфера, Int32 смещение, размер Int32)

на System.Net.Connection.SyncRead (HttpWebRequest запрос, булева userRetrievedStream, булева probeRead)

--- Конец внутренней трассировки стека исключений ---

на System.Net.HttpWebRequest.GetResponse()

на System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequ estChannel.HttpChannelRequest.WaitForReply (TimeSpan тайм-аут)

--- Конец внутренней трассировки стека исключений ---

сервера трассировки стека:
на System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException (WebException WebException , HttpWebRequest запрос, HttpAbortReason abortReason)

на System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply (TimeSpan тайм-аут)

в System.ServiceModel.Channels.RequestChannel.Request (сообщение Message, TimeSpan таймаут)

в System.ServiceModel.Dispatcher.RequestChannelBinder.Request (Message сообщение, TimeSpan таймаут)

в System.ServiceModel .Channels.ServiceChannel.Call (действие Строка, Логическое односторонняя, операция ProxyOperationRuntime, Object [] модули, Object [] выходы, TimeSpan тайм-аут)

на System.ServiceModel.Channels.ServiceChannelProxy.InvokeService (IMethodCallMessage методCall, ProxyOperationRuntime operation)

в System.ServiceModel.Channels.ServiceChannelProxy.Вызов (IMessage сообщение)

Exception при вызваны повторно [0]:

на System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage (Шеззаде reqMsg, IMessage retMsg)

на System.Runtime. Remoting.Proxies.RealProxy.PrivateInvoke (MessageData & msgData, тип Int32)

на IProjectService.GetQuerytoList (Int32 ID)

на ProjectServiceClient.GetQuerytoList (Int32 ид) в C: \ Users \ drwill \ документы \ Visual Studio 2010 \ Projects \ ProjectBaseWCF \ ProjectBase \ generatedProxy.cs: линия 1065
в ProjectWCFClient.MainForm.openToolStripMenuItem_Click (Object отправителя , EventArgs е) в C: \ Users \ drwill \ документы \ Visual Studio 2010 \ Projects \ ProjectBaseWCF \ ProjectBase \ PBMain.cs: линия 961

на ProjectWCFClient.MainForm.ProjectListBox_DoubleClick (отправителем объекта, EventArgs е) в C: \ Users \ drwill \ documents \ visual studio 2010 \ Projects \ ProjectBaseWCF \ ProjectBase \ PBMain.cs: строка 55

в System.Windows.Forms.Control.OnDoubleClick (EventArgs е)

на System.Windows.Forms.ListBox.WndProc (Сообщение & м)

в System.Windows.Forms.Control.ControlNativeWindow поле .OnMessage (Сообщение & м)

на System.Windows.Forms.Control.ControlNativeWindow.WndProc (Сообщение & м)

на System.Windows.Forms.NativeWindow.Callback (IntPtr HWND, Int3 2 тзда, 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"); 
+0

Проверьте это: http://stackoverflow.com/questions/3167932/c-sharp-wcf-when-is-it-appro-to-use-the-knowntype-attribute –

+0

Сторона примечания: те новые() заявления и конструкторы могут работать не так, как вы ожидаете. –

+0

Прокси-клиент и сервер работают на одном компьютере? – YK1

ответ

2

Okay.Так что это немного поздно, но вот то, что это было:

System.FormatException, который бросал был связан с возникновением int.Parse("0") внутри GetProject(int id) метода, когда я звонил его.

Таким образом, я изменил метод обработки корпуса "0", назвав его более надежным Convert.ToInt32("0").

Я думаю, что урок, извлеченный здесь, заключается в том, что сначала вы должны убедиться, что метод, который вы выполняете, работает. Тогда и только тогда вы должны спросить, не подходит ли DataContractSerializer для сериализации ваших типов.

+0

Я пытался выяснить проблему в течение нескольких часов ... Я выяснил, что в моем случае проблема была перечислением (параметром) не была правильно преобразована в строку. Вы сделали мой день! – chris6523

0

Я не думаю, что вам нужен KnownType. Возможно, это может быть ошибка синтаксического анализа с помощью DateTime. Проверьте культуру на клиентских и серверных машинах.

EDIT: Из дополнительной информации, похоже, что ваш прокси неправильно настроен - по сравнению с конфигурациями привязки на сервере. Повторное создание прокси с помощью Add Service Reference или SvcUtil.exe

+0

Я согласен с первой частью! Я не уверен в бит DateTime, могут быть проблемы с KnownType с DateTimeOffset, хотя: http://msdn.microsoft.com/en-us/library/ms730167.aspx –

+0

@dave - DateTimeOffset не используется в код - возможно, это то, что нужно использовать. Или отправьте дату как UTC. http://stackoverflow.com/questions/9878560/c-sharp-utc-datetime-query-in-wcf-net – YK1

+0

Культура на обеих машинах - 'en-US'. –

0

Try добавить конструктор без параметров для CommercialEntity

+1

Хорошее наблюдение - но, к сожалению, WCF DataContractSerializer не использует конструкторы - http://msdn.microsoft.com/en-us/magazine/cc163569.aspx#S5 – YK1

+0

Я добавил его, но, как подозревал YK1, нет кубиков. –

Смежные вопросы