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

Adr*_*ron 12 connection wcf exception

我有三个项目.一个是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; }
}
Run Code Online (Sandbox Code Playgroud)

我的合同如下:

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

    [OperationContract]
    void CreateTask(Task taskToCreate);

    [OperationContract]
    void UpdateTask(Task taskToCreate);

    [OperationContract]
    void DeleteTask(Task taskToDelete);
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用此代码在WPF应用程序或单元测试项目中使用该服务时:

var client = new TaskManagementClient();

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

client.Close();
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:"基础连接已关闭:连接意外关闭."

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>
Run Code Online (Sandbox Code Playgroud)

并且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>
Run Code Online (Sandbox Code Playgroud)

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

**

更新:我已添加评论,以便更多地解决此问题.当答案可用时,如果答案未发布,我会将其添加为官方"答案".

**

Adr*_*ron 21

我找到了答案

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

[DataContract]
public enum Priority
{
    [EnumMember]
    Low,
    [EnumMember]
    Medium,
    [EnumMember]
    High
}
Run Code Online (Sandbox Code Playgroud)

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

  • 在有人可以抛出的所有随机例外情况中,这是WCF团队能够提出的最佳选择吗?遇到完全相同的问题,我花了很多时间试图弄明白,并且让它更令人气愤,它在我的测试机器上运行但在移动到服务器时无法正常工作.IIS是邪恶的. (2认同)

Sam*_*Sam 7

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

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

public enum Priority
{    
  Low,    
  Medium,    
  High
}
Run Code Online (Sandbox Code Playgroud)

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


squ*_*uig 6

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

<dataContractSerializer maxItemsInObjectGraph="2147483647" />
Run Code Online (Sandbox Code Playgroud)