我可以序列化数据表或数据集以通过 C# 中的 Web 服务进行传输吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/561203/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 08:14:04  来源:igfitidea点击:

Can I serialize a Data Table or Data Set to transfer over a Web Service in C#?

c#web-services

提问by Loganj99

I am using a web service to query data from a table. Then I have to send it to a user who wants it as a DataTable. Can I serialize the data? Or should I send it as A DataSet. I am new to Web Services, so I am not sure the best way to do it.

我正在使用 Web 服务从表中查询数据。然后我必须将它发送给想要它作为 DataTable 的用户。我可以序列化数据吗?或者我应该将它作为数据集发送。我是 Web 服务的新手,所以我不确定最好的方法。

回答by Nick Berardi

You can transfer DataTable's over a Web Service. So that is probably your best option, becuase that is what the client asked for.

您可以通过 Web 服务传输 DataTable。所以这可能是你最好的选择,因为这就是客户所要求的。

回答by Joel Coehoorn

Sure. Both DataTable and DataSet are serializable, and they also have ReadXml() and WriteXml() functions you can use, too.

当然。DataTable 和 DataSet 都是可序列化的,它们也有您可以使用的 ReadXml() 和 WriteXml() 函数。

回答by Marc Gravell

If you expose it as a DataSet/DataTable, it will do its own serialization anyway (via IXmlSerializable, IIRC). Note that DataSet/DataTabledon't make for good data-types on web services if you want the service to be portable to other patforms (i.e. a java client, etc). But you cansimply expose it as such if you want...; .NET will deal with the translation.

如果您将其公开为DataSet/ DataTable,它无论如何都会执行自己的序列化(通过IXmlSerializable,IIRC)。请注意,如果您希望服务可移植到其他模式(即 Java 客户端等),则DataSet/DataTable不要为 Web 服务提供良好的数据类型。但是如果你愿意,你可以简单地公开它......; .NET 将处理翻译。

回答by Chris Ballard

See this postby Richard Blewett for reasons why you probably wouldn't want to do this.

请参阅Richard Blewett 的这篇文章,了解您可能不想这样做的原因。

EDIT:To summarise the above:

编辑:总结以上内容:

  • Using DataSetisn't interoperable. It uses annotations which only make sense when each end of the link uses the Microsoft stack.
  • DataSetis a pretty inefficient class for sending data over the wire - it contains change tracking data and metadata also.
  • It introduces tight coupling - changes made on the service side which might not even be needed by the client have to be reflected on the client side as well.
  • 使用DataSet不可互操作。它使用的注释只有在链接的每一端都使用 Microsoft 堆栈时才有意义。
  • DataSet是一个非常低效的类,用于通过线路发送数据 - 它也包含更改跟踪数据和元数据。
  • 它引入了紧耦合——在服务端所做的甚至可能不需要客户端的更改也必须反映在客户端。

回答by freggel

You can send the data as a xml string from a dataset by DataSet.GetXml()

您可以通过以下方式将数据作为数据集的 xml 字符串发送 DataSet.GetXml()

And than the user can deserialize it with DataSet.ReadXml()

然后用户可以反序列化它 DataSet.ReadXml()

And get the datatable from the dataset by DataSet.Tables

并从数据集中获取数据表 DataSet.Tables

Good luck

祝你好运

回答by Tor Haugen

The simplest and most interoperable way is to serialize the dataset to XML with the GetXml() method, then pass that as a string from the web service. The client can then deserialize it with the ReadXml() method.

最简单且最具互操作性的方法是使用 GetXml() 方法将数据集序列化为 XML,然后将其作为字符串从 Web 服务传递。然后客户端可以使用 ReadXml() 方法反序列化它。

We have consumed a service which did it this way, and it worked great.

我们已经使用了这样一种服务,而且效果很好。

The alternative is to expose the DataSet class in the service, and return the dataset object. But this will complicate things, especially if any client should be non-.NET.

另一种方法是在服务中公开 DataSet 类,并返回数据集对象。但这会使事情变得复杂,特别是如果任何客户端都不是 .NET。

回答by Lesh

DataTable are serializable but some tricks exist to return a untyped DataTable through WebService.

DataTable 是可序列化的,但存在一些通过 WebService 返回无类型数据表的技巧。

Before web service method returns filled DataTable (on service side) it must have assigned property TableName. In case if inside the OperationContract DataTable receives the reference of typed DataTable the serialization will fail with messaga like ""The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error".

在 Web 服务方法返回填充的 DataTable(在服务端)之前,它必须已分配属性 TableName。如果在 OperationContract DataTable 中接收到类型化 DataTable 的引用,则序列化将失败,并显示类似“”服务器没有提供有意义的回复;这可能是由于合同不匹配、会话过早关闭或内部服务器错误造成的。”

It means that you should fill the created DataTable, for instance using method Merge (or manually). Here are such DataContract implementation sample;

这意味着您应该填充创建的 DataTable,例如使用方法 Merge(或手动)。下面是这样的 DataContract 实现示例;

DataTable IHorizonCLService.RetrieveChangeLog(int iId)
{
   DataTable dt = new DataTable(); //create new DataTable to be returned by this web method
   dt.Merge(HorMan.RetrieveChangeLog(iId)); //get typed DataTable and fills the DataTable 
   dt.TableName = "SurChangeLogHor"; //assigns name
   return dt;
}

回答by Painy James

Just an interesting remark from here

只是一个有趣的评论从这里

And, never, ever, ever send an instance of System.Data.DataSet over the wire. There has never been, is not now, and never will be any reason to ever send any instance of this type anywhere. It's beyond massive and makes the 10,000 property data transfer object seem lightweight. The fact that something is serializable doesn't mean that it should be.

而且,永远,永远,永远不要通过网络发送 System.Data.DataSet 的实例。从来没有,现在没有,也永远不会有任何理由将这种类型的任何实例发送到任何地方。它超越了海量,使 10,000 属性数据传输对象看起来轻巧。可序列化的事实并不意味着它应该是。