常见的WCF异常:连接意外关闭

时间:2008-10-24 00:20:26

标签: wcf exception connection

我有三个项目。一个是WCF服务项目,一个是WPF项目,一个是Microsoft单元测试项目。我使用如下所示的数据对象设置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>

这不是第一次发生这种情况,我猜这是一个配置问题。但每次我通常只是吹走我的服务并把它放回去或创建一个新的服务项目。然后一切都很美妙。如果有人有任何想法,那将是非常棒的。 THX。

**

  

更新:我已添加评论以获取更多信息   我对这个问题的疑难解答。   当答案可用时,如果   答案未发表,我将其添加为   官方的“答案”。

**

12 个答案:

答案 0 :(得分:20)

我找到了答案

好的,不确定是否能回答我自己的问题,但我们走了。由于某种原因,枚举需要使用[EnumMember]属性标记如下:

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

一旦我这样做,我的测试和服务就可以在没有错误发生的情况下被调用。我仍然不确定为什么会显示该特定错误。错误似乎与错误发生的功能原因没有任何关联,但是这个修复肯定能够解决所有问题。

答案 1 :(得分:7)

正如您自己所说,如果您将枚举标记为DataContract,您也必须标记这些项目。

作为替代方案,您可以在枚举之前删除[DataContract],如下所示:

public enum Priority
{    
  Low,    
  Medium,    
  High
}

这也可以,因为在这种情况下,WCF自己处理枚举。如果您将其标记为[DataContract],则必须按照您自己注意的方式标记每个项目。

答案 2 :(得分:6)

我在返回大型有效负载时遇到此错误,结果是DataContractSerialiser停止了中间流,因为它已经达到默认的maxItemsInObjectGraph设置,将我的端点行为添加到了行为中修复了问题

<dataContractSerializer maxItemsInObjectGraph="2147483647" />

答案 3 :(得分:3)

确保不会抛出任何不是FaultException的东西并将其传递回客户端。

答案 4 :(得分:3)

我在使用LINQ和调用Select,Where等时没有立即调用.ToList()或ToArray()时注意到了这一点。迭代器会让你遇到麻烦。它们不是WCF知道如何使用的本机类型,如List,Array等。它们是WhereEnumerable类型的东西。在从NHibernate或Entity Framework发回结果时,请记住这一点。希望这有助于某人。花了我几个小时才弄清楚。

答案 5 :(得分:2)

如果其他人也在这样做,我将linq生成的对象列表返回给sql / dbml文件。我只需要在dbml文件中启用序列化:

http://blogs.msdn.com/b/wriju/archive/2007/11/27/linq-to-sql-enabling-dbml-file-for-wcf.aspx

欢呼声

答案 6 :(得分:2)

在我的情况下,我的数据合同有一个[datamember]属性,没有set方法。我使用WCF跟踪来获得真正的错误。 https://stackoverflow.com/a/4271528/463425。我希望这有助于某人。

答案 7 :(得分:1)

我可能会离开,但它可能是一个安全的事情......我之前已经得到了这个错误,我解决了它...但是我已经好几天试图得到很多不同的错误了

我有一篇基本的示例文章,但我在这里使用net.tcp(安全设置为“无”):Duplex WCF Services Hosted in IIS Using Net.Tcp

此外,你在哪里得到错误...是在“.Close()”行,还是“.GetTasks()。ToString()”行?

您可以检查的另一件事是在端口9999上简单地telnet到localhost,看看该服务是否正在监听完全连接。

答案 8 :(得分: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);

答案 9 :(得分:1)

另一个原因:如果DataContract/DataMember上有Interface个属性而不是具体类型(terrible idea,请不要这样做),并且您正在尝试序列化,则会出现此异常Concrete type

答案 10 :(得分:1)

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

Dim oTable As DataTable = New DataTable 'this wont serialize
Dim oTable As DataTable = New DataTable("MyTable")  'this will serialize

答案 11 :(得分:0)

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

<dataContractSerializer maxItemsInObjectGraph="2147483647" />

这很有用,但它不仅要添加到端点行为,还要添加到服务行为(这是有意义的,因为这是序列化发生的地方)。

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

如果仅添加到端点,我仍然会意外关闭连接错误。