我有一个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"底层连接已关闭:连接意外关闭."
[DataContract] public DataTable GetTbl() { DataTable tbl = new DataTable("testTbl"); //Populate table with SQL query return tbl; }
该表正在服务器端正确填充.它比我循环并返回的测试表要小得多,并且查询小而快 - 这里没有超时或大数据传输的问题.正在使用相同的功能和DataContracts/ServiceContracts/BehaviorContracts.
为什么填充表的方式对表成功返回有什么影响?
对于有类似问题的人,我已经解决了我的问题.这是几倍.
正如Darren建议并且Paul支持的那样,配置中的Max..Size属性需要扩大.SvcTraceViewer实用程序帮助确定了这一点,但它仍然不总是提供最有用的错误消息.
此外,当客户端更新服务引用时,配置有时也无法正确更新(例如,更改服务器上的配置值并不总是在客户端上正确更新.我必须进入并更改Max ..在我的调试过程中,在客户端和服务器端多次调整大小属性)
要使DataTable可序列化,需要为其指定名称.默认构造函数不为表提供名称,因此:
return new DataTable();
不可序列化,而:
return new DataTable("someName");
将表格命名为参数传递的任何内容.
请注意,通过将字符串分配给TableName
DataTable 的属性,可以随时为表指定名称.
var table = new DataTable(); table.TableName = "someName";
希望这会对某人有所帮助.
诊断这些类型的WCF错误(那些真的没有告诉你的错误)的最好方法是启用跟踪.在web.config文件中,添加以下内容:
然后,您可以在.NET Framework SDK(或Visual Studio)中的SvcTraceViewer.exe实用程序中打开生成的文件.在我的机器上,它可以在%PROGRAMFILES%\ Microsoft SDKs\Windows\v6.0A\Bin\SvcTraceViewer.exe中找到.
只需查找错误消息(以粗体显示红色),这将告诉您具体的问题.
除了为所有绑定属性设置最大值之外.
确保从webservice传递/返回的每个表都必须具有表名,这意味着该table.tablename
属性不应为空.
我将Datable添加到数据集并返回表格,如此...
DataTable result = new DataTable("result"); //linq to populate the table Dataset ds = new DataSet(); ds.Tables.Add(result); return ds.Tables[0];
希望能帮助到你 :)