views:

5854

answers:

6

I have three projects. One is a WCF Services Project, one is a WPF Project, and one is a Microsoft Unit Testing Project. I setup the WCF Services project with a data object that looks like this:

[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; }
}

My contract looks like this:

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

    [OperationContract]
    void CreateTask(Task taskToCreate);

    [OperationContract]
    void UpdateTask(Task taskToCreate);

    [OperationContract]
    void DeleteTask(Task taskToDelete);
}

When I try to use the service in either the WPF Application or the Unit Test Project with this code:

var client = new TaskManagementClient();

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

client.Close();

I get the following error: "The underlying connection was closed: The connection was closed unexpectedly."

The app.config for the WPF and Unit Test Projects look like this:

<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>

and the web.config of the WCF Service looks like this:

    <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>

This is not the first time this has happened, and I'm guessing it is a configuration issue. But each time I've usually just blown away my service and put it back or created a new service project. Then everything works wonderfully. If anyone has any ideas, that would be awesome. Thx.

**

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".

**

+1  A: 

I could be way off, but it might be a security thing... I've gotten that error before, and I solved it... but I was up for days trying to get a lot of different bugs worked out.

I have a sample article doing something basic, but I'm using net.tcp (with security set to "None") here: Duplex WCF Services Hosted in IIS Using Net.Tcp

Also, where are you getting the error... is it on the ".Close()" line, or the ".GetTasks().ToString()" line?

Another thing you can check is to simply telnet to localhost on port 9999 to see if the service is listening for incomming connections altogether.

Timothy Khouri
+2  A: 

Make sure that nothing that isn't a FaultException gets thrown and passed back to the client.

jezell
+3  A: 

I Found the Answer

Ok, not sure if it is kewl answering my own question, but here we go. For some reason the enumeration needed to be marked with the [EnumMember] Attributes as below:

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

Once I did that my tests and services could be called without the error occurring. I'm still not sure why that specific error was displayed. The error doesn't seem to align in any correlation with the functional reason the error occurred, but this fix definitely smoothed everything out.

Adron
Of all the random exceptions somebody could throw, this is the BEST that the WCF team could come up with?Ran into the exact same problem, and I spent forever trying to figure out, and to make it even more infuriating it worked on my test machine but wouldn't work properly when moved to the server. IIS is evil.
thaBadDawg
A: 

As you yourself noted, if you mark the enum as DataContract, you'll have to mark the items, too.

As an alternative you could just remove the [DataContract] before your enum like this:

public enum Priority
{    
  Low,    
  Medium,    
  High
}

This would work, too, because in this case WCF handles the enum by itself. If you mark it as [DataContract] you have to mark every item as you noticed yourself.

Sam
A: 

Refer to http://developergeeks.com/article/12/wcf-error-the-underlying-connection-was-closed for more info on this error.

A: 

Sometimes this error could be very misleading. Common WCF Exception : Connection Unexpectedly Closed can be occurred when the culture is not set correctly or in string formating as well.

Following fails:

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

while this works:

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

Rohini