使用场景
项目中遇到的需求使用到了XML和实体类之前的转换以及JSON和实体类之前的转化 图片如下:
本系统和第三方系统交互时需要经过一个中间系统,M系统是涉密系统 Z是中间系统 T是非密系统
M系统和Z系统之间交互是使用Json 但是Json中包含XMl数据 Z系统收到XMl后解析需要的部分在Z系统展示并且审批 通过之后Z系统把M传入的数据再下发给T系统,T系统解析需要的Xml然后解析信息
xml格式如下图:
<?xml version="1.0" encoding="utf-8"?>
<MfgTaskInfo>
<MfgTask>
<!--主键-->
<ID>122211002373</ID>
<!--接收方-->
<WorkCenterName>JLXT</WorkCenterName>
<!--派工时间-->
<DispatchDate>2019-05-15 08:32:49</DispatchDate>
<CommonExtendData>
<Fields>
<Field Name="name" Title="名称">张三</Field>
<Field Name="age" Title="年纪">18</Field>
<Field Name="address" Title="地址">洛阳</Field>
</Fields>
</CommonExtendData>
<data>
<student>
<name></name>
<age></age>
<address></address>
</student>
</data>
</MfgTask>
</MfgTaskInfo>
如上述xml中CommonExtendData中的xml是中间系统Z需要使用到的数据,data中的xml是第三方系统T需要的数据。
CommonExtendData中包含的Xml是比较特殊的xml使用VB自带的注解无法实现
data中包含的xml是正常xml使用xml注解就可以
Xml使用
实体类转化成XML
XML参考文档:https://learn.microsoft.com
1.正常格式XMl
格式:
<data>
<student>
<name></name>
<age></age>
<address></address>
</student>
</data>
- 实体类
Imports System.Xml.Serialization
<XmlRoot("data")>
Public Class CsdnStatusCDO
<XmlElement("student")>
Private _item As New student
Public Property item() As student
Get
Return _item
End Get
Set(ByVal value As student)
_item = value
End Set
End Property
End Class
Public Class student
Private _name As String
Public Property name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _age As String
Public Property age() As String
Get
Return _age
End Get
Set(ByVal value As String)
_age = value
End Set
End Property
Private _address As String
Public Property address() As String
Get
Return _address
End Get
Set(ByVal value As String)
_address = value
End Set
End Property
End Class
- 实体类转化成xml
下面方法是实体类转化成xml 返回xml字符串 ,同时也会保存该xml到本地,这样方便查看生成的xml是否有错
''' <summary>
''' '实体类转化成xml
''' </summary>
''' <param name="obj">实体类</param>
''' <param name="path">保存本地的路径</param>
''' <param name="fileName">文件名</param>
''' <returns></returns>
Public Shared Function XmlToObj(ByVal obj As Object, ByVal path As String, ByVal fileName As String) As String
Try
If IsNothing(obj) Then
Return String.Empty
End If
Dim xmlStr As String = ""
Dim settings As XmlWriterSettings = New XmlWriterSettings
settings.OmitXmlDeclaration = True
settings.Encoding = Encoding.Default
Dim memStream As MemoryStream = New MemoryStream
Using writer As XmlWriter = XmlWriter.Create(memStream, settings)
Dim nss As XmlSerializerNamespaces = New XmlSerializerNamespaces
nss.Add("", "")
Dim formatter As XmlSerializer = New XmlSerializer(obj.GetType())
formatter.Serialize(writer, obj, nss)
End Using
path = path + "\\" + System.DateTime.Now.ToString("yyyy-MM-dd")
If Directory.Exists(path) = False Then
My.Computer.FileSystem.CreateDirectory(path)
End If
xmlStr = Encoding.Default.GetString(memStream.ToArray)
Try
Dim xmlDoc As New XmlDocument
Dim xmlDocmentName As String = obj.GetType().Name
xmlDoc.LoadXml(xmlStr)
Dim savePath As String = System.IO.Path.Combine(path, fileName)
xmlDoc.Save(savePath)
Return xmlStr
Catch ex As Exception
Return String.Empty
End Try
Catch ex As Exception
Return String.Empty
End Try
End Function
- 测试方法
Public Sub TestXmltoObjOne()
'单条数据
Dim s As New CsdnStatusCDO
Dim t As New student
t.name = "张三"
t.age = "18"
t.address = "洛阳"
s.item = t
Dim srt As String = TestUtil.ObjToXml(s, "C:\test", "TestObjToXml")
Dim mm As String = ""
End Sub
- 运行结果
<data>
<item>
<name>张三</name>
<age>18</age>
<address>洛阳</address>
</item>
</data>
如果xml格式是list只需要修改下实体类中的格式即可
<XmlRoot("data")>
Public Class CsdnStatusCDO
<XmlElement("student")>
Private _items As New List(Of student)
Public Property items() As List(Of student)
Get
Return _items
End Get
Set(ByVal value As List(Of student))
_items = value
End Set
End Property
End Class
2.特殊格式XMl
格式:
<?xml version="1.0" encoding="utf-8"?>
<MfgTaskInfo>
<MfgTask>
<!--主键-->
<ID>122211002373</ID>
<!--接收方-->
<WorkCenterName>JLXT</WorkCenterName>
<CommonExtendData>
<Fields>
<Field Name="name" Title="名称">张三</Field>
<Field Name="age" Title="年纪">18</Field>
<Field Name="address" Title="地址">洛阳</Field>
</Fields>
</CommonExtendData>
<data>
<student>
<name></name>
<age></age>
<address></address>
</student>
</data>
</MfgTask>
</MfgTaskInfo>
XML转化成实体类
- xml转化成实体类方法
Public Sub TestXmltoObjOne1()
Dim doc As New XmlDocument
Dim text As XmlText
'xml声明段落
Dim xmlTitle As XmlNode = doc.CreateXmlDeclaration("1.0", "UTF-8", "")
doc.AppendChild(xmlTitle)
'根标签<MfgTaskInfo></MfgTaskInfo>
Dim MfgTaskInfo As XmlElement = doc.CreateElement("", "MfgTaskInfo", "")
text = doc.CreateTextNode("")
MfgTaskInfo.AppendChild(text)
doc.AppendChild(MfgTaskInfo)
'<MfgTask></MfgTask>
Dim MfgTask As XmlElement = doc.CreateElement("", "MfgTask", "")
text = doc.CreateTextNode("")
MfgTask.AppendChild(text)
'<ID></ID>
Dim ID As XmlElement = doc.CreateElement("", "ID", "")
text = doc.CreateTextNode("122211002373")
ID.AppendChild(text)
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(ID)
'<WorkCenterName></WorkCenterName>
Dim WorkCenterName As XmlElement = doc.CreateElement("", "WorkCenterName", "")
text = doc.CreateTextNode("JLXT")
WorkCenterName.AppendChild(text)
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(WorkCenterName)
'<CommonExtendData></CommonExtendData> 节点
Dim CommonExtendData As XmlElement = doc.CreateElement("", "CommonExtendData", "")
text = doc.CreateTextNode("")
CommonExtendData.AppendChild(text)
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(CommonExtendData)
'<Fields></Fields>
Dim Fields As XmlElement = doc.CreateElement("", "Fields", "")
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(CommonExtendData).AppendChild(Fields)
'<name></name>
Dim nameStr As XmlElement = doc.CreateElement("", "Field", "")
text = doc.CreateTextNode("李四")
nameStr.AppendChild(text)
'Field增加属性
nameStr.SetAttribute("Name", "name")
nameStr.SetAttribute("Title", "姓名")
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(CommonExtendData).AppendChild(Fields).AppendChild(nameStr)
'<age></age>
Dim ageStr As XmlElement = doc.CreateElement("", "Field", "")
text = doc.CreateTextNode("19")
ageStr.AppendChild(text)
'Field增加属性
ageStr.SetAttribute("Name", "age")
ageStr.SetAttribute("Title", "年纪")
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(CommonExtendData).AppendChild(Fields).AppendChild(ageStr)
'<address></address>
Dim addressStr As XmlElement = doc.CreateElement("", "Field", "")
text = doc.CreateTextNode("河南洛阳")
addressStr.AppendChild(text)
'Field增加属性
addressStr.SetAttribute("Name", "address")
addressStr.SetAttribute("Title", "地址")
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(CommonExtendData).AppendChild(Fields).AppendChild(addressStr)
'<data></data>节点
Dim data As XmlElement = doc.CreateElement("", "data", "")
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(data)
'<student></student>
Dim student As XmlElement = doc.CreateElement("", "student", "")
text = doc.CreateTextNode("")
student.AppendChild(text)
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(data).AppendChild(student)
'<name></name>
Dim name As XmlElement = doc.CreateElement("", "name", "")
text = doc.CreateTextNode("里斯")
name.AppendChild(text)
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(data).AppendChild(student).AppendChild(name)
'<age></age>
Dim age As XmlElement = doc.CreateElement("", "age", "")
text = doc.CreateTextNode("18")
age.AppendChild(text)
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(data).AppendChild(student).AppendChild(age)
'<address></address>
Dim address As XmlElement = doc.CreateElement("", "address", "")
text = doc.CreateTextNode("河南洛阳")
address.AppendChild(text)
doc.ChildNodes.Item(1).AppendChild(MfgTask).AppendChild(data).AppendChild(student).AppendChild(address)
TestUtil.SaveXmlToLocalhost(doc, "C:\test\t", "test")
End Sub
- 保存xml到本地的方法
''' <summary>
''' 保存xml到本地
''' </summary>
''' <param name="obj"></param>
''' <param name="path"></param>
''' <param name="fileName"></param>
''' <returns></returns>
Public Shared Function SaveXmlToLocalhost(ByRef obj As XmlDocument, ByRef path As String, ByRef fileName As String) As String
Try
If IsNothing(obj) Then
Return String.Empty
End If
Dim xmlStr As String = ""
path = path + System.DateTime.Now.ToString("yyyy-MM-dd")
If Directory.Exists(path) = False Then
My.Computer.FileSystem.CreateDirectory(path)
End If
Try
obj.Save(System.IO.Path.Combine(path, fileName))
Return obj.OuterXml.ToString
Catch ex As Exception
Return String.Empty
End Try
Catch ex As Exception
Return String.Empty
End Try
End Function
- 结果
<?xml version="1.0" encoding="UTF-8"?>
<MfgTaskInfo>
<MfgTask>
<ID>122211002373</ID>
<WorkCenterName>JLXT</WorkCenterName>
<CommonExtendData>
<Fields>
<Field Name="name" Title="姓名">李四</Field>
<Field Name="age" Title="年纪">19</Field>
<Field Name="address" Title="地址">河南洛阳</Field>
</Fields>
</CommonExtendData>
<data>
<student>
<name>里斯</name>
<age>18</age>
<address>河南洛阳</address>
</student>
</data>
</MfgTask>
</MfgTaskInfo>
Josn使用
实体类转化成JSON
- 实体类
Public Class student
Private _name As String
Public Property name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _age As String
Public Property age() As String
Get
Return _age
End Get
Set(ByVal value As String)
_age = value
End Set
End Property
Private _address As String
Public Property address() As String
Get
Return _address
End Get
Set(ByVal value As String)
_address = value
End Set
End Property
End Class
- 实体类转化成json工具类
'实体类转化成json
Public Shared Function ObjToJson(ByVal item As Object) As String
Dim serializer As New DataContractJsonSerializer(item.GetType)
Dim ms As New MemoryStream
serializer.WriteObject(ms, item)
Dim sb As New StringBuilder
sb.Append(Encoding.UTF8.GetString(ms.ToArray))
Return sb.ToString
End Function
- 测试方法
Private Sub TestObjToJson()
Dim t As New student
t.name = "张三"
t.age = "18"
t.address = "洛阳"
Dim ret As String = TestUtil.ObjToJson(t)
End Sub
- 结果
{"address":"洛阳","age":"18","name":"张三"}
JSON转化成实体类
- 实体类
Public Class TestDtoChS
Private _name As String
Public Property name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _age As String
Public Property age() As String
Get
Return _age
End Get
Set(ByVal value As String)
_age = value
End Set
End Property
Private _address As String
Public Property address() As String
Get
Return _address
End Get
Set(ByVal value As String)
_address = value
End Set
End Property
End Class
- josn转化成实体类工具类
'json 转化成实体类
Public Shared Function JsonToObj(Of T)(ByVal JsonStr As String) As T
If JsonStr <> "" Then
Dim JsonObj As T
Try
'json对象是list
Dim ret As JArray = JArray.Parse(JsonStr)
'如果josn是单个的可以用下面方法
'Dim retObj As JObject = JObject.Parse(JsonStr)
JsonObj = ret.ToObject(GetType(T))
Return JsonObj
Catch ex As Exception
Return JsonObj
End Try
End If
End Function
注释:
Imports System.Runtime.Serialization.Json
DataContractJsonSerializer
json转化成实体类 以上方法也可以使用但是在项目中 第三方系统返回json在解析过程中包含xml转成的 string会有报错
后来使用 Newtonsoft.Json.Linq 才解决了报错问题
- 测试方法
Private Sub TestJson()
Dim jsonStr As String = "[{'name':'张三','age':'18','address':'河南'},{'name':'李四', 'age':'28', 'address':'洛阳'}]"
Dim list As List(Of TestDtoChS) = TestUtil.JsonToObj(Of List(Of TestDtoChS))(jsonStr)
Dim test As New TestDtoChS
For Each test In list
Dim name As String = test.name
Dim age As String = test.age
Dim address As String = test.address
Next
End Sub
Http请求
以上方法组成xml后需要通过http把xml推送给第三方系统
具体方法如下:
''' <summary>
''' http请求 post
''' </summary>
''' <param name="url"></param>
''' <param name="cusData"></param>
''' <returns></returns>
Public Shared Function PostData(ByRef url As String, ByRef cusData As String) As String
ServicePointManager.Expect100Continue = False
Dim req As HttpWebRequest = WebRequest.Create(url)
'post请求方式
req.Method = "POST"
'内容类型
req.ContentType = "application/json"
req.AllowAutoRedirect = False
'将URL编码后的字符转转化为字节
Dim data As Byte() = Encoding.UTF8.GetBytes(cusData)
'设备请求contentLength
req.ContentLength = data.Length
'获取请求流
Dim reqStream As Stream = req.GetRequestStream
reqStream.Write(data, 0, data.Length)
reqStream.Close()
'获得响应流
Dim resp As HttpWebResponse = req.GetResponse
Dim stream As Stream = resp.GetResponseStream
Dim reader As StreamReader = New StreamReader(stream, Encoding.UTF8)
Dim result As String = ""
result = reader.ReadToEnd
Return result
End Function