2011-05-03 215 views
8

我想在CRM 2011環境中使用CRM 2011 SOAP Web服務JavaScript執行FetchXML查詢。如何使用CRM 2011 web服務和JavaScript在CRM 2011中執行FetchXML?

我發現了很多文章like this one顯示瞭如何使用仍在2011年環境中可用的4.0 web服務,但我不想這樣做。

This link似乎表明IOrganizationService.RetrieveMultiple可以處理FetchXML。但是,我不想爲此使用託管代碼。

我遇到了this link,它基本上顯示了我想要在RetrieveMultiple函數中執行的操作,但我希望能夠傳入我寫入的現有FetchXML,而不是新的過濾器表達式。

回答

7

使用JavaScript執行fetchxml查詢一堆框架/庫可供選擇:

代替手工編寫代碼的這些圖書館提供一個簡單的方法來執行幾個操作並訪問結果。但考慮到並非所有庫(當前)都支持跨瀏覽器(Q2.2012)。

+0

謝謝Thuld。我不認爲這些在我發佈我的問題時可用,但現在看起來有一些很好的選擇。 – Paul 2012-05-19 21:48:14

+0

關於3的優缺點有什麼意見?我想我應該開始使用一個,但不知道我應該考慮什麼,以決定... – keerz 2012-07-23 23:35:20

+0

好吧我是CrmFetchKit的作者,所以我更喜歡這一個:) 但是,一如既往,這取決於。 XrmServiceToolkit支持更多操作/ messags,另一方面,CrmFetchKit提供跨瀏覽器支持。 – thuld 2012-09-05 05:48:50

1

「REST是一種架構風格,其中每個資源都通過使用唯一的URI來解決。」 http://msdn.microsoft.com/en-us/library/gg334279.aspx

你將不能夠,如果你需要使用FetchXml使用REST終點。

另一種方法是按照您在CRM4示例中看到的方式構造SOAP消息。我還沒有自己做過,但也許你可以使用像Fiddler這樣的工具來查看SOAP消息是什麼樣子的,以便你可以在你修改過的FetchXml的環境中複製它們。

無論如何,現在只是一個想法。讓我知道它是怎麼回事,如果你設法解決它可能會發布你的解決方案。

+0

感謝您對REST端點的說明。一旦我找出這個問題,我一定會回覆。 – Paul 2011-05-04 06:41:44

2

this MSDN article的「捕獲示例HTTP請求和響應」部分概述瞭如何獲取從託管代碼發送到CRM 2011的SOAP消息。

this MSDN article的「執行查詢」部分給出了在託管代碼中使用2011的IOrganizationService.RetrieveMultiple來執行FetchXML查詢的示例。

使用這兩個樣本,可以提取包含FetchXML查詢的RetrieveMultiple的示例SOAP消息。

the first MSDN article的「創建JScript庫」部分顯示瞭如何針對2011 SOAP端點執行JavaScript中的執行請求。將本例中的Assign SOAP請求替換爲您從執行託管代碼獲取的RetrieveMultiple SOAP消息。

這使您能夠針對2011 SOAP端點執行JavaScript中的FetchXML請求。

下面是一個JavaScript庫,我使用上述信息寫了一些片段:

(function (window, undefined) { 
    var _window = undefined; 

    if (window.Xrm) 
     _window = window; 
    else if (window.parent.Xrm) 
     _window = window.parent; 
    else throw new Error("Unable to determine proper window"); 

    (function (Crm) { 
     (function (Service, $, JSON, Xrm) { 
      if (!Xrm) 
       throw new Error("Unable to locate Xrm"); 
      if (!JSON) 
       throw new Error("Unable to locate JSON"); 
      if (!$) 
       throw new Error("Unable to locate jQuery"); 

      Service.Create = function (ODataSetName, EntityObject) { 
       if (!EntityObject) { 
        throw new Error("EntityObject is a required parameter"); 
        return; 
       } 
       if (!ODataSetName) { 
        throw new Error("ODataSetName is a required parameter"); 
        return; 
       } 
       var jsonEntityObject = JSON.stringify(EntityObject); 

       var req = new XMLHttpRequest(); 
       req.open("POST", Service.GetODataEndPoint() + "/" + ODataSetName, false); 
       req.setRequestHeader("Accept", "application/json"); 
       req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); 
       req.onreadystatechange = function() { 
        debuggingCallBack(this); 
       }; 

       req.send(jsonEntityObject); 

      }; 
      function debuggingCallBack(req) { 
       if (req.readyState == 4 /* complete */) { 
        if (req.status == 201 || req.status == 204 || req.status == 1223) { 
         //Success 
         //201 = create 
         //204 = update 
         //1223 = delete 
        } 
        else { 
         //Failure 
         debugger; 
        } 
       } 
      }; 


      Service.Fetch = function (FetchXML) { 
       var request = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"; 
       request += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"; 
       request += "<s:Body>"; 
       request += "<RetrieveMultiple xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">"; 
       request += "<query i:type=\"a:FetchExpression\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">"; 
       request += "<a:Query>"; 
       request += Service.FetchEncode(FetchXML); 
       request += "</a:Query>"; 
       request += "</query>"; 
       request += "</RetrieveMultiple>"; 
       request += "</s:Body>"; 
       request += "</s:Envelope>"; 

       var req = new XMLHttpRequest(); 
       req.open("POST", Service.GetSOAPEndPoint(), false) 
       req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/RetrieveMultiple"); 
       req.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); 
       req.setRequestHeader("Content-Length", request.length); 
       req.send(request); 

       results = Service.GetResults(req.responseXML); 

       return results; 
      }; 
      Service.Delete = function (ODataSetName, EntityID) { 
       if (!EntityID) { 
        throw new Error("EntityID is a required parameter"); 
        return; 
       } 
       if (!ODataSetName) { 
        throw new Error("ODataSetName is a required parameter"); 
        return; 
       } 

       var req = new XMLHttpRequest(); 
       req.open("POST", Service.GetODataEndPoint() + "/" + ODataSetName + "(guid'" + EntityID + "')", false) 
       req.setRequestHeader("Accept", "application/json"); 
       req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); 
       req.setRequestHeader("X-HTTP-Method", "DELETE"); 
       req.onreadystatechange = function() { 
        debuggingCallBack(this); 
       }; 
       req.send(); 

      }; 


      Service.GetServerUrl = function() { 
       var serverUrl = null; 
       serverUrl = Xrm.Page.context.getServerUrl(); 
       if (serverUrl.match(/\/$/)) { 
        serverUrl = serverUrl.substring(0, serverUrl.length - 1); 
       } 
       return serverUrl; 
      }; 
      Service.GetODataEndPoint = function() { 
       return Service.GetServerUrl() + "/XRMServices/2011/OrganizationData.svc"; 
      }; 
      Service.GetSOAPEndPoint = function() { 
       return Service.GetServerUrl() + "/XRMServices/2011/Organization.svc/web"; 
      }; 

      Service.GetResults = function (responseXML) { 
       var sFetchResult = responseXML.selectSingleNode("//RetrieveMultipleResult").xml; 

       var oResultDoc = new ActiveXObject("Microsoft.XMLDOM"); 
       oResultDoc.async = false; 
       oResultDoc.loadXML(sFetchResult); 

       var oResults = new Array(oResultDoc.firstChild.firstChild.childNodes.length); 

       var iLen = oResultDoc.firstChild.firstChild.childNodes.length; 
       for (var i = 0; i < iLen; i++) { 

        var oResultNode = oResultDoc.firstChild.firstChild.childNodes[i]; 
        var oBE = new BusinessEntity(oResultNode.selectSingleNode("//a:LogicalName").text); 

        var iLenInner = oResultNode.firstChild.childNodes.length; 
        for (var j = 0; j < iLenInner; j++) { 
         var oRA = new Object(); 

         var value = null; 
         if (oResultNode.firstChild.childNodes[j].lastChild.childNodes.length == 3) { 
          if (oResultNode.firstChild.childNodes[j].lastChild.getElementsByTagName("a:Id").length == 1) 
           value = oResultNode.firstChild.childNodes[j].lastChild.getElementsByTagName("a:Id")[0].text; 
          if (oResultNode.firstChild.childNodes[j].lastChild.getElementsByTagName("a:Value").length == 1) 
           value = oResultNode.firstChild.childNodes[j].lastChild.getElementsByTagName("a:Value")[0].text; 
         } 
         if (!value) 
          value = oResultNode.firstChild.childNodes[j].lastChild.text; 

         oRA["value"] = value; 

         oBE.attributes[oResultNode.firstChild.childNodes[j].firstChild.firstChild.text] = oRA; 
        } 

        oResults[i] = oBE; 
       } 
       return oResults; 
      }; 

      Service.BusinessEntity = function BusinessEntity(sName) { 
       this.name = sName; 
       this.attributes = new Object(); 
      }; 

      Service.FetchEncode = function (FetchXML) { 
       var c; 
       var HtmlEncode = ''; 

       if (FetchXML == null) { 
        return null; 
       } 
       if (FetchXML == '') { 
        return ''; 
       } 

       for (var cnt = 0; cnt < FetchXML.length; cnt++) { 
        c = FetchXML.charCodeAt(cnt); 

        if (((c > 96) && (c < 123)) || 
          ((c > 64) && (c < 91)) || 
          (c == 32) || 
          ((c > 47) && (c < 58)) || 
          (c == 46) || 
          (c == 44) || 
          (c == 45) || 
          (c == 95)) { 
         HtmlEncode = HtmlEncode + String.fromCharCode(c); 
        } 
        else { 
         HtmlEncode = HtmlEncode + '&#' + c + ';'; 
        } 
       } 

       return HtmlEncode; 
      }; 
     } (Crm.Service = Crm.Service || {}, _window.jQuery, _window.JSON, _window.Xrm)); 
    } (_window.Crm = _window.Crm || {})); 
} (window)); 
+0

雖然此方法確實使您能夠針對2011 SOAP端點執行JavaScript中的FetchXML請求,但它不會以與4.0 Web服務相同的格式返回XML。 我一直希望能夠更新CRM 4.0到2011移植項目的FetchXML調用,但這不會那麼容易。 – Paul 2011-05-10 23:15:48

+0

在Service.Fetch函數中,返回之前定義的「結果」在哪裏? – musefan 2011-10-24 10:58:59

+0

好的。我會看看源代碼,然後和你一起回去。 – Paul 2012-01-27 19:52:51

2

從您發佈到Microsoft SDK的鏈接,你將看到如何連接到OData服務。正如你可能已經發現的那樣,ODATA不允許你執行提取。相反,您需要使用SOAP服務(/XrmServices/2011/Organization.svc),並使用Retrieve Multiple傳遞您的提取。

這裏是在通過JavaScript使用2011服務的更多詳細信息:http://blog.customereffective.com/blog/2011/05/execute-fetch-from-javascript-in-crm-2011.html

這裏是另一篇博客中,它解析返回的XML,並構建一個容易的使用JavaScript對象:http://blog.customereffective.com/blog/2011/05/parsing-and-consuming-the-crm-2011-soap-service-inside-javascript.html

2011年組織服務是它的回報完全不同,所以它不會從4.0的東西中實現即插即用;然而,2011年的終端有很多很好的改進。

+0

我正在使用的遷移使用Ascentium CRM Helper進行4.0 Web服務。我爲2011年的Web服務創建了一個類似的助手,該助手返回與Ascentium助手所做的相同的業務對象。我認爲轉換到buisness對象還有改進的餘地,但到目前爲止,它似乎適用於我當前的項目。 我有興趣閱讀您的upcomming帖子。也許我們可以比較我們的方法? – Paul 2011-05-13 16:54:30

+0

哇,我喜歡Ascentium的服務,奇怪的是有一些相似的元素,所以希望這些變化很小。這只是現在抓取。順便說一句,如果你不使用在線,那麼你可以註釋掉他們的一些CreateXMLHTTP代碼,並在本地連接而不必發佈(這很方便)。你應該能夠複製CreateXMLHTTP代碼和3個輔助類,並將它們插入我發佈的內容中。 – 2011-05-16 14:12:00