【问题标题】:WCF Service Does Not Send HTTP Response, even though method gets invokedWCF 服务不发送 HTTP 响应,即使方法被调用
【发布时间】:2014-07-24 23:01:21
【问题描述】:

当我尝试使用 WCF 测试客户端调用我的 WCF 方法时,我收到以下错误消息:

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)

我正在测试我的方法,所以我知道异常不是从方法内部抛出的。我还有一个拦截器Interceptor: Attribute, IOperationBehavior, IParameterInspector,其AfterCall 方法报告已到达拦截器。从异常消息、单元测试和拦截器中可以清楚地看出,在调用方法之后,当服务尝试(但失败)发送响应时,以某种方式抛出了异常。

我正在使用 Visual Studio 对 WCF 的内置支持。我没有做任何事情把它放在 IIS 上。 API 中的其他方法似乎工作得很好——只是那个方法不行。出了什么问题?

编辑:经过一些调试,我发现以下代码重现了我的问题。

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

添加 StrPlus 怎么会抛出异常?

【问题讨论】:

  • 使用 Fiddler 检查失败的请求。检查请求和响应。
  • 没有响应。当我使用 SOAP UI 时,它显示“获取响应时出错...目标服务器无法响应。”
  • 将服务方法的主体替换为空。通话还是失败吗?
  • 没有。我创建了服务方法主体return null;,调用返回null,正如预期的那样。我确实对返回值做了一些奇怪的事情;我目前正在尝试用一个较小的例子来重现这个问题(地雷对于 Stack Overflow 来说太大了);我的主要怀疑是返回类型无法在 WCF 中序列化。很快就会报告。
  • 从光明的一面看它,并将其视为调试中的经验教训。将调试器附加到服务器并将其设置为在所有异常时中断。也许禁用“仅我的代码”以查看 WCF 内部异常。

标签: c# wcf


【解决方案1】:

事实证明,仅获取属性不支持作为数据成员。为什么连接被切断仍然是个谜。通常 WCF 会返回一个错误文档。

WCF: Exposing readonly DataMember properties without set? 你可以添加一个 setter 来抛出一个NotSupportedException

【讨论】:

  • 没什么神秘的。序列化期间发生异常,通常不会由您的日志记录软件记录。看看你的事件日志,错误的完整细节应该在那里。
  • @Aron 通常,连接没有被切断。一个错误被发回。这可能是一个一般性错误,但仍然是一个错误。
  • 连接没有被“切断”。问题是 DataContractSerializer 无法实例化。没有序列化器,没有什么可以发回数据的。因此没有 HTTP 响应。因此客户认为连接被切断。尝试实例化 new DataContractSerialiser(typeof(CantBeSerialized)),看看会发生什么。
  • The connection was closed unexpectedly TCP 连接被切断而没有发送响应。当然他的数据不能被序列化,但是会产生一个错误或者一个 HTML 错误页面。没有技术原因阻止它。 Microsoft 框架不报告错误并且行为不正常是不寻常的。这就是为什么我怀疑有些事情尚未被发现。
  • 是的。我非常了解这个例外。现在打开Control Panel->Administrative Tools->Event Viewer->Windows Logs->Application。应该有一个错误。最上面的一个是 IIS unmanged 错误。第二个应该是 ASP.Net 错误,即 .net 无法实例化 DataContractSerialiser。没有错误通过 HTTP 发回,因为没有任何东西可以序列化错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
  • 1970-01-01
相关资源
最近更新 更多