在上篇的web自定义表单集成协同办公管理平台中提到web自定义表单开发工具已经成为协同产品继工作流之后的核心组件。在协同产品中web自定义表单开发工具的价值主要体现在:1、解决协同产品的通用性和用户需求个性化的矛盾;2、为异构系统提供数据展现的接口。
第一个价值点很好理解,就是客户可以在协同平台的基础上用web自定义表单开发工具开发业务表单,并绑定好企业的业务流程实现个性化的协同应用,固化组织的管理规范,更重要的保障了管理规范的有效执行,提升组织执行力。第二个价值点体现在既然是协同办公平台就需要和其他异构业务系统进行数据整合。在web自定义开发工具中与异构业务系统的数据整合分为两种:一种是业务系统提供访问数据库的连接,在web自定义表单工具中通过数据库连接直接访问业务系统的数据库实现数据的提取。这种方式在数据安全方面有一定的问题,客户一般不接受这种方式。第二种就是业务系统提供webservice接口,在web自定义开发工具中直接调用并接收返回数据显示。调用webservice的接口在web自定义开发工具中提供了两种接口,下面用示例演示调用的方法。
1、 用JS调用WebService,用JS调用WebService的方法比较简单,首先封装了一个JS调用WebService的方法,然后在设计表单时可以直接调用即可。下面是用Js调用WebService的表单实现过程。
步骤一:新建一个简单的web自定义表单,在表单中增加一个button,自定义button的点击事件函数,在函数中调用封装好的JS调用WebService的方法,并用提示信息查 看WebService的返回值。
步骤二:运行表单查看结果。
附:JS调用WebService的方法:
2 * @func 通过JS调用webservice并接收返回XML数据
3 * @param url 调用webservice的url路径
4 * var url = "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx";
5 * @param methodname webservice的方法名
6 * var methodname = "getRegionDataset";
7 * @param args 参数列表,多个参数以“,”分隔
8 * var args = "";
9 * @param argnames webservice的方法的变量名,多个变量以","分割
10 * var argnames = "";
11 * @param _namespace 命名空间
12 * var _namespace = "http://WebXml.com.cn/";
13 **/
14 function GetXmlByWebServiceForJs(url,methodname,argnames,args,_namespace)
15 {
16 var xmlhttp = createXMLHttpRequest();
17 var data;
18 data = '<?xml version="1.0" encoding="utf-8"?>';
19 data = data + '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">';
20 data = data + '<soap:Body>';
21 data = data + '<'+methodname+' xmlns="'+_namespace+'">';
22 if (args != "")
23 {
24 var arr = args.split(",");
25 var arr1 = argnames.split(",");
26 for(var i=0;i<arr.length;i++)
27 {
28 data = data + '<'+arr1[i]+'><![CDATA['+arr[i]+']]></'+arr1[i]+'>';
29 }
30 }
31 data = data + '</'+methodname+'>';
32 data = data + '</soap:Body>';
33 data = data + '</soap:Envelope>';
34
35 xmlhttp.Open("POST",url, false);
36 xmlhttp.SetRequestHeader ("Content-Type","text/xml; charset=utf-8");
37 xmlhttp.SetRequestHeader ("Content-Length",getlen(data));
38 xmlhttp.SetRequestHeader ("SOAPAction",_namespace+methodname);
39 xmlhttp.Send(data);
40
41 return xmlhttp.responseText;
42 }
43
44 //Create XMLHttpRequest Object
45 function createXMLHttpRequest()
46 {
47 var xmlhttp;
48 if(window.ActiveXObject)
49 {
50 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
51 }
52 else if(window.XMLHttpRequst)
53 {
54 xmlhttp=new XMLHttpRequest();
55 }
56 return xmlhttp;
57 }
58
59 //Get Request Data's length
60 function getlen(str)
61 {
62 var bytesCount=0;
63 for (var i = 0; i < str.length; i++)
64 {
65 var c = str.charAt(i);
66 if (/^[\u0000-\u00ff]$/.test(c)) //匹配双字节
67 {
68 bytesCount += 1;
69 }
70 else
71 {
72 bytesCount += 2;
73 }
74 }
75 return bytesCount;
76
77 }
2、 动态调用WebService,以前调用WebService的时候都是直接添加引用的方式,然后调用服务端的方法,而web自定义表单设计初衷是表单设计后不用编译直接运行。查找相关资料后整理了动态调用WebService的方法,表单设计时直接调用并接收返回结构。
设计思路:
具体实现步骤:
步骤一:参照JS调用WebService的表单设计过程。
步骤二:运行表单查看结果。
附:WebServiceHelper.cs类代码:
2 {
3 #region InvokeWebService
4
5 /// <summary>
6 /// 动态调用web服务
7 /// </summary>
8 /// <param name="url">URL</param>
9 /// <param name="methodname">方法名</param>
10 /// <param name="args">参数</param>
11 /// <returns>object</returns>
12 public static object InvokeWebService(string url, string methodname, object[] args)
13 {
14 return WebServiceHelper.InvokeWebService(url, null, methodname, args);
15 }
16
17 /// <summary>
18 /// 动态调用web服务
19 /// </summary>
20 /// <param name="url">URL地址</param>
21 /// <param name="classname">类名</param>
22 /// <param name="methodname">方法名</param>
23 /// <param name="args">方法参数</param>
24 /// <returns>方法返回值</returns>
25 public static object InvokeWebService(string url, string classname, string methodname, object[] args)
26 {
27 string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling";
28
29 if ((classname == null) || (classname == ""))
30 {
31 classname = WebServiceHelper.GetWsClassName(url);
32 }
33
34 try
35 {
36 //获取WSDL
37 WebClient wc = new WebClient();
38 IWebProxy proxy = WebRequest.GetSystemWebProxy();
39 proxy.Credentials = CredentialCache.DefaultCredentials;
40 wc.Proxy = proxy;
41
42 Stream stream = wc.OpenRead(url + "?WSDL");
43 ServiceDescription sd = ServiceDescription.Read(stream);
44 ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
45
46 sdi.ProtocolName = "Soap"; //指定访问协议。
47 sdi.Style = ServiceDescriptionImportStyle.Client; //生成客户端代理。
48 sdi.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;
49
50
51 sdi.AddServiceDescription(sd, "", "");
52 CodeNamespace cn = new CodeNamespace(@namespace);
53
54 //生成客户端代理类代码
55 CodeCompileUnit ccu = new CodeCompileUnit();
56 ccu.Namespaces.Add(cn);
57 sdi.Import(cn, ccu);
58 CSharpCodeProvider csc = new CSharpCodeProvider();
59
60 ICodeCompiler icc = csc.CreateCompiler();
61 //设定编译参数
62 CompilerParameters cplist = new CompilerParameters();
63 cplist.GenerateExecutable = false;
64 cplist.GenerateInMemory = true;
65 cplist.ReferencedAssemblies.Add("System.dll");
66 cplist.ReferencedAssemblies.Add("System.XML.dll");
67 cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
68 cplist.ReferencedAssemblies.Add("System.Data.dll");
69
70 //编译代理类
71 CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
72 //CompilerResults cr = csc.CompileAssemblyFromDom(cplist, ccu);
73
74 if (true == cr.Errors.HasErrors)
75 {
76 System.Text.StringBuilder sb = new System.Text.StringBuilder();
77
78 foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
79 {
80 sb.Append(ce.ToString());
81 sb.Append(System.Environment.NewLine);
82 }
83
84 throw new Exception(sb.ToString());
85 }
86
87 //生成代理实例,并调用方法
88 System.Reflection.Assembly assembly = cr.CompiledAssembly;
89 Type t = assembly.GetType(@namespace + "." + classname, true, true);
90 object obj = Activator.CreateInstance(t);
91 System.Reflection.MethodInfo mi = t.GetMethod(methodname);
92 ParameterInfo[] pars = mi.GetParameters();
93 for (int i = 0; i < pars.Length; i++)
94 {
95 if (args[i].GetType().Name != pars[i].ParameterType.Name)
96 {
97 args[i] = Convert.ChangeType((object)args[i], pars[i].ParameterType);
98 }
99 }
100
101 return mi.Invoke(obj, args);
102 }
103 catch (Exception ex)
104 {
105 return "Error-" + ex.Message + ex.InnerException.Message;
106 }
107
108
109 }
110
111 /// <summary>
112 /// GetWsClassName
113 /// </summary>
114 /// <param name="strUrl">URL</param>
115 /// <returns>ClassName</returns>
116 private static string GetWsClassName(string strUrl)
117 {
118 string[] parts = strUrl.Split('/');
119 string[] pps = parts[parts.Length - 1].Split('.');
120 return pps[0];
121 }
122 #endregion
123 }