使用WCF服务返回DataTable对象

时间:2009-09-04 17:42:57

标签: wcf datatable dataset serialization

这是一个奇怪的问题,我正在与WCF尝试在响应中发送DataTable。我有以下服务合同:

[ServiceContract]
public interface ISapphireDataService {
    [OperationContract]
    DataTable LoadData(string query, DateTime start, DateTime end);

    [OperationContract]
    string LoadDataTest();
}

以下方法的实现(其中provider是一个使数据库调用并返回DataTable的类):

public DataTable LoadData(string query, DateTime start, DateTime end) {
    //DataSet temp = new DataSet();
    //temp.Tables.Add(provider.LoadData(query, start, end).Copy());
    //return temp;

    return provider.LoadData(query, start, end).Copy();
}

public string LoadDataTest() {
    return "Hello World!";
}

现在,当我这样离开时,我总是在调用LoadData(...)方法时出错:

  

接收HTTP响应时发生错误   http://localhost:8731/Design_Time_Addresses/DataProviderServiceLibrary/SapphireDataService/。   这可能是由于服务端点绑定不使用HTTP   协议。
  这也可能是由于HTTP请求上下文所致   由服务器中止(可能是由于服务关闭)   有关详细信息,请参阅服务器日志。

这很奇怪,因为服务配置为使用wsHttpBinding,我假设使用HTTP协议。如果我尝试调用LoadDataTest()方法,则不会发生此错误!

所以我所做的就是将我从数据库中获取的这个表放入DataSet对象中并且它有效!没有错误或任何类似的东西。 但是,DataSet中返回的表是EMPTY。所有字段都是Null,没有数据被正确传输/反序列化,似乎:(

这似乎是一个常见的问题,但我还没有看到有效的答案。有什么想法吗?

3 个答案:

答案 0 :(得分:17)

我知道这是一个老问题,但也许某人仍然遇到同样的问题(就像我一样)。 我遇到了同样令人困惑的错误信息,花了好几个小时撞到我的头......

    public DataTable GetDataTable()
    {
        DataTable dt = new DataTable(**"MY_NAME"**);
        dt.Columns.Add("ID", typeof(int));
        dt.Columns.Add("Caption", typeof(string));

        dt.Rows.Add(new object[] { 1, "hooray!" });
        return dt;
    }

你应该给你的DataTable一个名字,我使用了重载的构造函数,没有更多的错误!

编辑: 当然,您实际上不应该使用DataTable或DataSet作为WCF服务的返回类型。对我而言,这仅仅是出于测试目的,因为我认为这是从数据库和线路中获取内容的最快捷方式....男孩我错了:)

答案 1 :(得分:7)

使用DataSet和DataTable不是最佳做法。它们非常笨重,最好使用一组数据类(poco / dto)。

一些背景信息:

Returning DataSets from WebServices is the Spawn of Satan and Represents All That Is Truly Evil in the World

答案 2 :(得分:6)

虽然我承认通过服务发送DataSet和DataTables是不好的,但实际上我已经改变了它,所以我没有这样做,问题的根源在其他地方撒谎。

对于那些绝对需要使用DataTables / DataSet的人来说,我得到的错误是因为我试图发送一个DbNull对象。我想这不是可序列化的,或者有其他原因它拒绝发送它。

在手动“转换”DbNull为null之后(我必须这样做才能将数据提取到我自己的自定义DataContract中),错误消失了,并且它有效!