3

When I try to invoke to my WCF method using the WCF Test Client, I get the following error message:

Failed to invoke the service. Possible causes: The service is offline or 
inaccessible; the client-side configuration does not match the proxy; the existing
proxy is invalid. Refer to the stack trace for more detail. You can try to recover
starting a new proxy, restoring to default configuration, or refreshing the 
service.

The underlying connection was closed: The connection was closed unexpectedly.

Server stack trace: 
   at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
   at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
   at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at MyApi.GetStuff(String[] stuff)
   at IMyApi.GetStuff(String[] stuff)

Inner Exception:
The underlying connection was closed: The connection was closed unexpectedly.
   at System.Net.HttpWebRequest.GetResponse()
   at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

I have my method under test so I know the exception isn't being thrown from inside the method. I also have an interceptor Interceptor: Attribute, IOperationBehavior, IParameterInspector whose AfterCall method is reporting that the interceptor was reached. It seems pretty clear from the exception message, the unit tests, and the interceptor that the exception is somehow being thrown AFTER the method is invoked, when the service attempts (but fails) to send the response.

I am using Visual Studio's built-in support for WCF. I didn't do anything to put it on IIS. Other methods in the API seem to work just fine - just that one doesn't. What is going wrong?

EDIT: After some debugging, I found that the following code reproduces my problem.

[ServiceContract]
public class TestService
{
    [OperationContract]
    public MyClass DoWork()
    {
        return new MyClass()
        {
            Str = "hello"
        };
    }
}

[DataContract]
public class MyClass
{
    [DataMember]
    public string Str { get; set; }

    [DataMember]
    public string StrPlus
    {
        get { return Str + " again!"; }
    }
}

How come adding StrPlus throws the exception?

S. Dixon
  • 842
  • 1
  • 12
  • 26
  • Use Fiddler to inspect the failing request. Inspect request and response. – usr Jul 24 '14 at 23:19
  • There is no response. When I use SOAP UI it says "Error Getting Response... Target server failed to respond." – S. Dixon Jul 24 '14 at 23:20
  • Replace the body of the service method with nothing. Does the call still fail? – usr Jul 24 '14 at 23:21
  • No. I made the service method body `return null;` and the call returns null, as expected. I did do some weird stuff with the return value; I'm currently trying to reproduce this issue with a smaller example (mines too big for Stack Overflow); my main suspicion was that the return type fails to serialize in WCF. Will report back shortly on that. – S. Dixon Jul 24 '14 at 23:25
  • 1
    Look at it from the bright side and treat this as a lesson learnt in debugging. Attach the debugger to the server and set it to break on all exceptions. Maybe disable "my code only" to see WCF internal exceptions. – usr Jul 24 '14 at 23:29
  • That'll be an interesting exercise! I haven't used much of Visual Studio's debugging much because of all the tests I've been writing! – S. Dixon Jul 24 '14 at 23:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/57955/discussion-between-stephen-and-usr). – S. Dixon Jul 24 '14 at 23:35

1 Answers1

4

It turns out get-only properties are not supported as data members. Still a mystery why the connection was cut. Normally WCF returns an error document.

WCF: Exposing readonly DataMember properties without set? You could add a setter throwing a NotSupportedException.

Community
  • 1
  • 1
usr
  • 168,620
  • 35
  • 240
  • 369
  • Nothing mysterious about it. The exception occurs during serialisation, which normally isn't logged by your logging software. Take a look in you event log, the full details of the error should be over there. – Aron Jul 25 '14 at 01:48
  • @Aron normally, the connection isn't cut though. An error is sent back. It might be a generic error but still an error. – usr Jul 25 '14 at 09:11
  • The connection isn't "cut". The issue is that the `DataContractSerializer` can't be instanciated. No serializer, nothing to send data back with. Hence no HTTP response. Hence the client thinks the connection was cut. Try instantiating a `new DataContractSerialiser(typeof(CantBeSerialized))`, and see what happens. – Aron Jul 25 '14 at 09:14
  • `The connection was closed unexpectedly` the TCP connection was cut without sending a response. Of course his data can't be serialized but a fault or an HTML error page could be generated. No technical reason preventing it.; It is unusual for a Microsoft framework to not report errors and behave erratically. That's why I suspect that there is something going on not yet discovered. – usr Jul 25 '14 at 09:26
  • 1
    Yes. I know the exception very well. Now open up `Control Panel`->`Administrative Tools`->`Event Viewer`->`Windows Logs`->`Application`. There should be an Error. The top one is the IIS unmanged error. The second one should be the ASP.Net error, which is that .net could not instantiate the DataContractSerialiser. No error is sent back over HTTP because there is nothing to serialize the error. – Aron Jul 25 '14 at 09:29
  • @Aron - Good insight. When I looked at the Event Logger, one of the top errors was `A message was not logged. Exception: System.Runtime.Serialization.InvalidDataContractException: No set method for property 'StrPlus' in type 'MyNamespace.MyClass'.` I didn't realize I could use the Event Viewer for debugging before; nice find. – S. Dixon Jul 25 '14 at 15:07