使用JS通过Web API执行批量操作,多个操作是一个事务!
关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复235或者20161105可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me 。
function submit() { var clientURL = Xrm.Page.context.getClientUrl(); var batchId = getRandomString(12); var changesetId = getRandomString(12); var requestMsg = ["--batch_" + batchId]; requestMsg.push("Content-Type: multipart/mixed;boundary=changeset_" + changesetId); requestMsg.push(""); requestMsg.push("--changeset_" + changesetId); requestMsg.push("Content-Type: application/http"); requestMsg.push("Content-Transfer-Encoding:binary"); requestMsg.push("Content-ID: 1"); requestMsg.push(""); requestMsg.push("POST " + clientURL + "/api/data/v8.1/ly_tests HTTP/1.1"); requestMsg.push("Content-Type: application/json;type=entry"); requestMsg.push("");//注意这里要加空行 var subMsg1 = {}; subMsg1.ly_name = "批量操作创建的罗勇测试记录"; subMsg1["ly_Lookup@odata.bind"] = "/accounts(CE23165A-3AA3-E511-80C7-000D3A807EC7)"; subMsg1["ly_ly_test_ly_testsub_Test"] = []; subMsg1["ly_ly_test_ly_testsub_Test"].push({ "ly_name": "批量操作创建的罗勇测试辅助实体记录1" }); subMsg1["ly_ly_test_ly_testsub_Test"].push({ "ly_name": "批量操作创建的罗勇测试辅助实体记录2" }); requestMsg.push(JSON.stringify(subMsg1)); requestMsg.push("--changeset_" + changesetId); requestMsg.push("Content-Type: application/http"); requestMsg.push("Content-Transfer-Encoding:binary"); requestMsg.push("Content-ID: 2"); requestMsg.push("");//注意这里要加空行 requestMsg.push("POST " + clientURL + "/api/data/v8.1/tasks HTTP/1.1"); requestMsg.push("Content-Type: application/json;type=entry"); requestMsg.push("");//注意这里要加空行 requestMsg.push("{'subject':'批量操作创建的任务','regardingobjectid_account_task@odata.bind':'https://demo.luoyong.me/api/data/v8.1/accounts(C223165A-3AA3-E511-80C7-000D3A807EC7)'}"); requestMsg.push("--changeset_" + changesetId); requestMsg.push("Content-Type: application/http"); requestMsg.push("Content-Transfer-Encoding:binary"); requestMsg.push("Content-ID: 3"); requestMsg.push(""); requestMsg.push("PATCH $1 HTTP/1.1"); requestMsg.push("Content-Type: application/json;type=entry"); requestMsg.push("");//注意这里要加空行 requestMsg.push("{'ly_singlelinetext':'更新了批量操作创建的罗勇测试实体记录'}"); requestMsg.push("--changeset_" + changesetId + "--");//changeset结束这里前面不要加空行 requestMsg.push("");//注意这里要加空行 requestMsg.push("--batch_" + batchId + "--");//batch结束前面加空行 executeBatch(clientURL, batchId, requestMsg.join("\n"), function (responseText) { Xrm.Utility.alertDialog("执行后返回status=200,也有可能有错误:" + responseText); }, function (responseText) { Xrm.Utility.alertDialog("执行出错:" + responseText); }); } function executeBatch(clientURL, batchId, requestMsg, successCallback, errorCallback) { var req = new XMLHttpRequest() req.open("POST", encodeURI(clientURL + "/api/data/v8.1/$batch", true));//true是异步请求,false是同步请求 req.setRequestHeader("Content-Type", "multipart/mixed;boundary=batch_" + batchId); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4 /* complete */) { req.onreadystatechange = null; if (this.status == 200) {//204代表成功无返回值 successCallback(this.responseText); } else { errorCallback(this.responseText); } } }; req.send(requestMsg); } function getRandomString(len, charSet) { charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var randomString = ''; for (var i = 0; i < len; i++) { var randomPoz = Math.floor(Math.random() * charSet.length); randomString += charSet.substring(randomPoz, randomPoz + 1); } return randomString; }
Content-Type: multipart/mixed;boundary=batch_AAA1234
OData-MaxVersion: 4.0
OData-Version: 4.0
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IlRBRzN5S3hrZW04eHppQmpmS3RSUFBoQ1liWSJ9.eyJhdWQiOiJodHRwczovL2RlbW8ubHVveW9uZy5tZS8iLCJpc3MiOiJodHRwOi8vc3RzLmx1b3lvbmcubWUvYWRmcy9zZXJ2aWNlcy90cnVzdCIsImlhdCI6MTQ3ODMwNzM5MiwiZXhwIjoxNDc4MzM2MTkyLCJ1cG4iOiJjcm1hZG1pbkBsdW95b25nLm1lIiwicHJpbWFyeXNpZCI6IlMtMS01LTIxLTY1Mzc0MDc5OC0yNDUxMzM4NTMyLTMwMjU3ODY3ODktMTEwNCIsInVuaXF1ZV9uYW1lIjoiTFVPWU9OR1xcY3JtYWRtaW4iLCJhdXRoX3RpbWUiOiIyMDE2LTExLTA1VDAwOjU2OjMyLjMxM1oiLCJhdXRobWV0aG9kIjoidXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFjOmNsYXNzZXM6UGFzc3dvcmRQcm90ZWN0ZWRUcmFuc3BvcnQiLCJ2ZXIiOiIxLjAiLCJhcHBpZCI6ImJhMTA2MjY1LWZiM2ItNDllMC1hMGU4LTY4NDBiM2Q3MWFjMiJ9.M8RXfCpBLOoJSazOkmjMIJYyYfYxVGmwojOjO4Pd4Yn9EtbeYK1t0tisP19WTsniHvsRXWaD5bwtLMxQL3DMCOJ1Ftsi7o6gr9U_9URRXffHOqPGOwO5n2Ofxga9pqETi2HPO0PpsyD0hOwMsBkZXCuwjOiYzNdbIY4bq0FDOc4iL7HYTd6xvYAOC8JhNj-H6QuqhrFxRPSrkcKt9Pgkg7T-oblWqZwZEV0sIRbm00pYLSIcPVRiFUmgBQUu7kwqFcwRDgLe7VlSTGlaTRtZphwMB-cYO3LebxDABeMuosZAZPa47g4s8xLpNb5lt9sd365Oebut4jUDhT1VIhNKPw
--batch_AAA1234
Content-Type: multipart/mixed;boundary=changeset_BBB4567
--changeset_BBB4567
Content-Type: application/http
Content-Transfer-Encoding:binary
Content-ID: 1
POST https://demo.luoyong.me/api/data/v8.1/ly_tests HTTP/1.1
Content-Type: application/json;type=entry
{"ly_name":"批量操作创建的罗勇测试记录","ly_Lookup@odata.bind":"/accounts(CE23165A-3AA3-E511-80C7-000D3A807EC7)","ly_integer":10,"ly_ly_test_ly_testsub_Test":[{'ly_name':'批量操作创建的罗勇测试辅助实体记录1'},{'ly_name':'批量操作创建的罗勇测试辅助实体记录2'}]}
--changeset_BBB4567
Content-Type: application/http
Content-Transfer-Encoding:binary
Content-ID: 2
POST https://demo.luoyong.me/api/data/v8.1/tasks HTTP/1.1
Content-Type: application/json;type=entry
{"subject":"批量操作创建的任务","regardingobjectid_account_task@odata.bind":"https://demo.luoyong.me/api/data/v8.1/accounts(C223165A-3AA3-E511-80C7-000D3A807EC7)"}
--changeset_BBB4567
Content-Type: application/http
Content-Transfer-Encoding:binary
Content-ID: 3
PATCH $1 HTTP/1.1
Content-Type: application/json;type=entry
{"ly_singlelinetext":"更新了批量操作创建的罗勇测试实体记录"}
--changeset_BBB4567--
--batch_AAA1234--
"--batchresponse_8071c8bc-f577-44a6-a246-e27c1ec027e2
?Content-Type: multipart/mixed; boundary=changesetresponse_c5387a7e-c5c6-4ea5-95bd-13df85d67046
?
?--changesetresponse_c5387a7e-c5c6-4ea5-95bd-13df85d67046
?Content-Type: application/http
?Content-Transfer-Encoding: binary
?Content-ID: 1
?
?HTTP/1.1 204 No Content
?OData-Version: 4.0
?Location: https://demo.luoyong.me/api/data/v8.1/ly_tests(6c358f7d-54a3-e611-816b-000d3a80c8b8)
?OData-EntityId: https://demo.luoyong.me/api/data/v8.1/ly_tests(6c358f7d-54a3-e611-816b-000d3a80c8b8)
?Access-Control-Expose-Headers: Preference-Applied,OData-EntityId,Location,ETag,OData-Version,Content-Encoding,Transfer-Encoding,Content-Length,Retry-After
?
?
?--changesetresponse_c5387a7e-c5c6-4ea5-95bd-13df85d67046
?Content-Type: application/http
?Content-Transfer-Encoding: binary
?Content-ID: 2
?
?HTTP/1.1 204 No Content
?OData-Version: 4.0
?Location: https://demo.luoyong.me/api/data/v8.1/tasks(6f358f7d-54a3-e611-816b-000d3a80c8b8)
?OData-EntityId: https://demo.luoyong.me/api/data/v8.1/tasks(6f358f7d-54a3-e611-816b-000d3a80c8b8)
?Access-Control-Expose-Headers: Preference-Applied,OData-EntityId,Location,ETag,OData-Version,Content-Encoding,Transfer-Encoding,Content-Length,Retry-After
?
?
?--changesetresponse_c5387a7e-c5c6-4ea5-95bd-13df85d67046
?Content-Type: application/http
?Content-Transfer-Encoding: binary
?Content-ID: 3
?
?HTTP/1.1 204 No Content
?OData-Version: 4.0
?Location: https://demo.luoyong.me/api/data/v8.1/ly_tests(6c358f7d-54a3-e611-816b-000d3a80c8b8)
?OData-EntityId: https://demo.luoyong.me/api/data/v8.1/ly_tests(6c358f7d-54a3-e611-816b-000d3a80c8b8)
?Access-Control-Expose-Headers: Preference-Applied,OData-EntityId,Location,ETag,OData-Version,Content-Encoding,Transfer-Encoding,Content-Length,Retry-After
?
?
?--changesetresponse_c5387a7e-c5c6-4ea5-95bd-13df85d67046--
?--batchresponse_8071c8bc-f577-44a6-a246-e27c1ec027e2--
?"
如果是查询操作呢,记得查询操作不要放到changeset中,我举个例子如下:
请求的内容如下,最后一个batch结尾只需要一个,其余的每个查询的格式是固定的,我这里举了两个查询的例子。
--batch_AAA123 Content-Type: application/http Content-Transfer-Encoding:binary GET https://luoyongdemo.crm.dynamics.com/api/data/v9.1/accounts?$select=createdon&$top=1 HTTP/1.1 Accept: application/json --batch_AAA123 Content-Type: application/http Content-Transfer-Encoding:binary GET https://luoyongdemo.crm.dynamics.com/api/data/v9.1/contacts?$select=createdon&$top=1 HTTP/1.1 Accept: application/json --batch_AAA123--
返回内容示例如下:
--batchresponse_169a82f8-26b1-4b42-8496-dd7030665e3e Content-Type: application/http Content-Transfer-Encoding: binary HTTP/1.1 200 OK Content-Type: application/json; odata.metadata=minimal OData-Version: 4.0 {"@odata.context":"https://luoyongdemo.crm.dynamics.com/api/data/v9.1/$metadata#accounts(createdon)","value":[{"@odata.etag":"W/\"665451369\"","createdon":"2020-10-07T09:41:50Z","accountid":"46c66651-8108-eb11-a813-000d3a111c98"}]} --batchresponse_169a82f8-26b1-4b42-8496-dd7030665e3e Content-Type: application/http Content-Transfer-Encoding: binary HTTP/1.1 200 OK Content-Type: application/json; odata.metadata=minimal OData-Version: 4.0 {"@odata.context":"https://luoyongdemo.crm.dynamics.com/api/data/v9.1/$metadata#contacts(createdon)","value":[{"@odata.etag":"W/\"822799980\"","createdon":"2020-12-04T08:09:29Z","contactid":"dd535807-0836-eb11-a813-000d3a148177"}]} --batchresponse_169a82f8-26b1-4b42-8496-dd7030665e3e--