如何使用 CRM 2011 网络服务和 JavaScript 在 CRM 2011 中执行 FetchXML?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5876964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:19:49  来源:igfitidea点击:

How to Execute FetchXML in CRM 2011 using a CRM 2011 webservice and JavaScript?

javascriptdynamics-crm-2011fetchxml

提问by Paul

I want to execute FetchXML queries in a CRM 2011 environment using the CRM 2011 SOAP web servicesand JavaScript.

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

I have found a number of articles like this oneshowing how to use the 4.0 web service that is still available in the 2011 environment, but I do not want to do this.

我找到了很多类似这样的文章,展示了如何使用在 2011 环境中仍然可用的 4.0 Web 服务,但我不想这样做。

This linkseems to indicate that IOrganizationService.RetrieveMultiple can handle FetchXML. However, I do not want to use managed code for this.

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

I've come across this linkthat shows essentially what I want to do in the RetrieveMultiple function, but I want to be able to pass in existing FetchXML that I've written, not a new filter expression.

我遇到了这个链接,它基本上显示了我想在 RetrieveMultiple 函数中执行的操作,但我希望能够传入我编写的现有 FetchXML,而不是新的过滤器表达式。

采纳答案by thuld

To execute fetchxml queries with JavaScript a bunch of frameworks /libraries are available:

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

Instead of writing the code by hand these libraries provide a simple way to perform several operations and access the results. But take into account that not all libraries (currently) support cross-browser (Q2.2012).

这些库不是手动编写代码,而是提供了一种执行多个操作和访问结果的简单方法。但考虑到并非所有库(当前)都支持跨浏览器(2012 年第 2 季度)。

回答by Paul

The "Capture Sample HTTP Request and Response" section of this MSDN articleoutlines how to get a SOAP message that is sent to CRM 2011 from managed code.

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

The "Execute the Query" section of this MSDN articlegives an example of using 2011's IOrganizationService.RetrieveMultiple in managed code to execute a FetchXML query.

这篇 MSDN 文章的“执行查询”部分给出了在托管代码中使用 2011 年的 IOrganizationService.RetrieveMultiple 来执行 FetchXML 查询的示例。

Using both of these samples, you can extract a sample SOAP message for RetrieveMultiple that contains a FetchXML query.

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

The "Create a JScript Library" section of the first MSDN articleshows how to perform an Execute request in JavaScript against the 2011 SOAP endpoint. Replace the Assign SOAP request in this example with the RetrieveMultiple SOAP message that you get from executing the managed code.

第一篇 MSDN 文章的“创建 JScript 库”部分展示了如何在 JavaScript 中针对 2011 SOAP 端点执行执行请求。将本示例中的 Assign SOAP 请求替换为您通过执行托管代码获得的 RetrieveMultiple SOAP 消息。

This enables you to execute a FetchXML request in JavaScript against the 2011 SOAP endpoint.

这使您能够在 JavaScript 中针对 2011 SOAP 端点执行 FetchXML 请求。

Here are some snippets from a JavaScript library I wrote using the information above:

以下是我使用上述信息编写的 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));

回答by Paul Way

From the link you posted to the Microsoft SDK, you will see how to connect to the ODATA service. As you may have already found, ODATA doesn't allow you to execute fetch.

从您发布到Microsoft SDK的链接中,您将看到如何连接到 ODATA 服务。您可能已经发现,ODATA 不允许您执行 fetch。

Instead, you will need to use the SOAP service (/XrmServices/2011/Organization.svc), and pass your fetch using Retrieve Multiple.

相反,您需要使用 SOAP 服务 ( /XrmServices/2011/Organization.svc),并使用 Retrieve Multiple 传递您的提取。

Here's a more detailed look at using the 2011 service through JavaScript: http://blog.customereffective.com/blog/2011/05/execute-fetch-from-javascript-in-crm-2011.html

下面是通过 JavaScript 使用 2011 服务的更详细的介绍:http: //blog.customereffective.com/blog/2011/05/execute-fetch-from-javascript-in-crm-2011.html

Here is another blog post which parses the returned XML and builds an easily consumable JavaScript object: http://blog.customereffective.com/blog/2011/05/parsing-and-consuming-the-crm-2011-soap-service-inside-javascript.html

这是另一篇博客文章,它解析返回的 XML 并构建一个易于使用的 JavaScript 对象:http: //blog.customereffective.com/blog/2011/05/parsing-and-sumption-the-crm-2011-soap-service-里面-javascript.html

The 2011 Organization Service is quite different in it's return, so it won't be plug-n-play from your 4.0 stuff; however, the 2011 endpoint has a lot of nice improvements.

2011 年的组织服务在它的返回上有很大的不同,所以它不会从你的 4.0 东西中即插即用;然而,2011 端点有很多不错的改进。

回答by Luke Baulch

"REST is an architectural style in which every resource is addressed by using a unique URI."http://msdn.microsoft.com/en-us/library/gg334279.aspx

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

You will not be able to use the REST end-point if you need to use FetchXml.

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

The alternative is to construct a SOAP message as you saw in your CRM4 examples. I haven't done this myself yet, but perhaps you could use a tool like Fiddler to see what the SOAP message look like so you can replicate them in your environment which your modified FetchXml.

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

Anyway, just an idea for now. Let me know how it goes, and if you manage to resolve it perhaps post your solution.

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