hBifTs

山自高兮水自深!當塵霧消散,唯事實留傳.荣辱不惊, 看庭前花开花落; 去留随意, 望天上云展云舒.
posts - 82, comments - 442, trackbacks - 38, articles - 27

导航

公告

Infopath Cookies(1)

Posted on 2005-05-26 22:00 hbiftsaa 阅读(...) 评论(...) 编辑 收藏
前一段时间做Office开发,用到了Biztalk和Infopath...
如前文( 在Biztalk中使用Log功能:)  ) 所提到的,Biztalk直是太强大了...
而且,后面和别人的聊天中得知,Biztalk的强大在于他可以很方便的把各种异构的环境进行统一,整合.
这对于企业的开发特别重要...谁都不想自己以前的投资一下就没了(打水漂了,完全重来)...
只是可惜,Biztalk的版本才是2004,即刚刚出来只有一年的时间,按M$的习惯,相关的文档是少之又少.....学习的难度比较高...

在使用Biztalk开发的时候,一般情况下面,它是直接可以把Hws等服务发布成WebService.那么调用就直接可以通过ASP.NET或是WinForm调用Web Service使用了...

不过,M$在Office2003中加入了一个新的产品-Infopath. 想必很多人都知道这个东西的...(但是,真正用过的,又有多少呢?.呵呵)

Infopath的表单,本质上就是一个XML文档,使用特定的XSLT进行显示,通过JScript进行交互...通过Infopath内置的功能,可以很轻松的实现WebService的调用(这个是Infopath最大的优点之一).同时,由于这个特性,Infopath在一些场合下面完全可以代替ASP.NET页面.
Infopath开发方便,直接调用WS,不用像ASP.NET一样写过多的代码.直接的结果就是开发成本降低(你不用去理会什么ViewState之类了的),同时也能减少开发周期(直接拖控件,直接就可以和数据源进行绑定)...


现在说几个Infopath开发的Cookie:

1.手动调用设计时加入的WebService.
           在使用Infopath设计器时,我们是可以直接加入WebService的引用的(通过 工具->辅助数据源 进行添加),在添加后,我们可以选中文档打开时调用...但是,一般情况下面,我们大都不会把所有的WebService在文档打开的时间进行调用的.所以我们需要一种在其它的时候调用WebService的方法:

对于每加入的一个数据源,都会在 XDocument.DataObjects 中增加一个Object.通过此Object的Query()函数,我们就可以手动调用WebService了.
比如调用GetTaskInfo 这个WebService:
XDocument.DataObjects.Item('GetTaskInfo').Query()

当然了,我们可能得给这个WebService传参数,或得到其返回值..
为了操作,我们先加入WebService的引用(如上面的GetTaskInfo),然后提取表单文件.提取后的文件里面,我们可以找到GetTaskInfo.xml GetTaskInfo1.xsd等文件.这里的GetTaskInfo.xml就是我们调用此WebService时传递的Soap的xml结构.打开这个文件,我们可以看到如下的结构:
<dfs:myFields xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" xmlns:ns7="http://microsoft.com/Biztalk2004/Hws/Hwsservice"><dfs:queryFields><ns7:GetTaskInfo><ns7:taskID></ns7:taskID></ns7:GetTaskInfo></dfs:queryFields><dfs:dataFields><ns7:GetTaskInfoResponse><ns7:Task></ns7:Task></ns7:GetTaskInfoResponse></dfs:dataFields></dfs:myFields>
其中,<dfs:queryFields/>中的<ns7:GetTaskInfo><ns7:taskID/></ns7:GetTaskInfo>就是此WebService的参数.
<dfs:dataFields>中的就是返回值了.
即,我们只要在调用WebService前把这个文件中的<dfs:queryFields>填入参数,调用后从<dfs:dataFields>取回返回值就OK了...
Come on. Let's go!
代码:
     var oAuxDom = XDocument.GetDOM('GetTaskInfo');
     oAuxDom.setProperty(
"SelectionNamespaces", 'xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" xmlns:ns7="http://microsoft.com/Biztalk2004/Hws/Hwsservice');
     oAuxDom.selectSingleNode(
"/dfs:myFields/dfs:queryFields/ns7:GetTaskInfo/ns7:taskID").text=taskID;
     XDocument.DataObjects.Item('GetTaskInfo').Query();
     var propertyNode;
     var returnTask = oAuxDom.selectNodes(
"/dfs:myFields/dfs:dataFields/ns7:GetTaskInfoResponse/ns7:Task");

returnTask就是此WebService的返回值了...此WebService的调用就Over了~

2.动态修改WebService的调用地址:
  在Infopath设计的过程中,我们可以直接添加WebService的地址.非常方便.但是在布署的时候会有问题.因为布署时的WebService安装的机器是不确定的.如果WebService的地址每改一次就要重设计一次Infopath,那不是太麻烦了:(
这里,我们还是得用到XDocument.DataObjects这个对象了~
同上面的,我们把提取表单文件.关闭Infopath,用Notepad打开mainifest.xsf文件.
我们可以在里面找到类似这样的代码:
    <xsf:dataObjects>
        
<xsf:dataObject name="GetTaskInfo" schema="GetTaskInfo.xsd" initOnLoad="no">
            
<xsf:query>
                
<xsf:webServiceAdapter wsdlUrl="http://localhost/HwsService/HwsService.asmx?WSDL" queryAllowed="yes" submitAllowed="no">
                    
<xsf:operation name="GetTaskInfo" soapAction="http://microsoft.com/Biztalk2004/Hws/Hwsservice/GetTaskInfo" serviceUrl="http://localhost/HwsService/HwsService.asmx">
                        
<xsf:input source="GetTaskInfo.xml"></xsf:input>
                    
</xsf:operation>
                
</xsf:webServiceAdapter>
            
</xsf:query>
        
</xsf:dataObject>
        .
    
</xsf:dataObjects>
看到了没有,这就是一个DataObjects,里面有一个名叫GetTaskInfo的DataObject,是不是和上面的那个GetTaskInfo的DataObject很像?都有一个Query?
嗯.这个就是上面的那个XDocument.DataObjects.Item("GetTaskInfo")对象...既然这样,都是XMLNode.那么就有办法可以修改WebService的地址了:)
示例代码:
   var wsObj = XDocument.DataObjects.Item('GetTaskInfo');
   
var url = "you new ws address.";
   
var objOperation = new ActiveXObject("MSXML.DOMdocument");
   objOperation.async 
= false;
   objOperation.validateOnParse 
= false;
   objOperation.loadXML(wsObj.QueryAdapter.Operation);
   objOperation.selectSingleNode(
"//xsf:operation/@serviceUrl").text = url;
   object.QueryAdapter.Operation 
= objOperation.xml;
这样,我们只要在调用Query()函数前先调用这个语句,就可以动态修改WebService的地址了~

呵呵,不要问我怎么得到那个Url啊...简单啊,在最前面放一个TextBox,让用户自己去填.或是直接使用JScript访问注册表,从注册表中得到Url(可以试试,我没试过).


大家一起来Infopath...