Как выполнить FetchXML в CRM 2011, используя веб-сервис CRM 2011 и JavaScript? - PullRequest
8 голосов
/ 04 мая 2011

Я хочу выполнить запросы FetchXML в среде CRM 2011 с помощью веб-служб CRM 2011 SOAP и JavaScript .

Я нашел несколько статей , подобных этой , показывающих, как использовать веб-сервис 4.0, который все еще доступен в среде 2011 года, но я не хочу этого делать.

Эта ссылка указывает на то, что IOrganizationService.RetrieveMultiple может обрабатывать FetchXML. Однако я не хочу использовать для этого управляемый код.

Я встречал эту ссылку , которая в основном показывает, что я хочу сделать в функции RetrieveMultiple, но я хочу иметь возможность передать существующий FetchXML, который я написал, а не новый фильтр выражение.

Ответы [ 4 ]

7 голосов
/ 15 мая 2012

Для выполнения запросов fetchxml с помощью JavaScript доступно несколько фреймворков / библиотек:

Вместо написания кода вручную эти библиотеки предоставляют простой способ выполнить несколько операций и получить доступ к результатам. Но учтите, что не все библиотеки (в настоящее время) поддерживают кросс-браузер (Q2.2012).

2 голосов
/ 06 мая 2011

В разделе «Capture Sample HTTP Request and Response» этой статьи MSDN описано, как получить SOAP-сообщение, отправленное в CRM 2011 из управляемого кода.

«ВыполнитьРаздел «Запрос» В этой статье MSDN приведен пример использования IOrganizationService.RetrieveMultiple 2011 года в управляемом коде для выполнения запроса FetchXML.

Используя оба этих примера, вы можете извлечь образец сообщения SOAPдля RetrieveMultiple, который содержит запрос FetchXML.

В разделе «Создание библиотеки JScript» в первой статье MSDN показано, как выполнить запрос на выполнение в JavaScript для конечной точки SOAP 2011 года.Замените в этом примере запрос Назначить SOAP на сообщение RetrieveMultiple SOAP, полученное при выполнении управляемого кода.

Это позволяет выполнить запрос FetchXML в JavaScript для конечной точки SOAP 2011 года.

Вот некоторые фрагменты из библиотеки 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 голосов
/ 07 мая 2011

По ссылке, которую вы разместили на Microsoft SDK , вы увидите, как подключиться к службе ODATA. Как вы, возможно, уже обнаружили, ODATA не позволяет вам выполнять выборку.

Вместо этого вам нужно будет использовать службу SOAP ( / XrmServices / 2011 / Organization.svc ) и передать выборку с помощью функции Retrieve Multiple.

Вот более подробное описание использования сервиса 2011 через JavaScript: 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 года сильно отличается по своей отдаче, так что она не будет plug-n-play из вашего материала 4.0; однако конечная точка 2011 года имеет много приятных улучшений.

1 голос
/ 04 мая 2011

"REST - это архитектурный стиль, в котором каждый ресурс адресуется с помощью уникального URI." http://msdn.microsoft.com/en-us/library/gg334279.aspx

Вы не сможете использоватьконечная точка REST, если вам нужно использовать FetchXml.

Альтернативой является создание сообщения SOAP, как вы видели в примерах CRM4.Я сам этого еще не сделал, но, возможно, вы могли бы использовать такой инструмент, как Fiddler, чтобы посмотреть, как выглядит сообщение SOAP, чтобы вы могли воспроизвести его в своей среде, в которой вы модифицировали FetchXml.

Во всяком случае, пока просто идея.Дайте мне знать, как это происходит, и, если вам удастся решить проблему, возможно, опубликуйте свое решение.

...