简体   繁体   English

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

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

I am using a web service to query data from a table. 我正在使用Web服务来查询表中的数据。 Then I have to send it to a user who wants it as a DataTable. 然后我必须将它发送给想要它作为DataTable的用户。 Can I serialize the data? 我可以序列化数据吗? Or should I send it as A DataSet. 或者我应该将其作为A DataSet发送。 I am new to Web Services, so I am not sure the best way to do it. 我是Web Services的新手,所以我不确定最好的方法。

You can send the data as a xml string from a dataset by DataSet.GetXml() 您可以通过DataSet.GetXml()将数据作为xml字符串从数据集发送

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 祝好运

If you expose it as a DataSet / DataTable , it will do its own serialization anyway (via IXmlSerializable , IIRC). 如果将它作为DataSet / DataTable公开,它将自己进行自己的序列化(通过IXmlSerializable ,IIRC)。 Note that DataSet / DataTable don't make for good data-types on web services if you want the service to be portable to other patforms (ie a java client, etc). 请注意,如果您希望将服务移植到其他模式(即Java客户端等),则DataSet / DataTable不会在Web服务上创建良好的数据类型。 But you can simply expose it as such if you want...; 但是如果你想......你可以简单地将它暴露出来; .NET will deal with the translation. .NET将处理翻译。

See this post by Richard Blewett for reasons why you probably wouldn't want to do this. 请参阅Richard Blewett的这篇文章 ,了解您可能不希望这样做的原因。

EDIT: To summarise the above: 编辑:总结以上内容:

  • Using DataSet isn't interoperable. 使用DataSet不可互操作。 It uses annotations which only make sense when each end of the link uses the Microsoft stack. 它使用的注释只有在链接的每一端使用Microsoft堆栈时才有意义。
  • DataSet is a pretty inefficient class for sending data over the wire - it contains change tracking data and metadata also. DataSet是一种非常低效的类,用于通过网络发送数据 - 它还包含更改跟踪数据和元数据。
  • 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. 它引入了紧密耦合 - 客户端甚至可能不需要在服务端进行的更改也必须反映在客户端。

Sure. 当然。 Both DataTable and DataSet are serializable, and they also have ReadXml() and WriteXml() functions you can use, too. DataTable和DataSet都是可序列化的,它们也可以使用ReadXml()和WriteXml()函数。

DataTable are serializable but some tricks exist to return a untyped DataTable through WebService. DataTable是可序列化的,但存在一些通过WebService返回无类型DataTable的技巧。

Before web service method returns filled DataTable (on service side) it must have assigned property TableName. 在Web服务方法返回填充的DataTable之前(在服务端),它必须已分配属性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; 如果在OperationContract DataTable内部接收到类型化DataTable的引用,则序列化将失败,并且Messaga就像“”服务器没有提供有意义的回复; this might be caused by a contract mismatch, a premature session shutdown or an internal server error". 这可能是由于合同不匹配,过早的会话关闭或内部服务器错误造成的“。

It means that you should fill the created DataTable, for instance using method Merge (or manually). 这意味着您应该填充创建的DataTable,例如使用方法Merge(或手动)。 Here are such DataContract implementation sample; 以下是此类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;
}

Just an interesting remark from here 从只是一个有趣的话在这里

And, never, ever, ever send an instance of System.Data.DataSet over the wire. 并且,永远不会,通过线路发送System.Data.DataSet的实例。 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. 它超出了大规模,使10,000属性数据传输对象看起来很轻巧。 The fact that something is serializable doesn't mean that it should be. 事物是可序列化的事实并不意味着它应该是。

You can transfer DataTable's over a Web Service. 您可以通过Web服务传输DataTable。 So that is probably your best option, becuase that is what the client asked for. 所以这可能是你最好的选择,因为这是客户要求的。

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. 最简单且最具互操作性的方法是使用GetXml()方法将数据集序列化为XML,然后将其作为字符串从Web服务传递。 The client can then deserialize it with the ReadXml() method. 然后,客户端可以使用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. 另一种方法是在服务中公开DataSet类,并返回数据集对象。 But this will complicate things, especially if any client should be non-.NET. 但这会使事情变得复杂,特别是如果任何客户端应该是非.NET的话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM