WCF: The underlying connection was closed
В одном из проектов, которым я сейчас занят, появилась странная ошибка - при обращении к одному из методов сервиса WCF, вылетает "The underlying connection was closed: The connection was closed unexpectedly". В самом сервисе необработаных ошибок нет (по крайней мере, ClrDbg их не показывает). После небольшого поиска нашел достаточно интересную причину ошибки:
- Метод, который приводил к ошибке имеет следующую сигнатуру:
DataSet GetObject(long id); - В своей реализации, метод создает типизированный датасет, разный, в зависимости от типа объекта и возвращает его клиенту. Важный момент - формальный результат фунции - DataSet, а фактический - какой-нибудь SuperDataSet.
- Оказываеться, в этом случае что-то ломается в сериализации DataSet-а и в том как этим пользуется WCF, что и приводит к вышеописанному поведению.
Как это чинить:
Простейший способ починить - скопировать содержимое типизированого DataSet-а в нетипизированный, перед возвратом.
[OperationContract]Некрасиво, но работает.
DataSet GetObject(long id) {
SuperDataSet ds = new SuperDataSet();
// заполняем SuperDataSet
....
....
DataSet res = new DataSet();
res.Merge(ds);
return ds;
}
Коментарі
якщо додаю в сервіс контракт новий метод, що повертає датасет, то при генерації клієнтського проксі коду за допомогою svcutil.exe в згенерованому файлі дещо міняється, в тому числі зникає namespace.
Старий клієнтський код перестає збиратись.
Я вирішив цю проблему некрасивим способом, але думаю, що потрібно відмовитись від використання svcutil.exe.
А ви використовуєте svcutil.exe чи клієнт бере длл з серверними інтерфейсами/контрактами і вручну будує конекцію до потрібного сервера/сервіса?
Мені подобається брати DLL з серверними інтерфейсами/контрактами, та деколи обходжусь і без них. Коротше - буває по різному.