• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 把.Net整合進其他平臺

    發表于:2007-05-25來源:作者:點擊數: 標簽:分布式平臺合進其他.NET
    整合分布式應用程序經常是一件非常困難并且錯綜復雜的任務,即使是最富有經驗的 開發 者也可能會覺得頭疼。當應用程序在不同的操作系統以及涉及不同的程序平臺時,這個集成問題變得尤其復雜。雖然說,Web服務承諾可以減輕 程序員 完成集成任務的困難程度,但

      整合分布式應用程序經常是一件非常困難并且錯綜復雜的任務,即使是最富有經驗的開發者也可能會覺得頭疼。當應用程序在不同的操作系統以及涉及不同的程序平臺時,這個集成問題變得尤其復雜。雖然說,Web服務承諾可以減輕程序員完成集成任務的困難程度,但是也可能給程序員們帶來一些意想不到的麻煩。在這里我們將把一個ASP.Net應用程序和一個PHP Web服務連結起來,以學習一些整合分布式應用程序的方法,以及必要的應對措施,包括運行什么以及不用去做什么。

      這個Web服務在一個Apache服務器上運行,并且使用PHP開發。它從各種微軟新聞組檢索新聞摘要以及它們的關聯的文本。即使由這個服務提供的數據可以直接使用內部的.Net對象存取,但是這個服務還是將使用并提供一個連接到非.Net平臺上的不錯的演示。我們這里要討論的實例基于.Net beta 2版。

      創建一個Web服務代理

      Visual Studio.NET提供了一個出色的機制用于自動地生成可用于存取遠程Web服務的代理對像。因此,要首先嘗試使用這些函數來導入由PHP服務提供的Web服務描述語言(Web Services Description Language,WSDL)文件。 還可以使用.Net SDK的WSDL.exe命令行公用程序。不幸的是,在使用VS.Net向導導入WSDL之后,并不能成功地創建一個代理。所以我必須把導入原始的WSDL文件后由VS.Net生成的文件轉換為WSDL:

      1. 把模式域名空間從http://www.w3.org/1999/XMLSchema改成http://www.w3.org/2001/XMLSchema 然后清除所有的當WSDL導入過程中由VS.Net添加的”q”域名空間。

      2. 刪除 xmlns:tm=http://microsoft.com/wsdl/mime/textMatching/和xmlns: mime="http://schemas.xmlsoap.org/wsdl/mime/" 名字空間,因為這個應用程序中不需要包含這些。

      3. 刪除類型元素,因為原始的 WSDL文檔 并沒有包含Web服務的模式信息的指定的元素區段。

      4. 改變輸入輸出元素消息屬性值為包含tns域名空間前綴的形式:

    <portType name="nntpSoapPortType">
    <operation name="getheaders" parameterOrder="newsgroup numitems">
    <input message="tns:getheaders" />
    <output message="tns:getheadersresponse" />
    </operation>
    <operation name="getarticle" parameterOrder="newsgroup article">
    <input message="tns:getarticle" />
    <output message="tns:getarticleresponse" />
    </operation>
    </portType>

      在進行了下面的這些微小的改變,VS.Net向導能夠讀取WSDL并且自動地生成一個代理。在編譯了這個代理之后,它被包含在一個ASP.Net頁面中。然而,當這個ASP.Net頁面被執行:“ message does not have a correct SOAP root XML tag.”,這個錯誤被當作一個SOAP錯誤從Web服務中返回。為了精確地評估這個錯誤,代理調用被一個名為Proxy Trace的公用程序使用,以便代理生成SOAP包裝。這可以通過把下列代碼添加進ASP.Net頁面來實現:

      msNews.Proxy = new System.Net.WebProxy( "http://localhost:8080");

      在察看了由.Net代理生成的SOAP包裝之后,我有點奇怪為什么會返回這個錯誤,因為實際上一個相對的SOAP包裝被生成并被發送到Web服務。即使在嘗試了好幾個轉化成代理代碼之后這個錯誤依然持續。代碼段列表2顯示了從PHP Web服務返回的完整的SOAP錯誤包裝。

      在使用VS.Net中創建的代理對象的好幾個把ASP.Net頁面與PHP Web服務連結的不成功的嘗試之后,我決定從頭開始創建SOAP包裝以便執行更有效的程序調試。{起先,它看起來好像由.Net代理生成的模式域名空間可能是問題的關鍵,因為.Net使用2001模式規范而PHP服務使用的是1999版本的規范。

      然而,我把自定義的SOAP包裝改為用1999版本代替2001版本,錯誤依然存在。在嘗試了好幾個其他的小的改變之后,我決定把SOAP包裝使用的域名空間前綴和正文元素從soap (由.Net代理生成)改為SOAP - ENV,因為我看見在SOAP錯誤信息中返回了SOAP - ENV前綴。(見代碼2)這表面上看上去微不足道的改變竟解決了問題!當處理任何請求的時候,PHP服務顯然需要SOAP - ENV前綴,而拒絕不包含SOAP - ENV前綴的要求。



      創建一個自定義代理

      既然已經了解了為什么Web服務返回一個SOAP錯誤,我們就可以創建一個自定義代理來生成網服務期待的SOAP包裝。雖然創建一個自定義SOAP包裝肯定比使用一個由VS.Net或者WSDL.exe公用程序生成的SOAP包裝要花更多的時間,但是這樣做可以完全控制包裝的內容。為了開始創建自定義代理,我創建一個名為msnewsserviceproxy的包含兩個字段的新類:

    public class MSNewsServiceProxy {
    string _uri;
    string _soapAction;
    }

      uri字段保存了Web服務的位置,而_soapAction字段保存了將要使用SOAP包裝發送的SOAPAction數據頭的名稱。在MSNewsServiceProxy類之內,添加CreateSoapEnvelope (),SendSoapEnvelope ()和FilterResult ()這三個方法。這些方法生成SOAP包裝請求,把它發送到Web服務,然后過濾返回的SOAP包裝。讓我們逐一的看看每個方法。注意代碼在SOAP包裝的根元素上添加一個SOAP - ENV域名空間前綴。Web服務顯然需要這個特定的前綴,而拒絕任何不包含這個前綴的信息。因為VS.Net生成的代理發送一個soap域名空間前綴(而不是SOAP - ENV),所以它的消息被拒絕。Web服務不應該需要一個特定的域名空間前綴而為此拒絕不帶此前綴的消息,但是域名空間問題也是你必須注意要想使工作更好的完成,要執行一些看上去不{0>可思議的事情。

      在SOAP包裝被創建之后,SendSoapEnvelope ()方法(見代碼段4)使用了幾個System.Net和System.IO域名空間中的類來把這個包裝發送到Web服務中。代碼首先通過把_uri變量傳送到對象構造器來創建一個HttpWebRequest對象。其次,與這個請求相關聯的相應的Method,ContentType和Header都將被發送。然后一個StreamWriter對象和HttpWebRequest對象的請求流相關聯,SOAP包裝就被使用StreamWriter的Write ()方法寫到流中。

      從Web服務返回的SOAP包裝被HttpWebResponse對象的SendSoapEnvelope ()方法獲得。

       HttpWebResponse response = (HttpWebResponse)request.GetResponse();

      如果應答不是空值,它將被載入一個XmlTextReader,XmlTextReader被用來填充XmlDocument對象。然后從這個方法中返回XmlDocument對象。

      FilterSoapEnvelope ()方法分析SOAP應答包裝并把從Web服務中返回的數據裝入自定義代理的“消費者”使用的XmlDocument對象:

    private XmlDocument
    FilterSoapEnvelope(
    XmlDocument doc) {
    XmlDocument filterDoc =new XmlDocument();
    XmlNode result = doc.SelectSingleNode("http://results");
    XmlNode resultImport = filterDoc.ImportNode(result,true);
    filterDoc.AppendChild(resultImport);
    return filterDoc;
    }

      雖然過濾器可以使用好幾種方法執行,但是FilterSoapEnvelope ()方法依靠XPath語句可以在應答SOAP包裝中得到結果元素。

      微軟新聞組PHP Web服務展示了允許取得新聞組新聞摘要的兩種方法:getheaders ()和getmessage ()。 你可以看到如何在自定義代理類中使用這兩種方法(見代碼段5)。 注意每個方法中的代碼傳遞Web服務方法名被調用到CreateSoapEnvelope ()方法和任何使用這個方法關聯的參數。 在SOAP包裝被發送以及應答被接受之后,FilterSoapEnvelope ()方法被調用來把返回的數據加載到一個XmlDocument對象中,同樣,這個對象也是代理“消費者”使用的。


      整合PHP Web服務

      既然一個自定義代理類已經準備好被使用,那么把它整合進一個ASP.Net頁面就變得很簡單了。getHeaders ()和getMessage ()方法可以調用Web服務,存取返回的XmlDocument對象(見代碼段6和7) 在XmlDocument內的子結點中的枚舉可以顯示這些數據。 雖然許多Web服務可以很容易地使用VS.Net或者WSDL.exe創建的代理類自動地生成,但是仍然會有你需要創建自定義SOAP包裝來把.Net和其他的平臺整合起來的情況。 本文中介紹的內容以及代碼就提供了完成這個整合工作的一種方法。

      代碼段1:

    POST http://www.codecraze.com/soap/nntp.php HTTP/1.1
    User-Agent: Mozilla/4.0 (compatible;
    MSIE 6.0; MS Web Services Client Protocol 1.0.2914.16)
    Content-Type: text/xml; charset=utf-8
    SOAPAction: "http://www.codecraze.com/soap/nntp.php"
    Content-Length: 683
    Expect: 100-continue
    Connection: Keep-Alive
    Host: www.codecraze.com

    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap=
    "http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/
    encoding/"
    xmlns:tns="http://tempuri.org/"
    xmlns:types="http://tempuri.org/encodedTypes"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body
    soap:encodingStyle=
    "http://schemas.xmlsoap.org/soap/encoding/">
    <q1:getheaders xmlns:q1=
    "http://www.codecraze.com/soap/nntp.xsd">
    <newsgroup xsi:type="xsd:string">
    microsoft.public.dotnet.xml
    </newsgroup>
    <numitems xsi:type="xsd:string">15</numitems>
    </q1:getheaders>
    </soap:Body>
    </soap:Envelope>

      代碼段2:

    HTTP/1.1 200 OK
    Date: Apr, 16 Dec 2002 15:57:47 GMT
    Server: Apache/1.3.20 (Unix) ApacheJServ/1.1.2 PHP/
    4.0.4pl1 FrontPage/5.0.2.2510 Rewrit/1.1a
    X-Powered-By: PHP/4.0.4pl1
    Content-Length: 419
    Keep-Alive: timeout=15, max=100
    Connection: Keep-Alive
    Content-Type: text/xml; charset="utf-8"

    <?xml version="1.0" encoding="utf-8"?>
    <SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/
    envelope/"
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/
    soap/encoding/">
    <SOAP-ENV:Body>
    <SOAP-ENV:Fault>
    <faultcode>SOAP-ENV:Client.SOAPMessageFormat</
    faultcode>
    <faultstring>
    message does not have a correct SOAP root XML tag
    </faultstring>
    </SOAP-ENV:Fault>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

      代碼段3 :

    private string CreateSoapEnvelope(
    string method,string[] param1,
    string[] param2) {
    StringBuilder sb = new StringBuilder();
    sb.Append("<SOAP-ENV:Envelope");
    sb.Append(" xmlns:SOAP-" +
    "ENV=\"http://schemas.xmlsoap.org/soap/
    envelope/\"");
    sb.Append(" xmlns:xsi=
    \"http://www.w3.org/1999/XMLSchema-" +
    instance\"");
    sb.Append(" xmlns:xsd=
    \"http://www.w3.org/1999/XMLSchema\">");
    sb.Append("<SOAP-ENV:Body>");
    sb.Append("<m:" + method + " xmlns:m=\"nntp.xsd\">");
    sb.Append("<" + param1[0] + ">" + param1[1] +
    "</" + param1[0] + ">");
    sb.Append("<" + param2[0] + ">" + param2[1] +
    "</" + param2[0] + ">");
    sb.Append("</m:" + method + ">");
    sb.Append("</SOAP-ENV:Body>");
    sb.Append("</SOAP-ENV:Envelope>");
    return sb.ToString();
    }

      代碼段4:

    private XmlDocument SendSoapEnvelope(string soapEnv) {
    HttpWebRequest request =
    (HttpWebRequest)WebRequest.Create(_uri);
    XmlTextReader xmlReader = null;
    XmlDocument xmlDoc = null;
    request.Method = "POST";
    request.ContentType = "text/xml";
    request.Headers.Add("SOAPAction",_soapAction);
    StreamWriter writer = new StreamWriter(
    request.GetRequestStream());
    writer.Write(soapEnv);
    writer.Close();
    HttpWebResponse response =
    (HttpWebResponse)request.GetResponse();

    if (response != null) {
    xmlReader = new XmlTextReader(
    response.GetResponseStream());
    xmlDoc = new XmlDocument();
    xmlDoc.Load(xmlReader);
    return xmlDoc;
    } else {
    return xmlDoc;
    }
    }

      代碼段5:

    public XmlDocument getHeaders(string newsgroup,
    string numitems) {
    string soapEnv = CreateSoapEnvelope("getheaders",
    new string[2]{"newsgroup",newsgroup},
    new string[2]{"numitems",numitems});
    return FilterSoapEnvelope(SendSoapEnvelope(soapEnv));
    }

    public XmlDocument getMessage(string newsgroup,
    string article) {
    string soapEnv = CreateSoapEnvelope("getmessage",
    new string[2]{"newsgroup",newsgroup},
    new string[2]{"article",article});
    return FilterSoapEnvelope(SendSoapEnvelope(soapEnv));
    }

      代碼段6:

    private void Page_Load(object sender, System.EventArgs e)
    {
    StringBuilder sb = new StringBuilder();
    try {
    MSNewsService.MSNewsServiceProxy news =
    new MSNewsService.MSNewsServiceProxy();
    XmlDocument newsHeaders =
    news.getHeaders("microsoft.public.dotnet.xml",
    "15");
    sb.Append("<ul>");
    foreach (XmlNode node in
    newsHeaders.DocumentElement.ChildNodes) {
    sb.Append("<li><a href=\"JavaScript:readArticle(
    '" + node.FirstChild.InnerText + "','" +
    node.ChildNodes.Item(1).InnerText +
    "')\">" + node.ChildNodes.Item(1).InnerText +
    "</a></li>");
    }
    sb.Append("<ul>");
    lblMessages.Text = sb.ToString();
    }
    catch (Exception exp) {
    lblMessages.Text =
    "The Web Service appears to be" + " unavailable";
    }
    }

      代碼MSNewsServiceProxy.cs:

    using System.Net;
    using System.Xml;
    using System.IO;
    using System.Text;
    namespace MSNewsService {

    public class MSNewsServiceProxy {
    string _uri;
    string _soapAction;

    public MSNewsServiceProxy() {
    _uri = "http://www.codecraze.com/soap/nntp.php";
    _soapAction = "http://www.codecraze.com/soap/nntp.php";
    }

    private XmlDocument SendSoapEnvelope(string soapEnv) {
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_uri);
    XmlTextReader xmlReader = null;
    XmlDocument xmlDoc = null;
    request.Method = "POST";
    request.ContentType = "text/xml";
    request.Headers.Add("SOAPAction",_soapAction);
    StreamWriter writer = new StreamWriter(request.GetRequestStream());
    writer.Write(soapEnv);
    writer.Close();
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    if (response != null) {
    xmlReader = new XmlTextReader(response.GetResponseStream());
    xmlDoc = new XmlDocument();
    xmlDoc.Load(xmlReader);
    return xmlDoc;
    } else {
    return xmlDoc;
    }
    }
    private string CreateSoapEnvelope(string method,string[] param1, string[] param2) {
    StringBuilder sb = new StringBuilder();
    sb.Append("<SOAP-ENV:Envelope");
    sb.Append(" xmlns:SOAP-" +
    "ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"");
    sb.Append(" xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-" +
    "instance\"");
    sb.Append(" xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\">");
    sb.Append("<SOAP-ENV:Body>");
    sb.Append("<m:" + method + " xmlns:m=\"nntp.xsd\">");
    sb.Append("<" + param1[0] + ">" + param1[1] + "</" + param1[0] + ">");
    sb.Append("<" + param2[0] + ">" + param2[1] + "</" + param2[0] + ">");
    sb.Append("</m:" + method + ">");
    sb.Append("</SOAP-ENV:Body>");
    sb.Append("</SOAP-ENV:Envelope>");
    return sb.ToString();
    }

    public XmlDocument getHeaders(string newsgroup,string numitems) {
    string soapEnv = CreateSoapEnvelope("getheaders",
    new string[2]{"newsgroup",newsgroup},
    new string[2]{"numitems",numitems});
    return FilterSoapEnvelope(SendSoapEnvelope(soapEnv));
    }
    public XmlDocument getMessage(string newsgroup,string article) {
    string soapEnv = CreateSoapEnvelope("getmessage",
    new string[2]{"newsgroup",newsgroup},
    new string[2]{"article",article});
    return FilterSoapEnvelope(SendSoapEnvelope(soapEnv));
    }

    private XmlDocument FilterSoapEnvelope(XmlDocument doc) {
    XmlDocument filterDoc = new XmlDocument();
    XmlNode result = doc.SelectSingleNode("http://results");
    XmlNode resultImport = filterDoc.ImportNode(result,true);
    filterDoc.AppendChild(resultImport);
    return filterDoc;
    }

    }
    }

      代碼msNewsClient.aspx.cs

    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.SessionState;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.Xml;
    using System.Text;

    namespace MSNewsService
    {

    public class MSNewsServiceClient : System.Web.UI.Page
    {
    protected System.Web.UI.WebControls.Label lblMessages;

    public MSNewsServiceClient()
    {
    Page.Init += new System.EventHandler(Page_Init);
    }

    private void Page_Load(object sender, System.EventArgs e) {
    StringBuilder sb = new StringBuilder();
    try {
    MSNewsService.MSNewsServiceProxy news = new MSNewsService.MSNewsServiceProxy();
    XmlDocument newsHeaders = news.getHeaders("microsoft.public.dotnet.xml","15");
    sb.Append("<ul>");
    foreach (XmlNode node in newsHeaders.DocumentElement.ChildNodes) {
    sb.Append("<li><a href=\"JavaScript:readArticle('" + node.FirstChild.InnerText +
    "','" + node.ChildNodes.Item(1).InnerText +
    "')\">" + node.ChildNodes.Item(1).InnerText + "</a></li>");
    }
    sb.Append("<ul>");
    lblMessages.Text = sb.ToString();
    }
    catch (Exception exp) {
    lblMessages.Text = "The Web Service appears to be unavailable";
    }
    }

    private void Page_Init(object sender, EventArgs e)
    {

    InitializeComponent();
    }


    private void InitializeComponent()
    {
    this.Load += new System.EventHandler(this.Page_Load);

    }

    }
    }

      代碼msNewsMessage.aspx

    <%@ Page language="c#" src="msNewsMessage.aspx.cs" Codebehind="msNewsMessage.aspx.cs" AutoEventWireup="false" Inherits="MSNewsService.msNewsMessage" %>
    <HTML>
    <body bgcolor="#ffffff">
    <h2>
    <asp:Label ID="lblMessageTitle" Runat="server" />
    </h2>
    <p>
    <asp:Label ID="lblMessageText" Runat="server" />
    </p>
    </body>
    </HTML>
    代碼msNewsMessage.aspx.cs
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.SessionState;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.Xml;

    namespace MSNewsService
    {

    public class msNewsMessage : System.Web.UI.Page
    {
    protected System.Web.UI.WebControls.Label lblMessageTitle;
    protected System.Web.UI.WebControls.Label lblMessageText;

    public msNewsMessage()
    {
    Page.Init += new System.EventHandler(Page_Init);
    }

    private void Page_Load(object sender, System.EventArgs e) {
    try {
    MSNewsService.MSNewsServiceProxy news = new MSNewsService.MSNewsServiceProxy();
    XmlDocument newsHeaders = news.getMessage("microsoft.public.dotnet.xml",
    Request["articleID"]);
    lblMessageTitle.Text = Request["title"];
    lblMessageText.Text = newsHeaders.FirstChild.InnerText;
    }
    catch (Exception exp) {
    lblMessageText.Text = "The Web Service appears to be unavailable";
    }
    }

    private void Page_Init(object sender, EventArgs e)
    {
    InitializeComponent();
    }


    private void InitializeComponent()
    {
    this.Load += new System.EventHandler(this.Page_Load);

    }

    }
    }

      代碼msNewsClient.apsx

    <%@ Page language="c#" src="msNewsClient.aspx.cs" Codebehind="msNewsClient.aspx.cs" AutoEventWireup="false" Inherits="MSNewsService.MSNewsServiceClient" %>
    <HTML>
    <head>
    <script language="javascript">
    function readArticle(id,title) {
    openWindow("msNewsMessage.aspx?articleID=" + id +
    "&title=" + title,500,400);
    }
    function openWindow(page,w,h) {
    window.open(page,"","status=no,width=" + w +
    ",height=" + h + ",scrollbars=yes");
    }
    </script>
    </head>
    <body bgcolor="#ffffff">
    <h2>Recent posts from: microsoft.public.dotnet.xml</h2>
    <p />
    <asp:Label ID="lblMessages" Runat="server" />
    </body>
    </HTML><0}

    原文轉自:http://www.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>