Soap技术在Windows应用程序开发中的应用B/S与C/S混合模式开发[草稿]

本文探讨了B/S和C/S架构各自的局限性,并提出了一种结合两者优势的混合架构解决方案。通过WinForm发送XML请求到WebService,再由WebService通过HttpPost调用aspx等页面处理请求,最终实现高效灵活的数据交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SOAP(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交换信息的简单的协议,是一个基于XML的协议。它包括四个部分:SOAP封装(envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架;SOAP编码规则(encoding rules),用于表示应用程序需要使用的数据类型的实例; SOAP RPC表示(RPC representation),表示远程过程调用和应答的协定;SOAP绑定(binding),使用底层协议交换信息。
  
  虽然这四个部分都作为SOAP的一部分,作为一个整体定义的,但他们在功能上是相交的、彼此独立的。特别的,信封和编码规则是被定义在不同的XML命名空间(namespace)中,这样使得定义更加简单。

B/S架构的软件,客户端对数据流的处理能力较弱,C/S架构的软件,又在数据库的集中处理上有点不不方便,尤其是,业务逻辑层有改变时,得重新安装客户端软件。

针对B/S和C/S的不足,笔者在开发中,尝试采用B/S + C/S混合模式开发,受益多多。现在拿出来与大家一起分享。

整个系统结构如下:

[WinForm] ---------XML Request------>Webservice -------Http Post---->[aspx/php/jsp/cgi] ----DB(MSSQL2000/2005)

在整个系统运作中,WebService 起到中间桥梁作用。它负责把WinForm的Xml请求包解析,然后调用相应的aspx页面进行处理。

WinForm ------ 界面层

aspx/php/jsp/cgi ---- 业务处理层

DB -----数据库实体

Request XML 协议介绍

<Form Name=[FormName] ID=[FormID] Action=[URL]Method=[Method]>
<Descript>
<!-- 表单头部说明 -->
</Descript>
<DATA>
<! 表单数据区 -->
<Item Name=[ItemName] ID=[ItemID]/>
<DATA>

</Form>

在我们的1.0Request XML 规范中,我们把界面层传递到WebService层的数据分为2类,1种是描述(Descript)类数据,1种是数据(DATA)类数据。

Name :提供WebService 进行数据识别,ID 与 Name相同,主要是考虑name重名的问题

Action : URL ,对该请求包,进行分析处理的aspx页面(也可以php/jsp/cgi)等

Method:等价于Html的 Post / Get

业务处理层数据处理原理

以aspx为例:

<%@ Page Language="C#" ValidateRequest="false" %>

<%

string xmlDescript;
string xmlData;

System.Xml.XmlDocument xd_Descript = new System.Xml.XmlDocument();
System.Xml.XmlDocument xd_Data = new System.Xml.XmlDocument(); //表单数据体

bool b_Descript_Request = false;
bool b_Data_Request = false;

bool b_xml_Descript = false;
bool b_xml_Data = false;


System.Text.StringBuilder sb = new StringBuilder();

sb.Append("<Return>");
sb.Append("<Time>" + System.DateTime.Now.ToLongDateString() + "</Time>");
try
{

xmlDescript = Request.Form["Descript"].ToString(); //表单描述部分

b_Descript_Request = true; //描述体 请求成功

xmlData = Request.Form["Data"].ToString();
b_Data_Request = true; //数据体 请求成功

xd_Descript.LoadXml(xmlDescript);
b_xml_Descript = true;

xd_Data.LoadXml(xmlData);
b_xml_Data = true;
}
catch (Exception ex)
{
sb.Append("<Error><![CDATA[" + ex.Message.ToString() + "]]></Error>");
}

sb.Append("<DescriptRequest>" + b_Descript_Request.ToString() + "</DescriptRequest>");
sb.Append("<DataRequest>" + b_Data_Request.ToString() + "</DataRequest>");
sb.Append("<DescriptXml>" + b_xml_Descript.ToString() + "</DescriptXml>");
sb.Append("<DataXml>" + b_xml_Data.ToString() + "</DataXml>");

sb.Append("</Return>");
Response.Write(sb.ToString());
Response.End();

//数据返回

%>

aspx页面,接收到来自 WebService的Http请求,经过对数据的处理加工,然后通过调用asp.NET的Response方法,把处理结果重写回WebService,然后WebService再把处理的数据封装打回到WinForm。

WebService动态调用aspx/jsp/php/cgi说明

WebService根据WinForm传入的ID和URL,进行调用。

[1]URL参数为空,则自动根据ID查询 config,xml配置文件,进行URL请求

[2]URL参数不为空,直接请求

下面以我们实际开发中使用的一个配置文件,提供大家参考。

<?xml version="1.0" encoding="utf-8" ?>
<!--
YC_Webservice 配置文件 Ver 0.1
昆明永创科技有限公司版权所有(CopyRight 2008)
http://www.yunfly.com
-->

<YC_WebService>
<Request>
<Form>
<!--入库管理-->
<FormRuKuDanDo URL="http://localhost:1401/do/ItemStore/in/InStoreForm.aspx" providerName="WinForm"/>
<FormRuKuDanSearch URL="http://localhost:1401/do/ItemStore/in/Find.aspx" providerName="WinForm"/>

<!--出库管理-->
<FormChuKuDanDo URL="http://localhost:1401/do/ItemStore/out/ChuKunDan.aspx" providerName="WinForm"/>
<FormChuKuDanSearch URL="http://localhost:1401/do/ItemStore/Out/OutStoreFormQuery.aspx" providerName="WinForm"/>

<!--入库单查询-->
<!--FormChuKuDanDo URL="http://localhost/do/ItemStore/ChuKunDan.aspx" providerName="WinForm"/-->
<!--订单管理 Beging -->
<FormDDZZ URL="http://localhost:1401/do/Order/DDZZ.aspx" detail="订单制作" providerName="WinForm"/>
<FormDDXG URL="http://localhost:1401/do/Order/DDXG.aspx" detail="订单修改" providerName="WinForm"/>
<FormDDZZ URL="http://localhost:1401/do/Order/DDLL.aspx" detail="订单浏览" providerName="WinForm"/>
<FormDDCX URL="http://localhost:1401/do/Order/DDCX.aspx" detail="订单查询" providerName="WinForm"/>
<!--订单 End -->
<!--零件库存管理 Begin -->
<FormItemStoreFind URL="http://localhost:1401/do/ItemStore/ItemStoreSearch.aspx?act=find" detail="零件库存查询" providerName="WinForm"/>
<FormItemInventoryChecks_Get URL="http://localhost:1401/do/ItemStore/ItemInventoryChecks.aspx?act=get" detail="库存盘点" providerName="WinForm"/>
<FormItemInventoryChecks_Set URL="http://localhost:1401/do/ItemStore/ItemInventoryChecks.aspx?act=set" detail="库存盘点" providerName="WinForm"/>
<!--零件库存管理 End -->


<!--模型管理 Begin-->
<FormNewComponent URL="http://localhost:1401/do/Moduel/Model_Component.aspx?act=new" detail="新建组件模型"/>
<FormNewComponent_SET URL="http://localhost:1401/do/Moduel/Model_Component.aspx?act=set" detail="修改组件模型"/>

<!--模型管理 End-->

</Form>
<Action>
<!--公共数据检索部分 Begin-->
<ACT_Product_IndexOf URL="http://localhost:1401/do/Action/ACT_Product_IndexOf.aspx" detail="产品检索"/>
<ACT_Supplier_Get URL="http://localhost:1401/do/Action/ACT_Supplier.aspx?act=get" detail="供应商信息"/>
<ACT_Supplier_Set URL="http://localhost:1401/do/Action/ACT_Supplier.aspx?act=set" detail="供应商信息"/>
<ACT_Supplier_New URL="http://localhost:1401/do/Action/ACT_Supplier.aspx?act=new" detail="供应商信息"/>
<ACT_Supplier_Del URL="http://localhost:1401/do/Action/ACT_Supplier.aspx?act=del" detail="供应商信息"/>
<ACT_Order_Get URL="http://localhost:1401/do/OrderIDSearch.aspx" detail="订单检索"/>
<ACT_Client_Get URL="http://localhost:1401/do/Action/ACT_Client.aspx?act=get" detail="客户信息"/>
<ACT_Client_Set URL="http://localhost:1401/do/Action/ACT_Client.aspx?act=set" detail="客户信息"/>
<ACT_Client_New URL="http://localhost:1401/do/Action/ACT_Client.aspx?act=new" detail="客户信息"/>
<ACT_Client_Del URL="http://localhost:1401/do/Action/ACT_Client.aspx?act=del" detail="客户信息"/>
<ACT_Item_IndexOf URL="http://localhost:1401/do/ItemStore/ItemStoreSearch.aspx?act=get" detail="零件检索"/>
<ACT_Supplier_Search URL="http://localhost:1401/do/Action/ACT_Supplier.aspx?act=search" detail="供应商信息"/>
<ACT_Client_Search URL="http://localhost:1401/do/Action/ACT_Client.aspx?act=search" detail="客户信息"/>
<!--公共数据检索部分 End-->
<!--系统注册信息Begin-->
<ACT_CompanyInforGet URL="http://localhost:1401/do/Action/ACT_CompanyInfor.aspx?act=get" detail="注册信息查询"/>
<ACT_CompanyInforSet URL="http://localhost:1401/do/Action/ACT_CompanyInfor.aspx?act=set" detail="注册信息修改"/>
<!--系统注册信息End-->
<!--模型操作 Begin-->
<ACT_Component_Get URL="http://localhost:1401/do/Moduel/Model_Component.aspx?act=get" detail="组件模型"/>
<ACT_Component_Del URL="http://localhost:1401/do/Moduel/Model_Component.aspx?act=del" detail="删除组件模型"/>
<ACT_Product_Get URL="http://localhost:1401/do/Moduel/Model_Product.aspx?act=get" detail="整车模型"/>
<!--模型操作 End-->

<DeleteDingDan URl="http://" providerName="WinForm"/>

<!--序列号 获取 Begin-->

<ACT_GET_DD_ID URL="http://localhost:1401/do/sys/GetSnNumberID.aspx?SeedType=101&amp;firstName=DD" detail="获取订单单号"/>
<ACT_GET_CG_ID URL="http://localhost:1401/do/sys/GetSnNumberID.aspx?SeedType=102&amp;firstName=CG" detail="获取采购单号"/>
<ACT_GET_RK_ID URL="http://localhost:1401/do/sys/GetSnNumberID.aspx?SeedType=103&amp;firstName=RK" detail="获取入库单号"/>
<ACT_GET_CK_ID URL="http://localhost:1401/do/sys/GetSnNumberID.aspx?SeedType=104&amp;firstName=CK" detail="获取出库单号"/>
<ACT_GET_XS_ID URL="http://localhost:1401/do/sys/GetSnNumberID.aspx?SeedType=105&amp;firstName=XS" detail="获取销售单号"/>


<!--序列号 获取 End-->

</Action>
</Request>
<Response>

</Response>
</YC_WebService>

如何在WebService 中调用一个aspx页面呢?这也许是一个大家所关心的话题。下面给出一段代码大家参考。我想大家一看就会明白的。

public string HttpPost(string strURL, string paraUrlCoded)
{
StringBuilder sb = new StringBuilder();

XmlDocument xd = new XmlDocument();

System.Net.HttpWebRequest request;
request = (System.Net.HttpWebRequest)WebRequest.Create(strURL);
request.Method = "POST";//Post请求方式
request.ContentType = "application/x-www-form-urlencoded";//内容类型

/*
//参数经过URL编码
string paraUrlCoded = System.Web.HttpUtility.UrlEncode("UserName");
paraUrlCoded += "=" + System.Web.HttpUtility.UrlEncode("this.textBox2.Text");
//
paraUrlCoded += "&" + System.Web.HttpUtility.UrlEncode("Password");
paraUrlCoded += "=" + System.Web.HttpUtility.UrlEncode("this.textBox3.Text");
*/

byte[] payload;
payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);//将URL编码后的字符串转化为字节
request.ContentLength = payload.Length;//设置请求的ContentLength
Stream writer = request.GetRequestStream();//获得请求流
writer.Write(payload, 0, payload.Length);//将请求参数写入流
writer.Close();//关闭请求流

// System.Net.HttpWebResponse response;
System.Net.WebResponse response;
//获得响应流
try
{
//response = (System.Net.HttpWebResponse)request.GetResponse();
response = request.GetResponse();

Stream stream = response.GetResponseStream();
xd.Load(stream);
stream.Close();//关闭流

sb.Append("<Result State=/"Succeed/">");
sb.Append(xd.OuterXml);
sb.Append("</Result>");

}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
//xd.InnerXml = "<Err>" + ex.Message + "</Err>";
sb.Append("<Result State=/"Failed/">");
sb.Append("<Error>");
sb.Append("远程服务请求失败:(<![CDATA[" + ex.Message + "]]>)");
sb.Append("</Error>");
sb.Append("</Result>");

}

return sb.ToString();
}

string strURL, ---- aspx页面调用的URL, 也可以是jsp/php/cgi 的调用路径

string paraUrlCoded --- 传递到asp/jsp/php/cgi的参数。 采用UrlEncode 重新编码。(这里和前面的 Methhod对应)

说道这里,也累了,我想大家应该可以明白整个流程了吧。(未完待续)换迎来信交流 bohegod@163.com 或登录我们的网站http://www.yunfly.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值