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

摘要:
DataSets=newDataSet();//将数据转换为xml格式StringXmlStr=ds。GetXml();“<啤酒<葡萄酒<分支1<</NewDataSet>///将DataTable转换为XML格式的字符串///<paramname=”dtData“>返回;

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

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

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

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

DataSet ds = new DataSet();
ds.Tables.Add(dtData);

//将数据转换为xml格式
String XmlStr = ds.GetXml();

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

                                                                             1       啤酒        分店1

                                                                             2       红酒        分店1

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

<NewDataSet>
  <Recipe>
    <ID>1</ID>
    <Name>啤酒</Name>
    <BranchNo>分店1</BranchNo>
  </Recipe>
  <Recipe>
    <ID>2</ID>
    <Name>红酒</Name>
    <BranchNo>分店1</BranchNo>
  </Recipe>
</NewDataSet>

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

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

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

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

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

        /// <summary>
        /// 将DataTable转换成XML格式的字符串
         /// </summary>
        /// <param name="dtData">DataTable</param>
        /// <returns>返回:XML格式的字符串</returns>
        public String DataTableToXmlStr(DataTable dtData)
        {
            try
            {
                DataSet ds = new DataSet();
                ds.Tables.Add(dtData);

                //将数据转换为xml格式
                   String XmlStr = ds.GetXml().Replace("
", "换行符").Replace("/", "~");
                return XmlStr;
            }
            catch (Exception ex)
            {
                return "";
            }
        }

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

String xmlStr = xmlStr.Replace("换行符", "
").Replace("~", "/");

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

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

         /// <summary>
        /// 将XML格式的字符串转化为DataTable
        /// </summary>
        /// <param name="xmlStr">XML格式的字符串</param>
        /// <returns>返回:DataTable</returns>
        public DataTable XmlStrToData(String xmlStr)
        {
            XmlTextReader reader = null;
            try
            {
                xmlStr = xmlStr.Replace("换行符", "
").Replace("~", "/");
                DataSet xmlds = new DataSet();
                StringReader stream = new StringReader(xmlStr);
                reader = new XmlTextReader(stream);
                xmlds.ReadXml(reader);

                if (reader != null)
                {
                    reader.Close();
                }

                return xmlds.Tables[0]; 
            }
            catch (Exception ex)
            {
                if (reader != null)
                {
                    reader.Close();
                }
                return null;
            }
        }

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

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


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

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

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

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

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

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

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

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

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

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

11.21补充:

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

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

(1)做一个Model:

public class MainBranchModel
    {
        public DataTable dtData = new DataTable();
    }

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

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

(3)客户端上传数据:

MainBranchModel recipeStr = new MainBranchModel();
recipeStr.dtData = dt.Copy();//dt就是客户端获取到的数据

//调用服务端函数:向总店发送数据
//将recipeStr作为参数传过去,服务端接收到后就可以直接用了。。。

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

免责声明:文章转载自《使用WCF传输DataTable:DataTable和Xml格式的字符串相互转换(C#)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇如何判断数据库中存储的是不是乱码轻松玩转windows之wamp开发环境部署下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

c#socket发送邮件详解

本文来自http://blog.csdn.net/gaooo/article/details/2027145 邮件发送在web应用中是屡见不鲜的,在asp时代大家多是利用一些第三方提供的组件如JMAIL、ASPMAIL等进行邮件发送。自从微软推出 Asp.net后,很多程序员开始转向采用C#作为主要的开发语言。asp.net提供了更加强大的功能,同时也提供...

NFS 共享存储

部署# 服务端# 安装 NFS 服务 #执行以下命令安装 NFS 服务, #apt 会自动安装 nfs-common、rpcbind 等软件包 sudoaptinstall nfs-kernel-server 创建共享目录 在服务器端创建 /nfs 目录。 编写配置文件 vim /etc/exports #[任意主机所有权限] /nfs...

Python爬取中文页面的时候出现的乱码问题

一、读取返回的页面数据 在浏览器打开的时候查看源代码,如果在头部信息中指定了UTF-8 那么再python代码中读取页面信息的时候,就需要指定读取的编码方式: response.read().decode('utf-8') 二、把中文数据写入到文件的时候 python默认的是按照ACSII的编码往外写,所以中文数据往外写肯定会出现乱码 那么再往外写入文件的...

C# 异步Socket

C# 异步Socket (BeginXXXX)服务器代码 前言: 1、最近维护公司的一个旧项目,是Socket通讯的,主要用于接收IPC(客户端)发送上来的抓拍图像,期间要保持通讯,监测数据包并进行处理。但是看之前那人写的代码个人觉得并不是很适合自己,于是就重写了,不过项目暂时弃置了,为了以后能够方便使用,也方便更多像我一样还是渣渣程序员的人,记录一些心得...

阿里云oss对象存储在vue中的使用

阿里云对象存储OSS(Object Storage Service)是阿里云提供的海量、安全、低成本、高持久的云存储服务。其数据设计持久性不低于99.9999999999%(12个9),服务可用性(或业务连续性)不低于99.995%。 OSS具有与平台无关的RESTful API接口,可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。 项目中如果...

从0学习WebLogic CVE-2020-2551漏洞

先知社区:https://xz.aliyun.com/t/7725 最近遇到的实际环境为weblogic,所以这里顺便总结下测2020-2551的一些相关的点 2551也是学习了很多优秀的师傅文章,非常感谢 0X00 漏洞利用基础学习从0开始学习复现这个洞不免又会设计到Java反序列化漏洞中那些老生常谈的名词理解,涉及到Java反序列化中的一些协议、行为、...