使用WCF传输DataTable:DataTable和Xml格式的字符串相互转换(C#)
背景:项目中要用到客户端向服务端传数据,使用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></ID>
<Name>啤酒</Name>
<BranchNo>分店1</BranchNo>
</Recipe>
<Recipe>
<ID></ID>
<Name>红酒</Name>
<BranchNo>分店1</BranchNo>
</Recipe>
</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,以及/,因此传输的时候仍然会报错。这里需要将这些特殊字符先替换掉,如:
String XmlStr = ds.GetXml().Replace("\r\n", "换行符").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("\r\n", "换行符").Replace("/", "~");
return XmlStr;
}
catch (Exception ex)
{
return "";
}
}
3、服务端接收到XML格式的字符串之后,首先将被替换的特殊字符还原:
String xmlStr = xmlStr.Replace("换行符", "\r\n").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("换行符", "\r\n").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[];
}
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 = ;
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#)的更多相关文章
- Java中XML格式的字符串4读取方式的简单比较
Java中XML格式的字符串4读取方式的简单比较 1.java自带的DOM解析. import java.io.StringReader; import javax.xml.parsers.Docum ...
- Dom4j解析xml格式的字符串【java】
一般我们会使用dom4j.SAX.w3c来解析xml文件,网上也大多提供此类解决方案. 但在实际项目中,也有会解析xml格式的字符串报文的. 比如,有如下字符串: String = "< ...
- 读取xml格式的字符串和上下文中的xml数据
1.读取xml格式的字符串 假设有一段下面的xml格式的字符串: <xml> <return_code><![CDATA[SUCCESS]]></re ...
- soapui如何发送xml格式的字符串
一个服务需要的xml格式的字符串参数,用soapUI传递参数时要这样写: <![CDATA[<?xml version="1.0" encoding="UTF ...
- java解析Xml格式的字符串
最近在工作中,需要调别的接口,接口返回的是一个字符串,而且内容是xml格式的,结果在解析json的时候报错,最终修改了接口的返回方式,以Map返回, 才得以接收到这个xml的字符串,然后通过dom4j ...
- 使用dom4j修改XML格式的字符串
XML格式 <data> <ryzd> <record> <western> <record> <diagnoses> < ...
- (转载)将一段符合XML格式规范字符串插入已有XML文档当中
想我们已经存在一个XML文档,结构如下: < xmlversion="1.0"encoding="utf-8">< employees&g ...
- C# asp.net XML格式的字符串显示不全
前台显示XML字符串显示不全 后台XML字符串使用<xmp></xmp>将XML格式字符串括起来
- C# 解析XML格式的字符串
public CreateOrderReturnResult GetCreateOrderReturnApi() { var result = new CreateOrderReturnResult( ...
随机推荐
- Eclipse 安装 SVN 的在线插件
这是继上次svn 客户端与服务器安装后的如何在Eclipse 环境下在线安装 SVN插件,我的Eclipse版本是4.50 SVN的在线安装 下面为大家提供SVN 的在线安装教程.下面是安装的 详细过 ...
- Angular 基础入门
简介 什么是AngularJS 一个功能非常完备的前端框架,通过增强HTML的方式提供一种便捷开发Web应用程序的方式 其核心特点就是几乎无任何DOM操作,让开发人员的精力和时间全部集中于业务 MVC ...
- awk使用说明
原文地址:http://www.cnblogs.com/verrion/p/awk_usage.html Awk使用说明 运维必须掌握的三剑客工具:grep(文件内容过滤器),sed(数据流处理器), ...
- afxcomctl32.h与afxcomctl32.inl报错
afxcomctl32.h与afxcomctl32.inl报错 编译公司一个几年前的老项目,是从VC6.0升级到VS2005的. 1.编译时报缺少头文件,于是附件包含目录,于是出现了以下报错: 1&g ...
- java 开发模式
Java-开发模式 Java Web开发方案有多种,这里列举一些经典的开发模式进行横向比较JSP+JAVABEAN开发模式: 特点:该模式将业务逻辑与页面表现进行分离,在一定程度上增加了程序的可 ...
- wamp 服务器安装问题 及cmd常用命令 和 php mysql数据库常用cmd命令集
1 官网下载wamp软件包,根据提示安装 2 目录结构: wamp: bin/为套件目录 包括mysql apache php log 日志记录 alias 配置 apps 数据库 ...
- JS高程4.变量,作用域和内存问题(3)垃圾收集
JavaScript的自动垃圾收集机制 执行环境会负责管理代码执行过程中使用的内存,编写JavaScript程序时,所需内存的分配以及无用内存的回收完全实现自动管理. 原理: 找出那些不再继续使用的变 ...
- AlloyRenderingEngine之Shape
写在前面 不读文章,只对代码感兴趣可以直接跳转到这里 https://github.com/AlloyTeam/AlloyGameEngine 然后star一下,多谢支持:). 游戏或者应用中,不是所 ...
- 前端导出Excel兼容写法
今天整理出在Web前端导出Excel的写法,写了一个工具类,对各个浏览器进行了兼容. 首先,导出的数据来源可能有两种: 1. 页面的HTML内容(一般是table) 2. 纯数据 PS:不同的数据源, ...
- switch语句的妙用
switch语句的普通用法很简单,如下: var a = 3; switch (a) { case 1: console.log(a); break; case 2: case 3: console. ...