Introduction

今やレガシーな子扱いになってしまった WCF (参考 .NET 5 に含まれない機能)。

とはいっても WCF を使っているプロダクトはまだあるわけで、開発している最中に遭遇したのが掲題のエラー。
現象として

  • サーバー側では、例外を投げることもなく、ServiceContract を実装したサービスの return も問題なく通る
    • ただし、これは例外設定で特定の例外を無視していたため、実際には return を抜けた際に、例外で停止してた (アタッチしていた時のみ)
  • 他のサービスメソッドはクライアントから問題なく呼び出せるのに、あるサービスメソッドだけ掲題のエラー
  • 「サービスの参照」は実行しており、I/F に齟齬はない
  • タイムアウトするようなデータ量でもない

なぁぜ?

How to resolve?

結論から言えば、サービス側が返すデータが例外を投げていたのが原因。

通常、データをクライアントに返す際は、そのデータはシリアル化可能であることが必須である。
例えば、下記のような感じ。

1
2
3
4
5
6
7
8
9
10
11
12
13
[DataContract]
[Serializable]
public sealed class Greeting
{

[DataMember]
public string Message
{
get;
set;
}

}

この例は非常にシンプルだったのだが、問題のデータはちょっと酷かった。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[DataContract]
[Serializable]
public sealed class Greeting
{

private string _Message;

[DataMember]
public string Message
{
get => throw new Exception();
set => this._Message = value;
}

}

これは極端な例だが、シリアル化対象のメンバーが例外を投げてしまうような構造をしていたのである。

なので、対処は簡単だったのだが…
自宅で検証している際に、エラーの内容が微妙に違うことに気づいた。
会社で遭遇したのは UWP のプログラムで、WCF のサービスを呼び出していた。
自宅での検証は UWP なんて面倒なので、.NET Framework のコンソールアプリで検証した。
結局、会社で遭遇結果と違ったので、UWP のコンソールアプリを作った。

サービス側は .NET Framework で作成し、UWP も .NET Framework のクライアント双方が同じサービスに接続したとする。

.NET Framework のコンソールアプリ

1
2
3
4
5
6
2024-04-27 21:24:19.9368 [ERROR] Error
Message: http://localhost:5001/ に対する HTTP 応答の受信中にエラーが発生しました。この原因としては、サービス エンドポイント バインドが HTTP プロトコルを使用していないことが考えられます。また別の原因として、HTTP
要求コンテキストがサーバーによって中止された可能性もあります (サーバーがシャットダウンした場合など)。詳細についてはサーバー ログを参照してください。, HResult: 0x80131501
Message: 接続が切断されました: 受信時に予期しないエラーが発生しました。, HResult: 0x80131509
Message: 転送接続からデータを読み取れません: 既存の接続はリモート ホストに強制的に切断されました。。, HResult: 0x80131620
Message: 既存の接続はリモート ホストに強制的に切断されました。, HResult: 0x80004005

.UWP のコンソールアプリ

1
2
3
4
5
6
7
2024-04-27 22:10:50.3144 [ERROR] Error
Message: An error occurred while receiving the HTTP response to http://localhost:5001/. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details., HResult: 0x80131500
Message: An error occurred while sending the request., HResult: 0x80072EFF
Message: このエラー コードに関連付けられたテキストが見つかりませんでした。

サーバーとの接続がリセットされました。
, HResult: 0x80072EFF

例外発生時の InnerException を再帰で調べ MessageHResult のプロパティをログに出したが、見事に内容が違う。
特に会社で調査していた時は、An error occurred while sending the request. の表示惑わされ、クライアントの問題かと思い、無駄に時間を過ごしてしまった。