Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
895
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
906
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4351
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Возвращение DataTables в WCF/.NET
У меня есть сервис WCF, из которого я хочу вернуть DataTable. Я знаю, что это часто очень обсуждаемая тема, насколько возвращение DataTables является хорошей практикой. Давайте на минуту отложим это в сторону.
Когда я создаю DataTable с нуля, как показано ниже, нет никаких проблем вообще. Таблица создается, заполняется и возвращается клиенту, и все хорошо:
[DataContract]
public DataTable GetTbl()
{
DataTable tbl = new DataTable("testTbl");
for(int i=0;i<100;i++)
{
tbl.Columns.Add(i);
tbl.Rows.Add(new string[]{"testValue"});
}
return tbl;
}
Однако, как только я выхожу и нажимаю на базу данных для создания таблицы, как показано ниже, я получаю CommunicationException "The underlying connection was closed: The connection was closed unexpectedly."
[DataContract]
public DataTable GetTbl()
{
DataTable tbl = new DataTable("testTbl");
//Populate table with SQL query
return tbl;
}
Таблица заполняется правильно на стороне сервера. Он значительно меньше, чем тестовая таблица, которую я прокрутил и вернул, а запрос маленький и быстрый - здесь нет проблем с таймаутами или большой передачей данных. Используются те же самые точные функции и DataContracts/ServiceContracts/BehaviorContracts.
Почему способ заполнения таблицы имеет какое-либо отношение к успешному возвращению таблицы?
Для всех, у кого есть подобные проблемы, я решил свою проблему. Это было в несколько раз больше.
- Как предположил Даррен, и Пол сделал резервную копию, свойства Max..Size в конфигурации необходимо было увеличить. Утилита SvcTraceViewer помогла определить это, но она по-прежнему не всегда дает наиболее полезные сообщения об ошибках.
- Кроме того, когда Ссылка на службу обновляется на стороне клиента, конфигурация иногда не обновляется должным образом (например Изменение значений конфигурации на сервере не всегда будет корректно обновляться на клиенте. Я должен был войти и изменить свойства Max..Size несколько раз как на стороне клиента, так и на стороне сервера в ходе моей отладки)
Для того чтобы DataTable можно было сериализовать, ему нужно дать имя. Конструктор по умолчанию не дает таблице имя, поэтому:
return new DataTable();не будет сериализуемым, в то время как:
return new DataTable("someName");назовет таблицу тем, что передается в качестве параметра.
Обратите внимание, что таблице можно дать имя в любое время, присвоив строку свойству
TableNameобъекта DataTable.var table = new DataTable(); table.TableName = "someName";
Надеюсь, это кому-нибудь поможет.
Лучший способ диагностировать такого рода ошибки WCF (те, которые действительно мало что вам говорят) - это включить трассировку. В свой файл web.config добавьте следующее:
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information"
propagateActivity="true">
<listeners>
<add name="ServiceModelTraceListener"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
initializeData="wcf-traces.svclog"/>
</listeners>
</source>
</sources>
</system.diagnostics>
Затем вы можете открыть полученный файл в утилите SvcTraceViewer.exe, которая поставляется в .NET Framework SDK (или с Visual Studio). На моей машине его можно найти по адресу %PROGRAMFILES%\Microsoft SDKs\Windows\v6.0A\Bin\SvcTraceViewer.exe.
Просто найдите сообщение об ошибке (выделенное жирным красным цветом), и оно расскажет вам конкретно, в чем ваша проблема.
Нужный атрибут-OperationContract (on interface) / поведение операции (on method):
[ServiceContract]
public interface ITableProvider
{
[OperationContract]
DataTable GetTbl();
}
[OperationBehavior]
public DataTable GetTbl(){
DataTable tbl = new DataTable("testTbl");
//Populate table with SQL query
return tbl;
}
Кроме того, в г... Я думаю, что конфигурация службы... вы хотите указать, что ошибки могут быть отправлены. Вы можете столкнуться с ошибкой, которая является чем-то вроде размера сообщения до большого и т. д. Вы можете исправить это, обманув читателя квотами и так далее.
По умолчанию wsHttpBinding имеет квоту на получение размера как 65 KB,, так что если в сериализованной таблице данных XML больше, то это вызовет ошибку (и я 95% уверен, что таблица данных больше, чем 65 KB с данными в ней).
Вы можете изменить настройки для квот чтения и так далее в web.config / app.config или установить их на экземпляре привязки в коде. Но да, это, вероятно, и есть ваша проблема, если вы не изменили его по умолчанию.
WSHttpBindingBase членов -посмотрите на свойство ReaderQuotas, а также на свойство MaxReceivedMessageSize.
Существует 3 причины для неудачного типа возврата как datatable в WCF службах
Вы должны указать имя таблицы данных как:
MyTable=new DataTable("tableName");При добавлении ссылки на стороне клиента службы WCF выберите многоразовый dll
system.dataУкажите атрибут для переменной-члена
datatable, например[DataMember] public DataTable MyTable{ get; set; }
Я думаю, что Даррен, скорее всего, прав - значения по умолчанию, предоставленные для WCF, смехотворно малы, и если вы столкнетесь с ними, вы получите ошибки, которые будет трудно отследить. Они появляются, как только вы пытаетесь сделать что-то, выходящее за рамки простого тестового случая. Я потратил больше времени, чем мне хотелось бы признать, на отладку проблем, которые оказались связаны с различными настройками конфигурации (размера) как на клиенте, так и на сервере. Я думаю, что в конечном итоге изменил почти все из них, экс. MaxBufferPoolSize, MaxBufferSize, MaxConnections, MaxReceivedMessageSize, и т. д.
Сказав это, утилита SvcTraceViewer также упомянута отлично. Я действительно столкнулся с несколькими случаями, когда это было не так полезно, как мне бы хотелось, но в целом это хороший инструмент для анализа потока сообщений и ошибок.