2008-10-24 119 views
12

我有三个项目。一个是WCF服务项目,一个是WPF项目,另一个是微软单元测试项目。我的设置与数据对象的WCF服务项目,看起来像这样:常见的WCF异常:连接意外关闭

[DataContract] 
public enum Priority 
{ 
    Low, 
    Medium, 
    High 
} 

[DataContract] 
public struct TimeInfo 
{ 
    [DataMember] 
    public Int16 EstimatedHours { get; set; } 

    [DataMember] 
    public Int16 ActualHours { get; set; } 

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

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

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

[DataContract] 
public class Task 
{ 
    [DataMember] 
    public string Title { get; set; } 

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

    [DataMember] 
    public Priority Priority { get; set; } 

    [DataMember] 
    public TimeInfo TimeInformation { get; set; } 

    [DataMember] 
    public Decimal Cost { get; set; } 
} 

我的合同是这样的:

[ServiceContract] 
public interface ITaskManagement 
{ 
    [OperationContract] 
    List<Task> GetTasks(); 

    [OperationContract] 
    void CreateTask(Task taskToCreate); 

    [OperationContract] 
    void UpdateTask(Task taskToCreate); 

    [OperationContract] 
    void DeleteTask(Task taskToDelete); 
} 

当我尝试无论是在WPF应用程序或单位使用服务使用此代码测试项目:

var client = new TaskManagementClient(); 

textBox1.Text = client.GetTasks().ToString(); 

client.Close(); 

我收到以下错误:“底层连接已关闭:连接意外关闭。”

为WPF和单元测试项目中的app.config像这样:

<system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
      <binding name="WSHttpBinding_ITaskManagement" closeTimeout="00:01:00" 
       openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
       bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
       maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
       messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" 
       allowCookies="false"> 
       <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
        maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
       <reliableSession ordered="true" inactivityTimeout="00:10:00" 
        enabled="false" /> 
       <security mode="Message"> 
        <transport clientCredentialType="Windows" proxyCredentialType="None" 
         realm="" /> 
        <message clientCredentialType="Windows" negotiateServiceCredential="true" 
         algorithmSuite="Default" establishSecurityContext="true" /> 
       </security> 
      </binding> 
     </wsHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="http://localhost:9999/TaskManagement.svc" 
      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITaskManagement" 
      contract="TaskManagement.ITaskManagement" name="WSHttpBinding_ITaskManagement"> 
      <identity> 
       <dns value="localhost" /> 
      </identity> 
     </endpoint> 
    </client> 
</system.serviceModel> 

和WCF服务的web.config中看起来是这样的:

<system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="InternetBasedWcfServices.TaskManagementBehavior"> 
       <serviceMetadata httpGetEnabled="true" /> 
       <serviceDebug includeExceptionDetailInFaults="false" /> 
      </behavior> 
      <behavior name="InternetBasedWcfServices.ScheduleManagementBehavior"> 
       <serviceMetadata httpGetEnabled="true" /> 
       <serviceDebug includeExceptionDetailInFaults="false" /> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <services> 
     <service behaviorConfiguration="InternetBasedWcfServices.TaskManagementBehavior" 
      name="InternetBasedWcfServices.TaskManagement"> 
      <endpoint address="" binding="wsHttpBinding" contract="InternetBasedWcfServices.ITaskManagement"> 
       <identity> 
        <dns value="localhost" /> 
       </identity> 
      </endpoint> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
     <service behaviorConfiguration="InternetBasedWcfServices.ScheduleManagementBehavior" 
      name="InternetBasedWcfServices.ScheduleManagement"> 
      <endpoint address="" binding="wsHttpBinding" contract="InternetBasedWcfServices.IScheduleManagement"> 
       <identity> 
        <dns value="localhost" /> 
       </identity> 
      </endpoint> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services> 
</system.serviceModel> 

这不是第一次发生这种情况,我猜这是一个配置问题。但每次我通常只是吹走我的服务,并放回或创建一个新的服务项目。那么一切都很好用。如果任何人有任何想法,那就太棒了。谢谢。

**

Updated: I've added comments for more of my troubleshooting on this problem. When an answer is available, if the answer is unpublished, I'll add it as an official "answer".

**

回答

20

我找到了答案

好了,不知道这是否是KEWL回答我的问题,但在这里我们去。出于某种原因需要枚举标有[EnumMember]属性如下:

[DataContract] 
public enum Priority 
{ 
    [EnumMember] 
    Low, 
    [EnumMember] 
    Medium, 
    [EnumMember] 
    High 
} 

一旦我做到了我的测试和服务可以在没有错误发生的调用。我仍然不确定为什么会显示特定的错误。这个错误似乎并不符合与错误发生的功能原因的任何关联,但是这个修复绝对平滑了一切。

+2

在有人可能抛出的所有随机例外中,这是WCF团队能够提出的最佳选择? 跑到完全相同的问题,我花了很长时间试图弄清楚,并使它更加生气它在我的测试机器上工作,但移动到服务器时将无法正常工作。 IIS是邪恶的。 – thaBadDawg 2009-07-13 16:58:48

+0

回答你自己的问题都很好:http://meta.stackexchange.com/questions/17463/can-i-answer-my-own-questions-even-those-where-i-knew-the-answer-before - 问 - 我认为应该有一个徽章! :) – russau 2012-03-26 23:08:06

+0

我虽然这个答案有点随意。但完全解决了我的情况! – 2014-05-12 13:24:14

1

我可能是遥远,但它可能是一个安全的事情......我以前得到的错误,我解决它...但是我花了好几天的时间试图获得很多不同的错误。

我有一个样品的文章做一些基本的东西,但我使用的net.tcp(安全设置为“无”)在这里:Duplex WCF Services Hosted in IIS Using Net.Tcp

而且,你在哪里得到的错误...是在“.Close()”行或“.GetTasks()。ToString()”行?

,您可以检查的另一件事是简单地远程登录到本地主机端口9999,看服务是否监听进来的完全连接。

3

确保没有什么是不是的FaultException得到投掷并传回给客户端。

7

正如你提到的,如果你标记枚举为DataContract,你必须标记的项目,太。

作为替代你可以只取出[DataContract]之前,你的枚举是这样的:

public enum Priority 
{  
    Low,  
    Medium,  
    High 
} 

这会工作,也因为在这种情况下WCF自己处理枚举。如果您将其标记为[DataContract],则必须标记您注意到的每件商品。

1

有时候这个错误可能是非常具有误导性的。常见的WCF异常:当文化设置不正确或字符串格式不正确时,可能会发生意外关闭连接。

继失败:

new DateTime(adate.Year, adate.Month, firstday).ToString("d", cultureInfo); 

,而这个工程:

CultureInfo culture = new CultureInfo(this.aculture.Name);    
Convert.ToString(new DateTime(adate.Year, adate.Month, firstday), culture); 
3

我使用LINQ时注意到这一点,并呼吁喜欢选择在哪里,等不来.ToList立即调用( )或ToArray()。迭代器会让你陷入困境。它们不是WCF知道如何像List,Array等一样工作的本地类型,它们是WhereEnumerable类型的东西。在从NHibernate或Entity Framework发回结果时请记住这一点。希望这可以帮助某人。花了我几个小时弄清楚。

6

返回一个大的载荷,当我得到这个错误,它竟然是DataContractSerialiser停止中游,因为它击中了默认maxItemsInObjectGraph设置,添加folloing到我的终点水煤浆固定的问题

<dataContractSerializer maxItemsInObjectGraph="2147483647" /> 
0

此线程上的某个人发布说,将此元素添加到端点行为可解决此问题。

<dataContractSerializer maxItemsInObjectGraph="2147483647" /> 

这工作,但它必须增加不仅对端点行为,而是服务行为太(这是有道理的,因为这是序列化将发生)。

如果它被添加到服务中,我只有这个错误“在对象图中可以序列化或反序列化的项的最大数目是'65536'。更改对象图或增加MaxItemsInObjectGraph配额。

如果添加到端点只有我仍然有连接意外关闭错误。

1

另一个原因:此异常出现,如果你有一个Interface,而不是一个具体类型(terrible ideaDataContract/DataMember属性,不要”不要这样做),并且您试图序列化Concrete type

1

在我的情况下,我正在返回一个自定义类对象,其中一个成员是数据表。如果你没有在数据表上的名字,它会抛出这个错误。

Dim oTable As DataTable = New DataTable 'this wont serialize 
Dim oTable As DataTable = New DataTable("MyTable") 'this will serialize 
相关问题