在WCF/.NET中返回DataTable

gor*_*ric 50 .net c# datatable wcf web-services

我有一个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;
}
Run Code Online (Sandbox Code Playgroud)

但是,只要我出去打开数据库来创建表,如下所示,我得到一个CommunicationException"底层连接已关闭:连接意外关闭."

[DataContract]
public DataTable GetTbl()
{
    DataTable tbl = new DataTable("testTbl");
    //Populate table with SQL query

    return tbl;
}
Run Code Online (Sandbox Code Playgroud)

该表正在服务器端正确填充.它比我循环并返回的测试表要小得多,并且查询小而快 - 这里没有超时或大数据传输的问题.正在使用相同的功能和DataContracts/ServiceContracts/BehaviorContracts.

为什么填充表的方式对表成功返回有什么影响?

gor*_*ric 82

对于有类似问题的人,我已经解决了我的问题.这是几倍.

  • 正如Darren建议并且Paul支持的那样,配置中的Max..Size属性需要扩大.SvcTraceViewer实用程序帮助确定了这一点,但它仍然不总是提供最有用的错误消息.
  • 此外,当客户端更新服务引用时,配置有时也无法正确更新(例如,更改服务器上的配置值并不总是在客户端上正确更新.我必须进入并更改Max ..在我的调试过程中,在客户端和服务器端多次调整大小属性)
  • 要使DataTable可序列化,需要为其指定名称.默认构造函数不为表提供名称,因此:

    return new DataTable();
    
    Run Code Online (Sandbox Code Playgroud)

    不可序列化,而:

    return new DataTable("someName");
    
    Run Code Online (Sandbox Code Playgroud)

    将表格命名为参数传递的任何内容.

    请注意,通过将字符串分配给TableNameDataTable 的属性,可以随时为表指定名称.

    var table = new DataTable();
    table.TableName = "someName";
    
    Run Code Online (Sandbox Code Playgroud)

希望这会对某人有所帮助.

  • 表名为+1.我查看了Fiddler中的HTTP返回,VS使用该表名生成自定义数据类型.如果名称为null,我猜它会尝试为该自定义数据类型使用空白名称,只是出错. (8认同)

Chr*_*lum 15

诊断这些类型的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>
Run Code Online (Sandbox Code Playgroud)

然后,您可以在.NET Framework SDK(或Visual Studio)中的SvcTraceViewer.exe实用程序中打开生成的文件.在我的机器上,它可以在%PROGRAMFILES%\ Microsoft SDKs\Windows\v6.0A\Bin\SvcTraceViewer.exe中找到.

只需查找错误消息(以粗体显示红色),这将告诉您具体的问题.


小智 5

除了为所有绑定属性设置最大值之外.

确保从webservice传递/返回的每个表都必须具有表名,这意味着该table.tablename属性不应为空.


Jan*_*i5e 5

我将Datable添加到数据集并返回表格,如此...

DataTable result = new DataTable("result");

//linq to populate the table

Dataset ds = new DataSet();
ds.Tables.Add(result);
return ds.Tables[0];
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你 :)