如何使用CRM 2011 webservice和JavaScript在CRM 2011中执行FetchXML?

时间:2011-05-03 23:40:25

标签: javascript dynamics-crm-2011 fetchxml

我想使用 CRM 2011 SOAP Web服务 JavaScript 在CRM 2011环境中执行FetchXML查询。

我发现了一些文章like this one,展示了如何使用2011环境中仍然可用的4.0网络服务,但我不想这样做。

This link似乎表明IOrganizationService.RetrieveMultiple可以处理FetchXML。但是,我不想为此使用托管代码。

我遇到this link基本上显示了我想在RetrieveMultiple函数中做什么,但我希望能够传入我编写的现有FetchXML,而不是新的过滤器表达式。< / p>

4 个答案:

答案 0 :(得分:7)

要使用JavaScript执行fetchxml查询,可以使用一堆框架/库:

这些库不是手动编写代码,而是提供执行多个操作和访问结果的简单方法。但请注意,并非所有库(当前)都支持跨浏览器(Q2.2012)。

答案 1 :(得分:2)

this MSDN article的“捕获示例HTTP请求和响应”部分概述了如何从托管代码获取发送到CRM 2011的SOAP消息。

this MSDN article的“执行查询”部分举例说明了在托管代码中使用2011的IOrganizationService.RetrieveMultiple来执行FetchXML查询。

使用这两个示例,您可以为包含FetchXML查询的RetrieveMultiple提取示例SOAP消息。

the first MSDN article的“创建JScript库”部分显示了如何在JavaScript中针对2011 SOAP端点执行Execute请求。将此示例中的Assign SOAP请求替换为您执行托管代码时获得的RetrieveMultiple SOAP消息。

这使您能够在JavaScript中针对2011 SOAP端点执行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));

答案 2 :(得分: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年的终点有很多很好的改进。

答案 3 :(得分:1)

  

“REST是一种架构风格,通过使用唯一的URI来解决每个资源。”   http://msdn.microsoft.com/en-us/library/gg334279.aspx

如果需要使用FetchXml,则无法使用REST端点。

另一种方法是构建一个SOAP消息,就像在CRM4示例中看到的那样。我自己还没有这样做,但也许您可以使用像Fiddler这样的工具来查看SOAP消息的外观,以便您可以在修改后的FetchXml环境中复制它们。

无论如何,现在只是一个想法。让我知道它是怎么回事,如果你设法解决它,也许发布你的解决方案。