12

我有三个项目。一个是 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>

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

**

更新:我已经添加了评论,以便我对这个问题进行更多的故障排除。当答案可用时,如果答案未发布,我会将其添加为官方“答案”。

**

4

12 回答 12

21

我找到了答案

好的,不确定它是否是 kewl 回答我自己的问题,但我们开始吧。出于某种原因,需要使用 [EnumMember] 属性标记枚举,如下所示:

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

一旦我这样做了,就可以调用我的测试和服务而不会发生错误。我仍然不确定为什么会显示该特定错误。该错误似乎与发生错误的功能原因没有任何关联,但此修复肯定使一切顺利。

于 2008-10-24T17:46:50.900 回答
7

正如您自己所指出的,如果您将枚举标记为 DataContract,那么您也必须标记这些项目。

作为替代方案,您可以像这样在枚举之前删除 [DataContract]:

public enum Priority
{    
  Low,    
  Medium,    
  High
}

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

于 2009-01-07T08:44:59.960 回答
6

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

<dataContractSerializer maxItemsInObjectGraph="2147483647" />
于 2011-10-19T07:17:18.583 回答
3

确保没有任何不是 FaultException 的东西被抛出并传回给客户端。

于 2008-10-24T03:37:25.980 回答
3

我在使用 LINQ 和 Select、Where 等调用时注意到了这一点,而无需立即调用 .ToList() 或 ToArray()。迭代器会给你带来麻烦。它们不是 WCF 知道如何使用的原生类型,如 List、Array 等。它们的类型是 WhereEnumerable 或其他类型。从 NHibernate 或实体框架发回结果时请记住这一点。希望这可以帮助某人。我花了几个小时才弄清楚。

于 2011-08-23T00:16:03.870 回答
2

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

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

干杯

于 2012-04-12T05:13:47.787 回答
2

就我而言,我的数据合约有一个 [datamember] 属性,它没有 set 方法。我使用 WCF 跟踪来获取真正的错误。https://stackoverflow.com/a/4271528/463425。我希望这可以帮助别人。

于 2013-09-06T07:53:01.990 回答
1

我可能会走得很远,但这可能是一个安全问题......我以前遇到过这个错误,我解决了它......但我花了几天时间试图解决很多不同的错误。

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

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

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

于 2008-10-24T02:53:27.033 回答
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);
于 2010-04-07T14:27:37.440 回答
1

另一个原因:如果你有DataContract/DataMember属性Interface而不是具体类型(糟糕的想法,不要这样做)并且你试图序列化Concrete type.

于 2012-09-18T08:54:02.240 回答
1

就我而言,我正在返回一个自定义类对象,其中一个成员是数据表。如果您在数据表上没有名称,则会引发此错误。

Dim oTable As DataTable = New DataTable 'this wont serialize
Dim oTable As DataTable = New DataTable("MyTable")  'this will serialize
于 2012-12-18T15:26:10.010 回答
0

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

<dataContractSerializer maxItemsInObjectGraph="2147483647" />

这行得通,但它不仅必须添加到端点行为中,还必须添加到服务行为中(这是有道理的,因为那是序列化发生的地方)。

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

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

于 2012-03-01T21:11:34.393 回答