Расширенная функциональность
16
Июл
10

FetchXML в JS в CRM 2011

Способ выполнения FetchXML-запроса в CRM 2011 с помощью JS претерпел некоторые изменения – стал немного сложнее и выполняется теперь через сообщение RetrieveMultiple. Ниже код, который показывает, как его выполнить:

function onLoad() {
    // Определяем Fetch-запрос
    var fetch = '<fetch mapping="logical" count="50" version="1.0">' +
                    '<entity name="account">' +
                        '<attribute name="accountid" />' +
                        '<attribute name="name" />' +
                    '</entity>' +
                '</fetch>';
    soapRequest(fetch);
}

function soapRequest(FetchXML) {
    // Формируем SOAP-запрос
    var request = '';
    request +=  '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body>';
    request +=  '<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">' +
                '<request i:type="b:RetrieveMultipleRequest" ' +
                ' xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" ' +
                ' xmlns:i="http://www.w3.org/2001/XMLSchema-instance">' +
                '<b:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">' +
                '<b:KeyValuePairOfstringanyType>' +
                '<c:key>Query</c:key>' +
                '<c:value i:type="b:FetchExpression">' +
                '<b:Query>';
    request +=  fetchEncode(FetchXML); // Кодируем Fetch-запрос
    request +=  '</b:Query>' +
                '</c:value>' +
                '</b:KeyValuePairOfstringanyType>' +
                '</b:Parameters>' +
                '<b:RequestId i:nil="true"/>' +
                '<b:RequestName>RetrieveMultiple</b:RequestName>' +
                '</request>' +
                '</Execute>';
    request +=  '</s:Body></s:Envelope>';

    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("POST", Xrm.Page.context.getServerUrl() + "/XRMServices/2011/Organization.svc/web", true);
    xmlhttp.setRequestHeader("Accept", "application/xml, text/xml, */*");
    xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4) {
            if (xmlhttp.status == 200) {
                var names = "";
                // Просматриваем и выводим результат
                var results = xmlhttp.responseXML.getElementsByTagName('a:Attributes');
                for (i = 0; i < results.length; i++)
                    names += results[i].childNodes[1].lastChild.text + "\n";
                alert(names);
            } else {
                alert(xmlhttp.responseText + " " + xmlhttp.statusText);
            }
        }
    };
    xmlhttp.send(request); // Отправляем запрос
}

// Функция кодирует Fetch-запрос
function fetchEncode(FetchXML) {
    var c;
    var HtmlEncode = '';

    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;
}

Тут три функции:

  • Первая простая – в ней формируется сам Fetch-запрос и передается второй функции;
  • Во второй формируется и выполняется SOAP-запрос и тут же происходит обработка полученных результатов;
  • А в третьей происходит кодирование Fetch-запроса перед его отправкой.


Комментарии (10)
  • Anna 16.07.2012

    День добрый! Пробую реализовать подобный пример со следующим запросом fetch:
    var sFetch = «» +
    «» +
    «» +
    «» +
    «» +
    «» +
    «» +
    «» +
    «» +
    «» +
    «»;

    for (i = 0; i < results.length; i++)
    names += results[i].childNodes[1].lastChild.text+ "\n";
    alert(names);
    И почему-то names всегда undefined

    Подскажите, пожалуйста, что не так делаю?
    Мне в результате надо получить 4 атрибута: lastname, firstname, uds_positionlevelid, uds_positionid

  • Anna 16.07.2012

    не вставился запрос:
    var sFetch = +
    +
    +
    +
    +
    +
    +
    +
    +
    +

  • Anna 16.07.2012

    var sFetch = +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    ;

  • Anna 16.07.2012

    так запрос и не вставился.. но он аналогичен вашем, отличие только в том, что мне надо получить 4 поля, перечисленные выше..

  • Михаил 16.07.2012

    Анна, скорее всего, вы не определили переменную names. Поставьте перед ее использованием
    var names = »;

  • Anna 16.07.2012

    определила. проблема осталась

  • Михаил 16.07.2012

    Значит она находится в другой области видимости.

  • Anna 16.07.2012

    а еще подскажите, пожалуйста, а почему может под одной учеткой запрос выполнять, а под другой — статус реквеста всегда 0?

  • Anna 16.07.2012

    доступ у учетки полный

  • Anna 16.07.2012

    По последней проблеме — решила. Вдруг кому пригодится.. Проблема в URL сервера. Надо получать не методом getServerUrl(), а из window.location.href

*

code