我想使用 CRM 2011 SOAP Web服务和 JavaScript 在CRM 2011环境中执行FetchXML查询。
我发现了一些文章like this one,展示了如何使用2011环境中仍然可用的4.0网络服务,但我不想这样做。
This link似乎表明IOrganizationService.RetrieveMultiple可以处理FetchXML。但是,我不想为此使用托管代码。
我遇到this link基本上显示了我想在RetrieveMultiple函数中做什么,但我希望能够传入我编写的现有FetchXML,而不是新的过滤器表达式。< / p>
答案 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环境中复制它们。
无论如何,现在只是一个想法。让我知道它是怎么回事,如果你设法解决它,也许发布你的解决方案。