与ASP.NET网页进行交互示例
官方网站为本节内容提供了示例,下载地址:
http://www.foxtable.com/samples/UDPWeb.rar
本节的任务是设计一个简单的订单查看网页,并可以修改和删除订单明细产品。网站的数据不是直接操作数据库获取的,而是通过和Foxtable的UDPClient服务端进行通讯取得。
要实现网页和Foxtable的通讯,首先我们的先定义好通讯的格式。(虽然我们是可以把任何对象比如.Net的Datatable序列化后进行UDP的传输,但不是本节讨论的话题,自定义传输格式的控制性更好,也减少了许多不必要的冗余信息。)
本示例定义传输的字符串的格式如下:
(1)发送和返回的信息均以“%”符号开始和结束
(2)查询的字符串以大写字母“G”开头
(3)更新数据以大写字母“U”开头
(4)删除数据以大写字母“D”开头
(5)查询的返回值里主表和明细表的内容以“$”符号分割
(6)明细表的多行内容以“@”符号分割
(7)表内容多个字段名称和值以“|”符号分割
基本的原理就是网站服务器的ASP.NET程序收到客户通过网页提交的数据或命令后,通过UDP将其转给在同一台服务器的Foxtable程序,Foxtable处理完毕后将结果传给ASP.NET程序,ASP.NET再将结果呈现在客户的网页上。
不管是网页、微信、手机APP,还是任何第三方的软件,都可以通过这个方法和foxtable进行数据交互。
提示:本机程序使用UDP通讯的时候,必须使用IP“127.0.0.1”
1. 设计ASPNET网页
首先打开VS,创建一个ASP.NET网站的项目,默认就会生成一个起始页面Default.aspx。我们就在Default.aspx设计好页面的展示,如下图:
在订单编号框中输入订单编号,点击“查询”按钮,通过下面的代码获取订单内容:
result = UDPCommunication("%G|" & orderNum & "%")
然后进行内容解析:
If result IsNot Nothing Then
If result.StartsWith("%") AndAlso result.EndsWith("%") Then
Session("OrderNum") = orderNum '记录订单编号
Dim orders() As String = result.Trim("%").Split("$") '分离主表和明细
Dim orderdetails() As String = orders(0).Split("|")
txtName.Value = orderdetails(0)
txtOrderDate.Value = orderdetails(1)
txtDeliverDate.Value = orderdetails(2)
If orders.Length = 2 Then
If orders(1).StartsWith("@") AndAlso orders(1).EndsWith("@") Then
Dim detailArry() As String = orders(1).Trim("@").Split("@") '分离不同明细
For Each de As String In detailArry
Dim details() As String = de.Split("|")
Dim dr As DataRow
dr = order.NewRow()
For i As Integer = 0 To details.Length - 1
dr(i) = details(i) '定义的字段必须和返回值的字段顺序一致
Next
order.Rows.Add(dr)
Next
End If
End If
End If
End If
这里定义一个函数来和Foxtable的UDPClient进行通讯,如
Function UDPCommunication(ByVal input As String) As String
Dim udp As New System.Net.Sockets.UdpClient(0)
Dim ip As New System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 52177) '定义通讯的网络端点,地址和端口号要和和UDPClient启动时的一致
Dim bytes() As Byte = System.Text.Encoding.Unicode.GetBytes(input)
udp.Send(bytes, bytes.Length, ip) '发送数据
Dim result As String = "!false"
Dim sdt As Date = Date.Now
While Date.Now < sdt.AddSeconds(1) '等1秒
If udp.Available > 0 Then
Dim remoteIp As New System.Net.IPEndPoint(System.Net.IPAddress.Any, 0)
Dim rbytes() As Byte = udp.Receive(remoteIp)
result = System.Text.Encoding.Unicode.GetString(rbytes) '获取返回值
End If
End While
udp.Close()
Return result
End Function
比如输入订单编号31,查询完成后的页面如下:
在明细中点击删除,就可以删除一条明细,代码如下
Dim numCell As TableCell = e.Item.Cells(2)
Dim num As String = numCell.Text
Dim result As String = UDPCommunication("%D|订单编号|" & Session("OrderNum").ToString() & "|产品代码|" & num & "%")
If result = "!false" Then
p1.InnerText = "删除产品" & e.Item.Cells(3).Text & "出错!"
Else
orderView.RowFilter = "产品代码='" & num + "'"
If orderView.Count > 0 Then
orderView.Delete(0)
End If
End If
orderView.RowFilter = ""
BindGrid()
同样,编辑的情况也类似,具体参考示例的VS项目。
2. Foxtable的UDPClient服务器端设计
2.1 设计一个下图所示的窗口:
窗口中启东按钮的代码为:
If UDPClients.Count = 0 Then
UDPClients.Add("UDP1",new UDPClient("UDP1") )
End If
UDPClients("UDP1").IP = e.Form.Controls("txtIP").Value
UDPClients("UDP1").Port = e.Form.Controls("txtPort").Value
UDPClients("UDP1").Start()
2.2 在菜单的“管理项目”功能区,单击“网络监视器”,设置UDPClient的ReceivedMessage事件代码:
Dim drnew As Row = Tables("通讯记录").AddNew()
drnew("接收时间") = now
drnew("接收内容") = e.Message
Dim msg As String = e.Message
Dim ret As String = "!false"
If e.Message.StartsWith("%") AndAlso e.Message.EndsWith("%") '假定收到的信息头尾都是"%"
msg = msg.Trim("%")
Dim prefix As String = msg.SubString(0,1)
Select Case prefix
Case "G" '查询
msg = msg.TrimStart("G","|")
Dim dr As DataRow = DataTables("订单").Find("订单编号 = '" & msg & "'")
If dr IsNot Nothing Then
ret = "%" & dr("客户名称") & "|" & dr("订单日期") & "|" & dr("发货日期")'拼接主表字段内容
Dim drs As List(Of DataRow)
drs = dr.GetChildRows("订单明细")
If drs.Count > 0 Then
ret = ret & "$" '分割主表和明细
For Each dr1 As DataRow In drs
ret = ret & "@" & dr1("产品代码") & "|" & dr1("产品名称") & "|" & dr1("数量") & "|" & dr1("单位") & "|" & dr1("单价")'拼接每一行明细的字段内容,必须和网页中定义的列顺序一致
Next
ret = ret & "@"
End If
ret &= "%"
End If
Case "U" '更新
msg = msg.TrimStart("U","|")
Dim dataArray() As String = msg.Split("|")
If dataArray.Length = 8 Then
Dim dr As DataRow = DataTables("订单明细").Find( dataArray(0) & " = '" & dataArray(1) & "' and " & dataArray(2) & " = '" & dataArray(3) & "'")
If dr IsNot Nothing Then '接收的内包含列名称和列值,这样就不用判断是更新那一列
dr(dataArray(4)) = dataArray(5)
dr(dataArray(6)) = dataArray(7)
DataTables("订单明细").Save()
ret = "!true"
End If
End If
Case "D" '删除
msg = msg.TrimStart("D","|")
Dim dataArray() As String = msg.Split("|")
If dataArray.Length = 4 Then
Dim dr As DataRow = DataTables("订单明细").Find( dataArray(0) & " = '" & dataArray(1) & "' and " & dataArray(2) & " = '" & dataArray(3) & "'")
If dr IsNot Nothing Then
dr.Delete()
ret = "!true"
DataTables("订单明细").Save()
End If
End If
Case Else
End Select
drnew("发送内容") = ret
e.ReturnValue = ret
drnew("发送时间") = now
End If
drnew.Save()
代码比较简单,就不多做解释了。