Почему добавление типизированного набора данных в службу WCF заставляет клиента использовать массивы для коллекций?

#.net #wcf #visual-studio

#.net #wcf #visual-studio

Вопрос:

У меня есть служба WCF и клиент WCF. Служба использует методы, которые возвращают общие списки, а тип ссылочной коллекции службы клиента устанавливается на общий список. Все работает нормально.

Я добавил в службу WCF метод, который возвращает типизированный набор данных. Первый контракт на операцию для возврата набора данных. Обновил ссылку на службу в клиенте, и это все сломало. Все списки были преобразованы в массивы, даже если для типа коллекции задано значение generic list .

Я подумал, что что-то пошло не так, поэтому я удалил ссылку на службу, перезаписал VS, создал ссылку на службу с нуля, и все равно все коллекции были преобразованы в массивы вместо списков.

Я подтвердил, что причиной этого был набор данных, потому что, когда я удалил новый метод из службы WCF и обновил ссылку, все коллекции вернулись к спискам.

Мне нужно использовать набор данных как есть. Как я могу использовать его и оставить остальные списки нетронутыми? Почему типизированный набор данных влияет на тип остальных используемых коллекций? Я использую обновление VS 2013 2 с .NET 4.5.1.

введите описание изображения здесь

Комментарии:

1. Я не уверен, что вы можете передавать подобные наборы данных через службы wcf, но что вы можете сделать, так это вернуть строку, которая будет сериализованным набором данных, и десериализовать ее на другом конце.

2. Конечно, я могу. Это просто класс. WCF уже выполняет сериализацию и десериализацию. Но я мог бы попытаться сериализовать его сам как строку, чтобы WCF не знал, что это набор данных.

3. @MatijaK. Вы можете передавать наборы данных по проводам. codeguru.com/csharp/.net/net_data/article.php/c19561 /…

4. НЕ ВОЗВРАЩАЙТЕ НАБОРЫ ДАННЫХ ИЗ ВЕБ-СЛУЖБ!!!! hanselman.com/blog /…

5. @Tom Я сказал, что мне нужно использовать набор данных как есть. Это устаревшее приложение. Я знаю, что наборы данных не являются оптимальными, и технически ЭТО НЕ ТАК. Однако этот пост посвящен чему-то конкретному. Дело не в том, могу я или нет использовать наборы данных в качестве возвращаемых типов. и, пожалуйста, прекратите использовать все заглавные буквы. Это похоже на крик.

Ответ №1:

Причина этого в том, что при добавлении ссылки на службу через Visual Studio под капотом Visual Studio вызывает svcutil.exe чтобы сгенерировать свой прокси-сервер. Это хорошо, потому что, как показывает ваш снимок экрана, svcutil способен интерпретировать коллекции в открытом определении службы wsdl как List<T> .

Обычно это хорошо работает для простых контрактов.

Теперь, по неясной причине, известной только Microsoft, svcutil имеет довольно сложную интерпретацию XSD, что означает, что для определений служб, которые выходят за рамки этой интерпретации, VS вернется к использованию старого доброго xsd.exe , который, оказывается, НЕ поддерживает коллекции как List<T> .

Обычно вы этого не замечаете, потому что большинство определений служб относительно просты и соответствуют правилам. Однако сброс чего-то вроде объекта .net DataSet в контракт на обслуживание и определение вашего сервиса становится настолько чудовищно сложным, что VS придется использовать xsd.exe чтобы сгенерировать ваш код.

И в этом заключается проблема.

Некоторые вещи, которые вы можете попробовать:

  1. Извлеките XSD из service WSDL и попробуйте вызвать svcutil напрямую: svcutil /o:file.cs /ct:System.Collections.Generic.List schema.xsd (вероятно, не сработает, но я бы попробовал на всякий случай)

  2. Измените сгенерированный код вручную, заменив все массивы списками (ой)

  3. Не добавляйте набор данных .net в определение вашей службы (это мое любимое)

  4. Используйте такой инструмент, как XsdArrayToList — это позволит вам повторно генерировать ваш созданный код.

Комментарии:

1. То, что вы сказали, похоже, не происходит. Я использовал Process Monitor и не смог найти xsd.exe ни svcutil.exe использование при захвате. Затем я переименовал все экземпляры этих исполняемых файлов на компьютере, и VS все еще смог создать ссылку на службу. Возможно, VS 2013 использует api. Список <T> и типизированные наборы данных даже нетипизированные наборы данных являются артефактами .NET, поэтому я ожидал, что в прокси-файле будут оба. Либо оба для поддержки .NET-клиента (в моем случае), либо нет для поддержки non . СЕТЕВЫЕ клиенты. Но поддержка одного, а не другого в WCF не имеет смысла.

2. Я перенес метод service в устаревшую службу веб-службы (asmx). Все должно быть стандартным, чтобы другие разработчики могли работать, ничего не нарушая, и не тратить время на устранение неполадок.

Ответ №2:

Я перенес метод service в устаревшую службу веб-службы (asmx).