背景:项目中要用到客户端向服务端传数据,使用WCF,绑定webHttpBinding,做了一个小例子。

业务逻辑简介:客户端在a表中添加了几条数据,从SQL Server数据库直接取出新添加的数据(DataTable格式的数据),传递给服务端,服务端有着和客户端相同的数据库结构,将收到的数据也同样添加到自己的a表中。除了添加数据,还有可能进行修改、删除等,并且有几十张表都会依次进行上述操作。客户端的任何变动都需要传给服务端,服务端做相同的变动。

由于客户端是从SQL直接取出的DataTable格式的数据,传递给服务端时,DataTable无法作为参数类型,运行会报错(这里是指使用在[WebInvoke]方法中时)。因此想到将DataTable转换成String类型再进行传输。为了保证服务端在收到字符串后能够再成功转换成DataTable,使用了XML格式的String。查阅了很多资料,网上很多例子都是先生成XML格式的文件,再把文件序列化后进行传输,感觉很麻烦。最终找到了一个解决方案,大致步骤如下:

1、在客户端将取到的DataTable数据加入一个DataSet中,DataSet有一个GetXml方法,可以直接转换成XML格式的字符串。

  1. DataSet ds = new DataSet();
  2. ds.Tables.Add(dtData);
  3.  
  4. //将数据转换为xml格式
  5. String XmlStr = ds.GetXml();

其中dtData就是获取到的DataTable格式的数据,内容如下:ID     Name      BranchNo

1       啤酒        分店1

2       红酒        分店1

转换成的XML字符串的内容为:

  1. <NewDataSet>
  2. <Recipe>
  3. <ID></ID>
  4. <Name>啤酒</Name>
  5. <BranchNo>分店1</BranchNo>
  6. </Recipe>
  7. <Recipe>
  8. <ID></ID>
  9. <Name>红酒</Name>
  10. <BranchNo>分店1</BranchNo>
  11. </Recipe>
  12. </NewDataSet>

表示为String类型后,XmlStr变量的内容为:"<NewDataSet>\r\n  <Recipe>\r\n    <ID>1</ID>\r\n    <Name>啤酒</Name>\r\n    <BranchNo>分店1</BranchNo>\r\n  </Recipe>\r\n  <Recipe>\r\n    <ID>2</ID>\r\n    <Name>红酒</Name>\r\n    <BranchNo>分店1</BranchNo>\r\n  </Recipe>\r\n</NewDataSet>"

2、虽然String类型(XmlStr变量)可以作为参数直接传给服务端了,但是由于字符串中包含:\r\n,以及/,因此传输的时候仍然会报错。这里需要将这些特殊字符先替换掉,如:

  1. String XmlStr = ds.GetXml().Replace("\r\n", "换行符").Replace("/", "~");

然后再进行传输就可以了。

因此,将DataTable转换成XML格式字符串的完整方法为:

  1. /// <summary>
  2. /// 将DataTable转换成XML格式的字符串
  3. /// </summary>
  4. /// <param name="dtData">DataTable</param>
  5. /// <returns>返回:XML格式的字符串</returns>
  6. public String DataTableToXmlStr(DataTable dtData)
  7. {
  8. try
  9. {
  10. DataSet ds = new DataSet();
  11. ds.Tables.Add(dtData);
  12.  
  13. //将数据转换为xml格式
  14. String XmlStr = ds.GetXml().Replace("\r\n", "换行符").Replace("/", "~");
  15. return XmlStr;
  16. }
  17. catch (Exception ex)
  18. {
  19. return "";
  20. }
  21. }

3、服务端接收到XML格式的字符串之后,首先将被替换的特殊字符还原:

  1. String xmlStr = xmlStr.Replace("换行符", "\r\n").Replace("~", "/");

4、最后将XML格式的字符串再还原为DataTable格式的数据,以便对数据库进行操作。需要添加对System.Xml的引用。

将XML格式的字符串转化为DataTable的完整方法如下所示:

  1. /// <summary>
  2. /// 将XML格式的字符串转化为DataTable
  3. /// </summary>
  4. /// <param name="xmlStr">XML格式的字符串</param>
  5. /// <returns>返回:DataTable</returns>
  6. public DataTable XmlStrToData(String xmlStr)
  7. {
  8. XmlTextReader reader = null;
  9. try
  10. {
  11. xmlStr = xmlStr.Replace("换行符", "\r\n").Replace("~", "/");
  12. DataSet xmlds = new DataSet();
  13. StringReader stream = new StringReader(xmlStr);
  14. reader = new XmlTextReader(stream);
  15. xmlds.ReadXml(reader);
  16.  
  17. if (reader != null)
  18. {
  19. reader.Close();
  20. }
  21.  
  22. return xmlds.Tables[];
  23. }
  24. catch (Exception ex)
  25. {
  26. if (reader != null)
  27. {
  28. reader.Close();
  29. }
  30. return null;
  31. }
  32. }

5、我的例子中,服务端的接口函数如下:

  1. /// <summary>
  2. /// 分店向总店上传酒水数据
  3. /// </summary>
  4. /// <param name="recipeXml"></param>
  5. /// <returns></returns>
  6. [OperationContract(Name = "BranchRecipeXml")]
  7. [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "BranchRecipeXml/{recipeXml}", BodyStyle = WebMessageBodyStyle.Bare)]
  8. String BranchRecipe(String recipeXml);

客户端通过调用这个方法,将DataTable格式的数据转换为XML格式的字符串,通过recipeXml参数传递给服务端,并接收返回值(String类型,表示操作是否成功)。

PS:客户端和服务端的具体例子就不直接给出了,不是本文要表达的重点。

补充:还有一种比较简单的实现方式,是刚刚才试验出来的:

1、客户端,将DataTable格式的数据(dt)写入Stream:

  1. System.IO.MemoryStream xmlStream = new System.IO.MemoryStream();
    dt.WriteXml(xmlStream, XmlWriteMode.WriteSchema);
  2. xmlStream.Position = ;

2、将Stream作为参数传递给服务端,服务端接口如下:

  1. /// <summary>
  2. /// 分店向总店上传酒水数据
  3. /// </summary>
  4. /// <param name="recipeStr"></param>
  5. /// <returns></returns>
  6. [OperationContract(Name = "BranchRecipeStr")]
  7. [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "BranchRecipeStr", BodyStyle = WebMessageBodyStyle.Bare)]
  8. String BranchRecipeStr(Stream recipeStr);

3、服务端接收到Stream后,再转换成DataTable:

  1. DataTable dt = new DataTable();
  2. dt.ReadXml(recipeStr);

这里recipeStr就是客户端传过来的Stream recipeStr。

11.21补充:

刚刚又试验出一种更好的方法。。。是在做的过程中无意间想到的,试了一下,居然可以—_—

因为[WebInvoke]方法的参数可以是类的。。。那把表结构做成类的形式太麻烦了的话,是不是可以把表作为这个类中的一个元素呢?

(1)做一个Model:

  1. public class MainBranchModel
  2. {
  3. public DataTable dtData = new DataTable();
  4. }

(2)服务端接口,将这个Model作为参数类型:

  1. /// <summary>
  2. /// 分店向总店上传酒水数据
  3. /// </summary>
  4. /// <param name="recipeStr"></param>
  5. /// <returns></returns>
  6. [OperationContract(Name = "BranchRecipeModel")]
  7. [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "BranchRecipeModel", BodyStyle = WebMessageBodyStyle.Bare)]
  8. String BranchRecipeStr(MainBranchModel recipeStr);

(3)客户端上传数据:

  1. MainBranchModel recipeStr = new MainBranchModel();
  2. recipeStr.dtData = dt.Copy();//dt就是客户端获取到的数据
  3.  
  4. //调用服务端函数:向总店发送数据
  5. //将recipeStr作为参数传过去,服务端接收到后就可以直接用了。。。

用Model作为参数的好处,是当参数个数发生变化后,不需要修改接口函数。如在Model中添加一个元素,传参时对这个新参数赋值,收到后再对新参数进行处理即可。接口函数及调用方法完全不用做任何改动。

使用WCF传输DataTable:DataTable和Xml格式的字符串相互转换(C#)的更多相关文章

  1. Java中XML格式的字符串4读取方式的简单比较

    Java中XML格式的字符串4读取方式的简单比较 1.java自带的DOM解析. import java.io.StringReader; import javax.xml.parsers.Docum ...

  2. Dom4j解析xml格式的字符串【java】

    一般我们会使用dom4j.SAX.w3c来解析xml文件,网上也大多提供此类解决方案. 但在实际项目中,也有会解析xml格式的字符串报文的. 比如,有如下字符串: String = "< ...

  3. 读取xml格式的字符串和上下文中的xml数据

    1.读取xml格式的字符串 假设有一段下面的xml格式的字符串: <xml>     <return_code><![CDATA[SUCCESS]]></re ...

  4. soapui如何发送xml格式的字符串

    一个服务需要的xml格式的字符串参数,用soapUI传递参数时要这样写: <![CDATA[<?xml version="1.0" encoding="UTF ...

  5. java解析Xml格式的字符串

    最近在工作中,需要调别的接口,接口返回的是一个字符串,而且内容是xml格式的,结果在解析json的时候报错,最终修改了接口的返回方式,以Map返回, 才得以接收到这个xml的字符串,然后通过dom4j ...

  6. 使用dom4j修改XML格式的字符串

    XML格式 <data> <ryzd> <record> <western> <record> <diagnoses> < ...

  7. (转载)将一段符合XML格式规范字符串插入已有XML文档当中

    想我们已经存在一个XML文档,结构如下:   < xmlversion="1.0"encoding="utf-8">< employees&g ...

  8. C# asp.net XML格式的字符串显示不全

    前台显示XML字符串显示不全 后台XML字符串使用<xmp></xmp>将XML格式字符串括起来

  9. C# 解析XML格式的字符串

    public CreateOrderReturnResult GetCreateOrderReturnApi() { var result = new CreateOrderReturnResult( ...

随机推荐

  1. 2.JAVA之GUI编程布局

    布局管理器 容器中的组件排放方式,就是布局 常见的布局管理器: **************************************************** 1.FlowLayout(流式 ...

  2. LINQ to SQL语句(18)之运算符转换

    运算符转换 1.AsEnumerable:将类型转换为泛型 IEnumerable 使用 AsEnumerable<TSource> 可返回类型化为泛型 IEnumerable 的参数.在 ...

  3. Get radio selected value

    先看下面 foreach得到的radio list: 现在想实现把选择的选项值Post至服务端:

  4. [Q&A] C1DataGrid 奇葩的 BeginNewRow() 方法

    一.前言 用户千千万,自然需求就千奇百怪都有,某天有人提了这样一个需求: 某个 C1DataGrid 在 ScrollViewer 的底部(使纵向滚动条显示出来),然后当该 C1DataGrid 增加 ...

  5. JavaWeb_day01_HTTP_Servlet

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! JavaWeb_day01 HTTP协议 HTTP(H ...

  6. 关于Linux下转换oracle字符集

    前阵子给以同事导oracle数据库,但是发现导入后数据都是乱码,下面是自己解决这个问题的一些小整理. 比如: #su oralce $export ORACLE_SID=orcl $export OR ...

  7. xinetd cpu 100%

    今天,有个给客户试用的环境出现xinetd cpu 100%,而且连续运行很长时间了.之前也有环境发生过,今天排查解决了三四个问题,实在是查的身体都不舒服了,还没时间查这个问题... 知道的求解...

  8. (转) Qt 出现“undefined reference to `vtable for”原因总结

    由于Qt本身实现的机制所限,我们在使用Qt制作某些软件程序的时候,会遇到各种各样这样那样的问题,而且很多是很难,或者根本找不到原因的,即使解决了问题,如果有人问你为什么,你只能回答--不知道. 今天我 ...

  9. sea.js详解

    Seajs相关知识 seajs.Use 引入入口文件 第一个参数表示模块id 字符串表示一个模块id 数组,数组每个成员表示一个模块 第二个参数表示回调函数(可有可无的) 作用就是当模块加载完成执行回 ...

  10. [JS,Canvas]日历时钟

    [JS,Canvas]日历时钟 Html: <!doctype html> <html> <head> <meta charset="UTF-8&q ...