MS CRM 2011 RetrieveMultiple with JScript JQuery Silverlight LINQ FetchXML and QueryExpression
289615 ワード
オリジナル住所:http://www.cnblogs.com/jfzhu/archive/2013/03/07/2947306.html
転載は出典を明記してください
(一)Jscript
Jscriptは一度に最大50個のデータを返し、より多くのデータを得るには__を使用する必要があります.nextオブジェクト
1.同期操作は50個未満のデータを返す
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
<script src="aw_json.js" type="text/javascript"></script>
<script src="new_TestLibrary.js" type="text/javascript"></script>
<script type="text/javascript">
function clearaccountsGrid() {
var accountsGrid = document.getElementById("accountsGrid");
for (var i = accountsGrid.rows.length - 1; i >= 0; i--) {
accountsGrid.deleteRow(i);
}
}
function setElementText(element, text) {
///<summary>
/// This function mitigates the fact that IE uses innerText and other browsers use textContent.
///</summary>
if (typeof (element.innerText) != "undefined")
{ element.innerText = text; }
else
{ element.textContent = text; }
}
function Button1_onclick() {
clearaccountsGrid();
RetrieveAllAccounts()
}
function RetrieveAllAccounts() {
try {
var oDataPath = TestLibrary._ODataPath();
var filter = "/AccountSet?$select=Name";
var retrieveRecordsReq = new XMLHttpRequest();
retrieveRecordsReq.open("GET", oDataPath + filter, false);
retrieveRecordsReq.setRequestHeader("Accept", "application/json");
retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
retrieveRecordsReq.send();
var retrievedResponse = JSON.parse(retrieveRecordsReq.responseText).d;
var totalAccountCount = retrievedResponse.results.length;
setElementText(document.getElementById("totalLabel"), "There are " + totalAccountCount + " accounts");
if (retrievedResponse.results.length > 0) {
var accountsGrid = document.getElementById("accountsGrid");
for (var i = 0; i < retrievedResponse.results.length; i++) {
var account = retrievedResponse.results[i];
var row = document.createElement("tr");
var nameCell = document.createElement("td");
setElementText(nameCell, account.Name);
row.appendChild(nameCell);
accountsGrid.appendChild(row);
}
}
}
catch (e) {
alert(e.Message);
}
}
</script>
<title></title>
</head>
<body>
<label id="totalLabel"></label>
<input id="Button1" type="button" value="button" onclick="return Button1_onclick()" />
<div id="tableContainer">
<table id="accountsTable" rules="groups" summary="This table displays the accounts retrieved.">
<tbody id="accountsGrid" />
</table>
</div>
</body>
</html>
if (typeof (TestLibrary) == "undefined") {
TestLibrary = { __namespace: true };
}
TestLibrary = {
Name: "TestLibrary",
_context: function () {
if (typeof GetGlobalContext != "undefined")
{ return GetGlobalContext(); }
else {
if (typeof Xrm != "undefined") {
return Xrm.Page.context;
}
else
{ throw new Error("Context is not available."); }
}
},
_getServerUrl: function () {
var serverUrl = TestLibrary._context().getServerUrl()
if (serverUrl.match(/\/$/)) {
serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}
return serverUrl;
},
_ODataPath: function () {
return TestLibrary._getServerUrl() + "/XRMServices/2011/OrganizationData.svc/";
}
}
2.同期操作は50以上のデータを返す
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
<script src="aw_json.js" type="text/javascript"></script>
<script src="new_TestLibrary.js" type="text/javascript"></script>
<script type="text/javascript">
function clearaccountsGrid() {
var accountsGrid = document.getElementById("accountsGrid");
for (var i = accountsGrid.rows.length - 1; i >= 0; i--) {
accountsGrid.deleteRow(i);
}
}
function setElementText(element, text) {
///<summary>
/// This function mitigates the fact that IE uses innerText and other browsers use textContent.
///</summary>
if (typeof (element.innerText) != "undefined")
{ element.innerText = text; }
else
{ element.textContent = text; }
}
function Button1_onclick() {
clearaccountsGrid();
RetrieveAllAccounts()
}
function RetrieveAllAccounts() {
try {
var oDataPath = TestLibrary._ODataPath();
var type = "AccountSet";
var filter = "?$select=Name";
var retrieveRecordsReq = new XMLHttpRequest();
retrieveRecordsReq.open("GET", oDataPath + type + filter, false);
var totalAccountCount = 0;
retrieveRecordsReq.setRequestHeader("Accept", "application/json");
retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
retrieveRecordsReq.send();
var retrievedResponse = JSON.parse(retrieveRecordsReq.responseText).d;
totalAccountCount = totalAccountCount + retrievedResponse.results.length;
setElementText(document.getElementById("totalLabel"), "There are " + totalAccountCount + " accounts");
if (retrievedResponse.results.length > 0) {
var accountsGrid = document.getElementById("accountsGrid");
for (var i = 0; i < retrievedResponse.results.length; i++) {
var account = retrievedResponse.results[i];
var row = document.createElement("tr");
var nameCell = document.createElement("td");
setElementText(nameCell, account.Name);
row.appendChild(nameCell);
accountsGrid.appendChild(row);
}
}
while (retrievedResponse.__next != null) {
var queryOptions = retrievedResponse.__next.substring((TestLibrary._ODataPath() + "AccountSet").length);
retrieveRecordsReq = new XMLHttpRequest();
retrieveRecordsReq.open("GET", oDataPath + type + queryOptions, false);
retrieveRecordsReq.setRequestHeader("Accept", "application/json");
retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
retrieveRecordsReq.send();
retrievedResponse = JSON.parse(retrieveRecordsReq.responseText).d;
totalAccountCount = totalAccountCount + retrievedResponse.results.length;
setElementText(document.getElementById("totalLabel"), "There are " + totalAccountCount + " accounts");
if (retrievedResponse.results.length > 0) {
var accountsGrid = document.getElementById("accountsGrid");
for (var i = 0; i < retrievedResponse.results.length; i++) {
var account = retrievedResponse.results[i];
var row = document.createElement("tr");
var nameCell = document.createElement("td");
setElementText(nameCell, account.Name);
row.appendChild(nameCell);
accountsGrid.appendChild(row);
}
}
}
}
catch (e) {
alert(e.Message);
}
}
</script>
<title></title>
</head>
<body>
<label id="totalLabel"></label>
<input id="Button1" type="button" value="button" onclick="return Button1_onclick()" />
<div id="tableContainer">
<table id="accountsTable" rules="groups" summary="This table displays the accounts retrieved.">
<tbody id="accountsGrid" />
</table>
</div>
</body>
</html>
3.非同期操作は50個未満のデータを返す
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
<script src="aw_json.js" type="text/javascript"></script>
<script src="new_TestLibrary.js" type="text/javascript"></script>
<script type="text/javascript">
var totalAccountCount = 0;
function retrieveAccounts() {
clearaccountsGrid();
var req = new XMLHttpRequest();
req.open("GET", TestLibrary._ODataPath() + "AccountSet?$select=Name", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
if (this.status == 200) {
var returned = JSON.parse(this.responseText).d;
retrieveAccountsCallBack(returned.results);
}
else {
alert(_errorHandler(this).message);
}
}
};
req.send();
}
function _errorHandler(req) {
if (req.status == 12029)
{ return new Error("The attempt to connect to the server failed."); }
if (req.status == 12007)
{ return new Error("The server name could not be resolved."); }
var errorText;
try
{ errorText = JSON.parse(req.responseText).error.message.value; }
catch (e)
{ errorText = req.responseText }
return new Error("Error : " +
req.status + ": " +
req.statusText + ": " + errorText);
}
function retrieveAccountsCallBack(retrievedAccounts) {
totalAccountCount = totalAccountCount + retrievedAccounts.length;
setElementText(document.getElementById("totalLabel"), "There are " + totalAccountCount + " accounts");
var accountsGrid = document.getElementById("accountsGrid");
for (var i = 0; i < retrievedAccounts.length; i++) {
var account = retrievedAccounts[i];
var row = document.createElement("tr");
var nameCell = document.createElement("td");
setElementText(nameCell, account.Name);
row.appendChild(nameCell);
accountsGrid.appendChild(row);
}
}
function clearaccountsGrid() {
totalAccountCount = 0;
var accountsGrid = document.getElementById("accountsGrid");
for (var i = accountsGrid.rows.length - 1; i >= 0; i--) {
accountsGrid.deleteRow(i);
}
}
function setElementText(element, text) {
///<summary>
/// This function mitigates the fact that IE uses innerText and other browsers use textContent.
///</summary>
if (typeof (element.innerText) != "undefined")
{ element.innerText = text; }
else
{ element.textContent = text; }
}
function Button1_onclick() {
retrieveAccounts()
}
</script>
<title></title>
</head>
<body>
<label id="totalLabel"></label>
<input id="Button1" type="button" value="button" onclick="return Button1_onclick()" />
<div id="tableContainer">
<table id="accountsTable" rules="groups" summary="This table displays the accounts retrieved.">
<tbody id="accountsGrid" />
</table>
</div>
</body>
</html>
4.非同期操作は50以上のデータを返す
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
<script src="aw_json.js" type="text/javascript"></script>
<script src="new_TestLibrary.js" type="text/javascript"></script>
<script type="text/javascript">
var totalAccountCount = 0;
function retrieveAccounts() {
clearaccountsGrid();
var options = "$select=Name";
//The retrieveAccountsCallBack function is passed through as the successCallBack.
TestLibrary.RetrieveMultipleRecords("Account", options, retrieveAccountsCallBack, function (error) { alert(error.message); }, function () { alert("complete")});
}
function retrieveAccountsCallBack(retrievedAccounts) {
totalAccountCount = totalAccountCount + retrievedAccounts.length;
setElementText(document.getElementById("totalLabel"), "There are " + totalAccountCount + " accounts");
var accountsGrid = document.getElementById("accountsGrid");
for (var i = 0; i < retrievedAccounts.length; i++) {
var account = retrievedAccounts[i];
var row = document.createElement("tr");
var nameCell = document.createElement("td");
setElementText(nameCell, account.Name);
row.appendChild(nameCell);
accountsGrid.appendChild(row);
}
}
function clearaccountsGrid() {
totalAccountCount = 0;
var accountsGrid = document.getElementById("accountsGrid");
for (var i = accountsGrid.rows.length - 1; i >= 0; i--) {
accountsGrid.deleteRow(i);
}
}
function setElementText(element, text) {
///<summary>
/// This function mitigates the fact that IE uses innerText and other browsers use textContent.
///</summary>
if (typeof (element.innerText) != "undefined")
{ element.innerText = text; }
else
{ element.textContent = text; }
}
function Button1_onclick() {
retrieveAccounts()
}
</script>
<title></title>
</head>
<body>
<label id="totalLabel"></label>
<input id="Button1" type="button" value="button" onclick="return Button1_onclick()" />
<div id="tableContainer">
<table id="accountsTable" rules="groups" summary="This table displays the accounts retrieved.">
<tbody id="accountsGrid" />
</table>
</div>
</body>
</html>
TestLibrary.jsはSDKです.REST.jsの簡略版は、SDKも完全に使用できます.REST.js
if (typeof (TestLibrary) == "undefined") {
TestLibrary = { __namespace: true };
}
TestLibrary = {
Name: "TestLibrary",
_context: function () {
if (typeof GetGlobalContext != "undefined")
{ return GetGlobalContext(); }
else {
if (typeof Xrm != "undefined") {
return Xrm.Page.context;
}
else
{ throw new Error("Context is not available."); }
}
},
_getServerUrl: function () {
var serverUrl = TestLibrary._context().getServerUrl()
if (serverUrl.match(/\/$/)) {
serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}
return serverUrl;
},
_ODataPath: function () {
return TestLibrary._getServerUrl() + "/XRMServices/2011/OrganizationData.svc/";
},
RetrieveMultipleRecords: function (type, options, successCallback, errorCallback, OnComplete) {
var optionsString;
if (options != null) {
if (options.charAt(0) != "?") {
optionsString = "?" + options;
}
else
{ optionsString = options; }
}
var req = new XMLHttpRequest();
req.open("GET", TestLibrary._ODataPath() + type + "Set" + optionsString, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
if (this.status == 200) {
var returned = JSON.parse(this.responseText).d;
successCallback(returned.results);
if (returned.__next != null) {
var queryOptions = returned.__next.substring((TestLibrary._ODataPath() + type + "Set").length);
TestLibrary.RetrieveMultipleRecords(type, queryOptions, successCallback, errorCallback, OnComplete);
}
else
{ OnComplete(); }
}
else {
errorCallback(TestLibrary._errorHandler(this));
}
}
};
req.send();
},
_errorHandler: function (req) {
if (req.status == 12029)
{ return new Error("The attempt to connect to the server failed."); }
if (req.status == 12007)
{ return new Error("The server name could not be resolved."); }
var errorText;
try
{ errorText = JSON.parse(req.responseText).error.message.value; }
catch (e)
{ errorText = req.responseText }
return new Error("Error : " +
req.status + ": " +
req.statusText + ": " + errorText);
}
}
SDK.REST.js:
if (typeof (SDK) == "undefined")
{ SDK = { __namespace: true }; }
SDK.REST = {
_context: function () {
///<summary>
/// Private function to the context object.
///</summary>
///<returns>Context</returns>
if (typeof GetGlobalContext != "undefined")
{ return GetGlobalContext(); }
else {
if (typeof Xrm != "undefined") {
return Xrm.Page.context;
}
else
{ throw new Error("Context is not available."); }
}
},
_getServerUrl: function () {
///<summary>
/// Private function to return the server URL from the context
///</summary>
///<returns>String</returns>
var serverUrl = this._context().getServerUrl()
if (serverUrl.match(/\/$/)) {
serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}
return serverUrl;
},
_ODataPath: function () {
///<summary>
/// Private function to return the path to the REST endpoint.
///</summary>
///<returns>String</returns>
return this._getServerUrl() + "/XRMServices/2011/OrganizationData.svc/";
},
_errorHandler: function (req) {
///<summary>
/// Private function return an Error object to the errorCallback
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest response that returned an error.
///</param>
///<returns>Error</returns>
//Error descriptions come from http://support.microsoft.com/kb/193625
if (req.status == 12029)
{ return new Error("The attempt to connect to the server failed."); }
if (req.status == 12007)
{ return new Error("The server name could not be resolved."); }
var errorText;
try
{ errorText = JSON.parse(req.responseText).error.message.value; }
catch (e)
{ errorText = req.responseText }
return new Error("Error : " +
req.status + ": " +
req.statusText + ": " + errorText);
},
_dateReviver: function (key, value) {
///<summary>
/// Private function to convert matching string values to Date objects.
///</summary>
///<param name="key" type="String">
/// The key used to identify the object property
///</param>
///<param name="value" type="String">
/// The string value representing a date
///</param>
var a;
if (typeof value === 'string') {
a = /Date\(([-+]?\d+)\)/.exec(value);
if (a) {
return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10));
}
}
return value;
},
_parameterCheck: function (parameter, message) {
///<summary>
/// Private function used to check whether required parameters are null or undefined
///</summary>
///<param name="parameter" type="Object">
/// The parameter to check;
///</param>
///<param name="message" type="String">
/// The error message text to include when the error is thrown.
///</param>
if ((typeof parameter === "undefined") || parameter === null) {
throw new Error(message);
}
},
_stringParameterCheck: function (parameter, message) {
///<summary>
/// Private function used to check whether required parameters are null or undefined
///</summary>
///<param name="parameter" type="String">
/// The string parameter to check;
///</param>
///<param name="message" type="String">
/// The error message text to include when the error is thrown.
///</param>
if (typeof parameter != "string") {
throw new Error(message);
}
},
_callbackParameterCheck: function (callbackParameter, message) {
///<summary>
/// Private function used to check whether required callback parameters are functions
///</summary>
///<param name="callbackParameter" type="Function">
/// The callback parameter to check;
///</param>
///<param name="message" type="String">
/// The error message text to include when the error is thrown.
///</param>
if (typeof callbackParameter != "function") {
throw new Error(message);
}
},
createRecord: function (object, type, successCallback, errorCallback) {
///<summary>
/// Sends an asynchronous request to create a new record.
///</summary>
///<param name="object" type="Object">
/// A JavaScript object with properties corresponding to the Schema name of
/// entity attributes that are valid for create operations.
///</param>
///<param name="type" type="String">
/// The Schema Name of the Entity type record to create.
/// For an Account record, use "Account"
///</param>
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called by a successful response.
/// This function can accept the returned record as a parameter.
/// </param>
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
this._parameterCheck(object, "SDK.REST.createRecord requires the object parameter.");
this._stringParameterCheck(type, "SDK.REST.createRecord requires the type parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.REST.createRecord requires the successCallback is a function.");
this._callbackParameterCheck(errorCallback, "SDK.REST.createRecord requires the errorCallback is a function.");
var req = new XMLHttpRequest();
req.open("POST", encodeURI(this._ODataPath() + type + "Set"), true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
if (this.status == 201) {
successCallback(JSON.parse(this.responseText, SDK.REST._dateReviver).d);
}
else {
errorCallback(SDK.REST._errorHandler(this));
}
}
};
req.send(JSON.stringify(object));
},
retrieveRecord: function (id, type, select, expand, successCallback, errorCallback) {
///<summary>
/// Sends an asynchronous request to retrieve a record.
///</summary>
///<param name="id" type="String">
/// A String representing the GUID value for the record to retrieve.
///</param>
///<param name="type" type="String">
/// The Schema Name of the Entity type record to retrieve.
/// For an Account record, use "Account"
///</param>
///<param name="select" type="String">
/// A String representing the $select OData System Query Option to control which
/// attributes will be returned. This is a comma separated list of Attribute names that are valid for retrieve.
/// If null all properties for the record will be returned
///</param>
///<param name="expand" type="String">
/// A String representing the $expand OData System Query Option value to control which
/// related records are also returned. This is a comma separated list of of up to 6 entity relationship names
/// If null no expanded related records will be returned.
///</param>
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called by a successful response.
/// This function must accept the returned record as a parameter.
/// </param>
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
this._stringParameterCheck(id, "SDK.REST.retrieveRecord requires the id parameter is a string.");
this._stringParameterCheck(type, "SDK.REST.retrieveRecord requires the type parameter is a string.");
if (select != null)
this._stringParameterCheck(select, "SDK.REST.retrieveRecord requires the select parameter is a string.");
if (expand != null)
this._stringParameterCheck(expand, "SDK.REST.retrieveRecord requires the expand parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.REST.retrieveRecord requires the successCallback parameter is a function.");
this._callbackParameterCheck(errorCallback, "SDK.REST.retrieveRecord requires the errorCallback parameter is a function.");
var systemQueryOptions = "";
if (select != null || expand != null) {
systemQueryOptions = "?";
if (select != null) {
var selectString = "$select=" + select;
if (expand != null) {
selectString = selectString + "," + expand;
}
systemQueryOptions = systemQueryOptions + selectString;
}
if (expand != null) {
systemQueryOptions = systemQueryOptions + "&$expand=" + expand;
}
}
var req = new XMLHttpRequest();
req.open("GET", encodeURI(this._ODataPath() + type + "Set(guid'" + id + "')" + systemQueryOptions), true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
if (this.status == 200) {
successCallback(JSON.parse(this.responseText, SDK.REST._dateReviver).d);
}
else {
errorCallback(SDK.REST._errorHandler(this));
}
}
};
req.send();
},
updateRecord: function (id, object, type, successCallback, errorCallback) {
///<summary>
/// Sends an asynchronous request to update a record.
///</summary>
///<param name="id" type="String">
/// A String representing the GUID value for the record to retrieve.
///</param>
///<param name="object" type="Object">
/// A JavaScript object with properties corresponding to the Schema Names for
/// entity attributes that are valid for update operations.
///</param>
///<param name="type" type="String">
/// The Schema Name of the Entity type record to retrieve.
/// For an Account record, use "Account"
///</param>
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called by a successful response.
/// Nothing will be returned to this function.
/// </param>
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
this._stringParameterCheck(id, "SDK.REST.updateRecord requires the id parameter.");
this._parameterCheck(object, "SDK.REST.updateRecord requires the object parameter.");
this._stringParameterCheck(type, "SDK.REST.updateRecord requires the type parameter.");
this._callbackParameterCheck(successCallback, "SDK.REST.updateRecord requires the successCallback is a function.");
this._callbackParameterCheck(errorCallback, "SDK.REST.updateRecord requires the errorCallback is a function.");
var req = new XMLHttpRequest();
req.open("POST", encodeURI(this._ODataPath() + type + "Set(guid'" + id + "')"), true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("X-HTTP-Method", "MERGE");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
if (this.status == 204 || this.status == 1223) {
successCallback();
}
else {
errorCallback(SDK.REST._errorHandler(this));
}
}
};
req.send(JSON.stringify(object));
},
deleteRecord: function (id, type, successCallback, errorCallback) {
///<summary>
/// Sends an asynchronous request to delete a record.
///</summary>
///<param name="id" type="String">
/// A String representing the GUID value for the record to delete.
///</param>
///<param name="type" type="String">
/// The Schema Name of the Entity type record to delete.
/// For an Account record, use "Account"
///</param>
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called by a successful response.
/// Nothing will be returned to this function.
/// </param>
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
this._stringParameterCheck(id, "SDK.REST.deleteRecord requires the id parameter.");
this._stringParameterCheck(type, "SDK.REST.deleteRecord requires the type parameter.");
this._callbackParameterCheck(successCallback, "SDK.REST.deleteRecord requires the successCallback is a function.");
this._callbackParameterCheck(errorCallback, "SDK.REST.deleteRecord requires the errorCallback is a function.");
var req = new XMLHttpRequest();
req.open("POST", encodeURI(this._ODataPath() + type + "Set(guid'" + id + "')"), true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("X-HTTP-Method", "DELETE");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
if (this.status == 204 || this.status == 1223) {
successCallback();
}
else {
errorCallback(SDK.REST._errorHandler(this));
}
}
};
req.send();
},
retrieveMultipleRecords: function (type, options, successCallback, errorCallback, OnComplete) {
///<summary>
/// Sends an asynchronous request to retrieve records.
///</summary>
///<param name="type" type="String">
/// The Schema Name of the Entity type record to retrieve.
/// For an Account record, use "Account"
///</param>
///<param name="options" type="String">
/// A String representing the OData System Query Options to control the data returned
///</param>
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called for each page of records returned.
/// Each page is 50 records. If you expect that more than one page of records will be returned,
/// this function should loop through the results and push the records into an array outside of the function.
/// Use the OnComplete event handler to know when all the records have been processed.
/// </param>
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
///<param name="OnComplete" type="Function">
/// The function that will be called when all the requested records have been returned.
/// No parameters are passed to this function.
/// </param>
this._stringParameterCheck(type, "SDK.REST.retrieveMultipleRecords requires the type parameter is a string.");
if (options != null)
this._stringParameterCheck(options, "SDK.REST.retrieveMultipleRecords requires the options parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.REST.retrieveMultipleRecords requires the successCallback parameter is a function.");
this._callbackParameterCheck(errorCallback, "SDK.REST.retrieveMultipleRecords requires the errorCallback parameter is a function.");
this._callbackParameterCheck(OnComplete, "SDK.REST.retrieveMultipleRecords requires the OnComplete parameter is a function.");
var optionsString;
if (options != null) {
if (options.charAt(0) != "?") {
optionsString = "?" + options;
}
else
{ optionsString = options; }
}
var req = new XMLHttpRequest();
req.open("GET", this._ODataPath() + type + "Set" + optionsString, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
if (this.status == 200) {
var returned = JSON.parse(this.responseText, SDK.REST._dateReviver).d;
successCallback(returned.results);
if (returned.__next != null) {
var queryOptions = returned.__next.substring((SDK.REST._ODataPath() + type + "Set").length);
SDK.REST.retrieveMultipleRecords(type, queryOptions, successCallback, errorCallback, OnComplete);
}
else
{ OnComplete(); }
}
else {
errorCallback(SDK.REST._errorHandler(this));
}
}
};
req.send();
},
associateRecords: function (parentId, parentType, relationshipName, childId, childType, successCallback, errorCallback) {
this._stringParameterCheck(parentId, "SDK.REST.associateRecords requires the parentId parameter is a string.");
///<param name="parentId" type="String">
/// The Id of the record to be the parent record in the relationship
/// </param>
///<param name="parentType" type="String">
/// The Schema Name of the Entity type for the parent record.
/// For an Account record, use "Account"
/// </param>
///<param name="relationshipName" type="String">
/// The Schema Name of the Entity Relationship to use to associate the records.
/// To associate account records as a Parent account, use "Referencedaccount_parent_account"
/// </param>
///<param name="childId" type="String">
/// The Id of the record to be the child record in the relationship
/// </param>
///<param name="childType" type="String">
/// The Schema Name of the Entity type for the child record.
/// For an Account record, use "Account"
/// </param>
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called by a successful response.
/// Nothing will be returned to this function.
/// </param>
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
this._stringParameterCheck(parentType, "SDK.REST.associateRecords requires the parentType parameter is a string.");
this._stringParameterCheck(relationshipName, "SDK.REST.associateRecords requires the relationshipName parameter is a string.");
this._stringParameterCheck(childId, "SDK.REST.associateRecords requires the childId parameter is a string.");
this._stringParameterCheck(childType, "SDK.REST.associateRecords requires the childType parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.REST.associateRecords requires the successCallback parameter is a function.");
this._callbackParameterCheck(errorCallback, "SDK.REST.associateRecords requires the errorCallback parameter is a function.");
var req = new XMLHttpRequest();
req.open("POST", encodeURI(this._ODataPath() + parentType + "Set(guid'" + parentId + "')/$links/" + relationshipName), true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
if (this.status == 204 || this.status == 1223) {
successCallback();
}
else {
errorCallback(SDK.REST._errorHandler(this));
}
}
};
var childEntityReference = {}
childEntityReference.uri = this._ODataPath() + "/" + childType + "Set(guid'" + childId + "')";
req.send(JSON.stringify(childEntityReference));
},
disassociateRecords: function (parentId, parentType, relationshipName, childId, successCallback, errorCallback) {
this._stringParameterCheck(parentId, "SDK.REST.disassociateRecords requires the parentId parameter is a string.");
///<param name="parentId" type="String">
/// The Id of the record to be the parent record in the relationship
/// </param>
///<param name="parentType" type="String">
/// The Schema Name of the Entity type for the parent record.
/// For an Account record, use "Account"
/// </param>
///<param name="relationshipName" type="String">
/// The Schema Name of the Entity Relationship to use to disassociate the records.
/// To disassociate account records as a Parent account, use "Referencedaccount_parent_account"
/// </param>
///<param name="childId" type="String">
/// The Id of the record to be disassociated as the child record in the relationship
/// </param>
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called by a successful response.
/// Nothing will be returned to this function.
/// </param>
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
this._stringParameterCheck(parentType, "SDK.REST.disassociateRecords requires the parentType parameter is a string.");
this._stringParameterCheck(relationshipName, "SDK.REST.disassociateRecords requires the relationshipName parameter is a string.");
this._stringParameterCheck(childId, "SDK.REST.disassociateRecords requires the childId parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.REST.disassociateRecords requires the successCallback parameter is a function.");
this._callbackParameterCheck(errorCallback, "SDK.REST.disassociateRecords requires the errorCallback parameter is a function.");
var req = new XMLHttpRequest();
req.open("POST", encodeURI(this._ODataPath() + parentType + "Set(guid'" + parentId + "')/$links/" + relationshipName + "(guid'" + childId + "')"), true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("X-HTTP-Method", "DELETE");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
if (this.status == 204 || this.status == 1223) {
successCallback();
}
else {
errorCallback(SDK.REST._errorHandler(this));
}
}
};
req.send();
},
__namespace: true
};
(二)JQuery
JQueryはAJAXを使用しているので、すべて非同期操作です.以下の例ではSDKをそのまま用いる.JQuery.js
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
<script src="aw_json.js" type="text/javascript"></script>
<script src="new_jquery.js" type="text/javascript"></script>
<script src="new_sdk.jquery.js" type="text/javascript"></script>
<script type="text/javascript">
var totalAccountCount = 0;
function retrieveAccounts() {
clearaccountsGrid();
SDK.JQuery.retrieveMultipleRecords(
"Account",
"$select=Name",
retrieveAccountsCallBack,
function (error) {
alert(error.message);
},
function () {
alert("complete");
}
);
}
function retrieveAccountsCallBack(retrievedAccounts) {
totalAccountCount = totalAccountCount + retrievedAccounts.length;
setElementText(document.getElementById("totalLabel"), "There are " + totalAccountCount + " accounts");
var accountsGrid = document.getElementById("accountsGrid");
for (var i = 0; i < retrievedAccounts.length; i++) {
var account = retrievedAccounts[i];
var row = document.createElement("tr");
var nameCell = document.createElement("td");
setElementText(nameCell, account.Name);
row.appendChild(nameCell);
accountsGrid.appendChild(row);
}
}
function clearaccountsGrid() {
totalAccountCount = 0;
var accountsGrid = document.getElementById("accountsGrid");
for (var i = accountsGrid.rows.length - 1; i >= 0; i--) {
accountsGrid.deleteRow(i);
}
}
function setElementText(element, text) {
///<summary>
/// This function mitigates the fact that IE uses innerText and other browsers use textContent.
///</summary>
if (typeof (element.innerText) != "undefined")
{ element.innerText = text; }
else
{ element.textContent = text; }
}
function Button1_onclick() {
retrieveAccounts()
}
</script>
<title></title>
</head>
<body>
<label id="totalLabel"></label>
<input id="Button1" type="button" value="button" onclick="return Button1_onclick()" />
<div id="tableContainer">
<table id="accountsTable" rules="groups" summary="This table displays the accounts retrieved.">
<tbody id="accountsGrid" />
</table>
</div>
</body>
</html>
SDK.JQuery.js
/// <reference path="jquery1.4.1vsdoc.js" />
if (typeof (SDK) == "undefined")
{ SDK = { __namespace: true }; }
SDK.JQuery = {
_context: function () {
///<summary>
/// Private function to the context object.
///</summary>
///<returns>Context</returns>
if (typeof GetGlobalContext != "undefined")
{ return GetGlobalContext(); }
else {
if (typeof Xrm != "undefined") {
return Xrm.Page.context;
}
else
{ throw new Error("Context is not available."); }
}
},
_getServerUrl: function () {
///<summary>
/// Private function to return the server URL from the context
///</summary>
///<returns>String</returns>
var serverUrl = this._context().getServerUrl()
if (serverUrl.match(/\/$/)) {
serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}
return serverUrl;
},
_ODataPath: function () {
///<summary>
/// Private function to return the path to the REST endpoint.
///</summary>
///<returns>String</returns>
return this._getServerUrl() + "/XRMServices/2011/OrganizationData.svc/";
},
_errorHandler: function (req) {
///<summary>
/// Private function return an Error object to the errorCallback
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest response that returned an error.
///</param>
///<returns>Error</returns>
return new Error("Error : " +
req.status + ": " +
req.statusText + ": " +
JSON.parse(req.responseText).error.message.value);
},
_dateReviver: function (key, value) {
///<summary>
/// Private function to convert matching string values to Date objects.
///</summary>
///<param name="key" type="String">
/// The key used to identify the object property
///</param>
///<param name="value" type="String">
/// The string value representing a date
///</param>
var a;
if (typeof value === 'string') {
a = /Date\(([-+]?\d+)\)/.exec(value);
if (a) {
return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10));
}
}
return value;
},
_parameterCheck: function (parameter, message) {
///<summary>
/// Private function used to check whether required parameters are null or undefined
///</summary>
///<param name="parameter" type="Object">
/// The parameter to check;
///</param>
///<param name="message" type="String">
/// The error message text to include when the error is thrown.
///</param>
if ((typeof parameter === "undefined") || parameter === null) {
throw new Error(message);
}
},
_stringParameterCheck: function (parameter, message) {
///<summary>
/// Private function used to check whether required parameters are null or undefined
///</summary>
///<param name="parameter" type="String">
/// The string parameter to check;
///</param>
///<param name="message" type="String">
/// The error message text to include when the error is thrown.
///</param>
if (typeof parameter != "string") {
throw new Error(message);
}
},
_callbackParameterCheck: function (callbackParameter, message) {
///<summary>
/// Private function used to check whether required callback parameters are functions
///</summary>
///<param name="callbackParameter" type="Function">
/// The callback parameter to check;
///</param>
///<param name="message" type="String">
/// The error message text to include when the error is thrown.
///</param>
if (typeof callbackParameter != "function") {
throw new Error(message);
}
},
createRecord: function (object, type, successCallback, errorCallback) {
///<summary>
/// Sends an asynchronous request to create a new record.
///</summary>
///<param name="object" type="Object">
/// A JavaScript object with properties corresponding to the Schema name of
/// entity attributes that are valid for create operations.
///</param>
this._parameterCheck(object, "SDK.JQuery.createRecord requires the object parameter.");
///<param name="type" type="String">
/// The Schema Name of the Entity type record to create.
/// For an Account record, use "Account"
///</param>
this._stringParameterCheck(type, "SDK.JQuery.createRecord requires the type parameter is a string.");
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called by a successful response.
/// This function can accept the returned record as a parameter.
/// </param>
this._callbackParameterCheck(successCallback, "SDK.JQuery.createRecord requires the successCallback is a function.");
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
this._callbackParameterCheck(errorCallback, "SDK.JQuery.createRecord requires the errorCallback is a function.");
var jsonEntity = window.JSON.stringify(object);
$.ajax({ type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: this._ODataPath() + type + "Set",
data: jsonEntity,
beforeSend: function (xhr) {
//Specifying this header ensures that the results will be returned as JSON.
xhr.setRequestHeader("Accept", "application/json");
},
success: function (data, textStatus, xhr) {
successCallback(data.d);
},
error: function (xhr, textStatus, errorThrown) {
errorCallback(SDK.JQuery._errorHandler(xhr));
}
});
},
retrieveRecord: function (id, type, select, expand, successCallback, errorCallback) {
///<summary>
/// Sends an asynchronous request to retrieve a record.
///</summary>
///<param name="id" type="String">
/// A String representing the GUID value for the record to retrieve.
///</param>
this._stringParameterCheck(id, "SDK.JQuery.retrieveRecord requires the id parameter is a string.");
///<param name="type" type="String">
/// The Schema Name of the Entity type record to retrieve.
/// For an Account record, use "Account"
///</param>
this._stringParameterCheck(type, "SDK.JQuery.retrieveRecord requires the type parameter is a string.");
///<param name="select" type="String">
/// A String representing the $select OData System Query Option to control which
/// attributes will be returned. This is a comma separated list of Attribute names that are valid for retrieve.
/// If null all properties for the record will be returned
///</param>
if (select != null)
this._stringParameterCheck(select, "SDK.JQuery.retrieveRecord requires the select parameter is a string.");
///<param name="expand" type="String">
/// A String representing the $expand OData System Query Option value to control which
/// related records are also returned. This is a comma separated list of of up to 6 entity relationship names
/// If null no expanded related records will be returned.
///</param>
if (expand != null)
this._stringParameterCheck(expand, "SDK.JQuery.retrieveRecord requires the expand parameter is a string.");
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called by a successful response.
/// This function must accept the returned record as a parameter.
/// </param>
this._callbackParameterCheck(successCallback, "SDK.JQuery.retrieveRecord requires the successCallback parameter is a function.");
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
this._callbackParameterCheck(errorCallback, "SDK.JQuery.retrieveRecord requires the errorCallback parameter is a function.");
var systemQueryOptions = "";
if (select != null || expand != null) {
systemQueryOptions = "?";
if (select != null) {
var selectString = "$select=" + select;
if (expand != null) {
selectString = selectString + "," + expand;
}
systemQueryOptions = systemQueryOptions + selectString;
}
if (expand != null) {
systemQueryOptions = systemQueryOptions + "&$expand=" + expand;
}
}
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: this._ODataPath() + type + "Set" + "(guid'" + id + "')" + systemQueryOptions,
beforeSend: function (xhr) {
//Specifying this header ensures that the results will be returned as JSON.
xhr.setRequestHeader("Accept", "application/json");
},
success: function (data, textStatus, xhr) {
//JQuery does not provide an opportunity to specify a date reviver so this code
// parses the xhr.responseText rather than use the data parameter passed by JQuery.
successCallback(JSON.parse(xhr.responseText, SDK.JQuery._dateReviver).d);
},
error: function (xhr, textStatus, errorThrown) {
errorCallback(SDK.JQuery._errorHandler(xhr));
}
});
},
updateRecord: function (id, object, type, successCallback, errorCallback) {
///<summary>
/// Sends an asynchronous request to update a record.
///</summary>
///<param name="id" type="String">
/// A String representing the GUID value for the record to retrieve.
///</param>
this._stringParameterCheck(id, "SDK.JQuery.updateRecord requires the id parameter.");
///<param name="object" type="Object">
/// A JavaScript object with properties corresponding to the Schema Names for
/// entity attributes that are valid for update operations.
///</param>
this._parameterCheck(object, "SDK.JQuery.updateRecord requires the object parameter.");
///<param name="type" type="String">
/// The Schema Name of the Entity type record to retrieve.
/// For an Account record, use "Account"
///</param>
this._stringParameterCheck(type, "SDK.JQuery.updateRecord requires the type parameter.");
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called by a successful response.
/// Nothing will be returned to this function.
/// </param>
this._callbackParameterCheck(successCallback, "SDK.JQuery.updateRecord requires the successCallback is a function.");
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
this._callbackParameterCheck(errorCallback, "SDK.JQuery.updateRecord requires the errorCallback is a function.");
var jsonEntity = window.JSON.stringify(object);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
data: jsonEntity,
url: this._ODataPath() + type + "Set" + "(guid'" + id + "')",
beforeSend: function (xhr) {
//Specifying this header ensures that the results will be returned as JSON.
xhr.setRequestHeader("Accept", "application/json");
//Specify the HTTP method MERGE to update just the changes you are submitting.
xhr.setRequestHeader("X-HTTP-Method", "MERGE");
},
success: function (data, textStatus, xhr) {
//Nothing is returned to the success function
successCallback();
},
error: function (xhr, textStatus, errorThrown) {
errorCallback(SDK.JQuery._errorHandler(xhr));
}
});
},
deleteRecord: function (id, type, successCallback, errorCallback) {
///<summary>
/// Sends an asynchronous request to delete a record.
///</summary>
///<param name="id" type="String">
/// A String representing the GUID value for the record to delete.
///</param>
this._stringParameterCheck(id, "SDK.JQuery.deleteRecord requires the id parameter.");
///<param name="type" type="String">
/// The Schema Name of the Entity type record to delete.
/// For an Account record, use "Account"
///</param>
this._stringParameterCheck(type, "SDK.JQuery.deleteRecord requires the type parameter.");
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called by a successful response.
/// Nothing will be returned to this function.
/// </param>
this._callbackParameterCheck(successCallback, "SDK.JQuery.deleteRecord requires the successCallback is a function.");
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
this._callbackParameterCheck(errorCallback, "SDK.JQuery.deleteRecord requires the errorCallback is a function.");
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: this._ODataPath() + type + "Set(guid'" + id + "')",
beforeSend: function (XMLHttpRequest) {
//Specifying this header ensures that the results will be returned as JSON.
XMLHttpRequest.setRequestHeader("Accept", "application/json");
//Specify the HTTP method DELETE to perform a delete operation.
XMLHttpRequest.setRequestHeader("X-HTTP-Method", "DELETE");
},
success: function (data, textStatus, xhr) {
// Nothing is returned to the success function.
successCallback();
},
error: function (xhr, textStatus, errorThrown) {
errorCallback(SDK.JQuery._errorHandler(xhr));
}
});
},
retrieveMultipleRecords: function (type, options, successCallback, errorCallback, OnComplete) {
///<summary>
/// Sends an asynchronous request to retrieve records.
///</summary>
///<param name="type" type="String">
/// The Schema Name of the Entity type records to retrieve
/// For an Account record, use "Account"
///</param>
this._stringParameterCheck(type, "SDK.JQuery.retrieveMultipleRecords requires the type parameter is a string.");
///<param name="options" type="String">
/// A String representing the OData System Query Options to control the data returned
/// Do not include the $top option, use the top parameters to set the maximum number of records to return.
///</param>
if (options != null)
this._stringParameterCheck(options, "SDK.JQuery.retrieveMultipleRecords requires the options parameter is a string.");
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called for each page of records returned.
/// This function should loop through the results and push the records into an array.
/// </param>
this._callbackParameterCheck(successCallback, "SDK.JQuery.retrieveMultipleRecords requires the successCallback parameter is a function.");
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
this._callbackParameterCheck(errorCallback, "SDK.JQuery.retrieveMultipleRecords requires the errorCallback parameter is a function.");
///<param name="OnComplete" type="Function">
/// The function that will be called when all the requested records have been returned.
/// No parameters are passed to this function.
/// </param>
this._callbackParameterCheck(OnComplete, "SDK.JQuery.retrieveMultipleRecords requires the OnComplete parameter is a function.");
var optionsString;
if (options != null) {
if (options.charAt(0) != "?") {
optionsString = "?" + options;
}
else
{ optionsString = options; }
}
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: this._ODataPath() + type + "Set" + optionsString,
beforeSend: function (XMLHttpRequest) {
//Specifying this header ensures that the results will be returned as JSON.
XMLHttpRequest.setRequestHeader("Accept", "application/json");
},
success: function (data, textStatus, xhr) {
if (data && data.d && data.d.results) {
successCallback(JSON.parse(xhr.responseText, SDK.JQuery._dateReviver).d.results);
if (data.d.__next != null) {
var queryOptions = data.d.__next.substring((SDK.JQuery._ODataPath() + type + "Set").length);
SDK.JQuery.retrieveMultipleRecords(type, queryOptions, successCallback, errorCallback, OnComplete);
}
else
{ OnComplete(); }
}
},
error: function (xhr, textStatus, errorThrown) {
errorCallback(SDK.JQuery._errorHandler(xhr));
}
});
},
__namespace: true
};
(三)Silverlight
Silverlightは非同期操作を使用しています.Silverlightプログラムの作成方法を参照.
1.50個未満のレコードを返す
<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SilverlightApplication2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SilverlightApplication2"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel x:Name="MessagePanel" VerticalAlignment="Top">
<sdk:Label x:Name="myLabel" Content=""/>
<sdk:DataGrid x:Name="myDataGrid" AutoGenerateColumns="False" IsReadOnly="True" >
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn x:Name="FirstNameColumn" Header="First Name" Binding="{Binding FirstName, Mode=OneTime}" />
<sdk:DataGridTextColumn x:Name="LastNameColumn" Header="Last Name" Binding="{Binding LastName, Mode=OneTime}" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</StackPanel>
</Grid>
</UserControl>
using System;
using System.Data.Services.Client;
using System.Linq;
using System.Threading;
using System.Windows.Controls;
using SilverlightApplication2.CrmODataService;
using SilverlightApplication2.Utilities;
namespace SilverlightApplication2
{
public partial class MainPage : UserControl
{
private SynchronizationContext _syncContext;
private escrmContext _context;
private String _serverUrl;
public MainPage()
{
InitializeComponent();
//Keeps a reference to the UI thread
_syncContext = SynchronizationContext.Current;
//Get the ServerUrl (ServerUrl is formatted differently OnPremise than OnLine)
_serverUrl = ServerUtility.GetServerUrl();
if (!String.IsNullOrEmpty(_serverUrl))
{
//Setup Context
_context = new escrmContext(new Uri(String.Format("{0}/xrmservices/2011/organizationdata.svc/",
_serverUrl), UriKind.Absolute));
//This is important because if the entity has new
//attributes added the code will fail.
_context.IgnoreMissingProperties = true;
SearchContacts();
}
else
{
//No ServerUrl was found. Display message.
MessagePanel.Children.Add(new TextBlock()
{
Text =
"Unable to access server url. Launch this Silverlight " +
"Web Resource from a CRM Form OR host it in a valid " +
"HTML Web Resource with a " +
"<script src='ClientGlobalContext.js.aspx' " +
"type='text/javascript'></script>"
});
}
}
private void SearchContacts()
{
DataServiceQuery<Contact> query = (DataServiceQuery<Contact>)_context.ContactSet.Where(x => x.StateCode.Value.Value == 0);
query.BeginExecute(OnContactSearchComplete, query);
}
private void OnContactSearchComplete(IAsyncResult result)
{
try
{
//Get the original query back from the result.
DataServiceQuery<Contact> query = result.AsyncState as DataServiceQuery<Contact>;
var itemsource = new DataServiceCollection<Contact>(query.EndExecute(result));
this.myDataGrid.ItemsSource = itemsource;
myLabel.Content = "There are " + itemsource.Count + " contacts";
}
catch (SystemException se)
{
_syncContext.Send(new SendOrPostCallback(showErrorDetails), se);
}
}
private void showErrorDetails(object ex)
{
//Assure the control is visible
MessagePanel.Visibility = System.Windows.Visibility.Visible;
Exception exception = (Exception)ex;
String type = exception.GetType().ToString();
MessagePanel.Children.Add(new TextBlock()
{
Text =
String.Format("{0} Message: {1}", type, exception.Message)
});
MessagePanel.Children.Add(new TextBlock()
{
Text =
String.Format("Stack: {0}", exception.StackTrace)
});
if (exception.InnerException != null)
{
String exceptType = exception.InnerException.GetType().ToString();
MessagePanel.Children.Add(new TextBlock()
{
Text =
String.Format("InnerException: {0} : {1}", exceptType,
exception.InnerException.Message)
});
}
}
}
}
2.50以上のレコードを返す
<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SilverlightApplication2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel x:Name="MessagePanel" VerticalAlignment="Top" Height="145">
<sdk:Label x:Name="myLabel" Content=""/>
</StackPanel>
<sdk:DataGrid x:Name="myDataGrid" AutoGenerateColumns="False" IsReadOnly="True" ScrollViewer.VerticalScrollBarVisibility="Visible" Margin="0,71,0,0">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn x:Name="FirstNameColumn" Header="First Name" Binding="{Binding FirstName, Mode=OneTime}" />
<sdk:DataGridTextColumn x:Name="LastNameColumn" Header="Last Name" Binding="{Binding LastName, Mode=OneTime}" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</Grid>
</UserControl>
using System;
using System.Data.Services.Client;
using System.Linq;
using System.Threading;
using System.Windows.Controls;
using SilverlightApplication2.CrmODataService;
using SilverlightApplication2.Utilities;
namespace SilverlightApplication2
{
public partial class MainPage : UserControl
{
private SynchronizationContext _syncContext;
private escrmContext _context;
private String _serverUrl;
public DataServiceCollection<Contact> ContactCollection;
public MainPage()
{
InitializeComponent();
//Keeps a reference to the UI thread
_syncContext = SynchronizationContext.Current;
//Get the ServerUrl (ServerUrl is formatted differently OnPremise than OnLine)
_serverUrl = ServerUtility.GetServerUrl();
if (!String.IsNullOrEmpty(_serverUrl))
{
//Setup Context
_context = new escrmContext(new Uri(String.Format("{0}/xrmservices/2011/organizationdata.svc/",
_serverUrl), UriKind.Absolute));
//This is important because if the entity has new
//attributes added the code will fail.
_context.IgnoreMissingProperties = true;
SearchContacts();
}
else
{
//No ServerUrl was found. Display message.
MessagePanel.Children.Add(new TextBlock()
{
Text =
"Unable to access server url. Launch this Silverlight " +
"Web Resource from a CRM Form OR host it in a valid " +
"HTML Web Resource with a " +
"<script src='ClientGlobalContext.js.aspx' " +
"type='text/javascript'></script>"
});
}
}
private void SearchContacts()
{
DataServiceQuery<Contact> query = (DataServiceQuery<Contact>)_context.ContactSet.AddQueryOption("$select", "FirstName,LastName").Where(x => x.StateCode.Value.Value == 0);
query.BeginExecute(ProcessPages<Contact>, new PagingContext<Contact>()
{
ServiceContext = _context,
Query = query,
PageProcessor = delegate(DataServiceCollection<Contact> results)
{
try
{
if (null == ContactCollection)
{
ContactCollection = new DataServiceCollection<Contact>(_context);
ContactCollection.Load(results);
}
else
{
for (int i = 0; i < results.Count; i++)
{
ContactCollection.Add(results[i]);
}
}
myLabel.Content = "There are " + ContactCollection.Count + " contacts";
this.myDataGrid.ItemsSource = ContactCollection;
}
catch (Exception ex)
{
_syncContext.Send(new SendOrPostCallback(showErrorDetails), ex);
}
return true;
}
});
}
private void ProcessPages<T>(IAsyncResult result)
{
try
{
PagingContext<T> context = (PagingContext<T>)result.AsyncState;
QueryOperationResponse<T> response;
if (null == context.Query)
{
response = (QueryOperationResponse<T>)context.ServiceContext.EndExecute<T>(result);
}
else
{
response = (QueryOperationResponse<T>)context.Query.EndExecute(result);
context.Query = null;
}
DataServiceCollection<T> results = new DataServiceCollection<T>(response);
if (null != context.PageProcessor && !context.PageProcessor(results))
{
//Stop processing
return;
}
DataServiceQueryContinuation<T> token = results.Continuation;
if (null == token)
{
System.Windows.MessageBox.Show("complete");
return;
}
context.ServiceContext.BeginExecute(token, ProcessPages<T>, context);
}
catch (Exception ex)
{
throw ex;
}
}
private void showErrorDetails(object ex)
{
//Assure the control is visible
MessagePanel.Visibility = System.Windows.Visibility.Visible;
Exception exception = (Exception)ex;
String type = exception.GetType().ToString();
MessagePanel.Children.Add(new TextBlock()
{
Text =
String.Format("{0} Message: {1}", type, exception.Message)
});
MessagePanel.Children.Add(new TextBlock()
{
Text =
String.Format("Stack: {0}", exception.StackTrace)
});
if (exception.InnerException != null)
{
String exceptType = exception.InnerException.GetType().ToString();
MessagePanel.Children.Add(new TextBlock()
{
Text =
String.Format("InnerException: {0} : {1}", exceptType,
exception.InnerException.Message)
});
}
}
}
sealed class PagingContext<T>
{
public DataServiceContext ServiceContext { get; set; }
public DataServiceQuery<T> Query { get; set; }
public Func<DataServiceCollection<T>, bool> PageProcessor { get; set; }
}
}
(四)LINQ
using System;
using Microsoft.Xrm.Sdk.Discovery;
using Microsoft.Xrm.Sdk.Client;
using System.Configuration;
using Microsoft.Xrm.Sdk;
using Microsoft.Crm.Sdk.Messages;
using System.Linq;
namespace CRM.LINQTest
{
class Program
{
static void Main(string[] args)
{
string _discoveryServiceAddress = ConfigurationManager.AppSettings["DiscoveryServiceAddress"];
IServiceManagement<IDiscoveryService> serviceManagement = ServiceConfigurationFactory.CreateManagement<IDiscoveryService>(new Uri(_discoveryServiceAddress));
AuthenticationProviderType endpointType = serviceManagement.AuthenticationType;
AuthenticationCredentials authCredentials = GetCredentials(endpointType);
String organizationUri = ConfigurationManager.AppSettings["OrganizationServiceAddress"];
if (!String.IsNullOrWhiteSpace(organizationUri))
{
IServiceManagement<IOrganizationService> orgServiceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(organizationUri));
// Set the credentials.
AuthenticationCredentials credentials = GetCredentials(endpointType);
// Get the organization service proxy.
using (OrganizationServiceProxy organizationProxy = GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials))
{
// This statement is required to enable early-bound type support.
organizationProxy.EnableProxyTypes();
IOrganizationService _service = (IOrganizationService)organizationProxy;
ServiceContext svcContext = new ServiceContext(_service);
var accounts = (from a in svcContext.AccountSet
select new Account()
{
Name = a.Name,
}).ToArray();
int i = 1;
foreach (var a in accounts)
{
Console.WriteLine(string.Format("{0}/{2}: {1}", i, a.Name, accounts.Count()));
i++;
}
}
}
}
private static AuthenticationCredentials GetCredentials(AuthenticationProviderType endpointType)
{
string _userName = ConfigurationManager.AppSettings["UserName"];
string _password = ConfigurationManager.AppSettings["Password"];
string _domain = ConfigurationManager.AppSettings["Domain"];
AuthenticationCredentials authCredentials = new AuthenticationCredentials();
switch (endpointType)
{
case AuthenticationProviderType.ActiveDirectory:
authCredentials.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(_userName, _password, _domain);
break;
case AuthenticationProviderType.Federation:
case AuthenticationProviderType.OnlineFederation:
authCredentials.ClientCredentials.UserName.UserName = _userName;
authCredentials.ClientCredentials.UserName.Password = _password;
break;
default:
break;
}
return authCredentials;
}
private static TProxy GetProxy<TService, TProxy>(IServiceManagement<TService> serviceManagement, AuthenticationCredentials authCredentials)
where TService : class
where TProxy : ServiceProxy<TService>
{
Type classType = typeof(TProxy);
if (serviceManagement.AuthenticationType != AuthenticationProviderType.ActiveDirectory)
{
AuthenticationCredentials tokenCredentials = serviceManagement.Authenticate(authCredentials);
// Obtain discovery/organization service proxy for Federated, LiveId and OnlineFederated environments.
// Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and SecurityTokenResponse.
return (TProxy)classType
.GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(SecurityTokenResponse) })
.Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse });
}
// Obtain discovery/organization service proxy for ActiveDirectory environment.
// Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and ClientCredentials.
return (TProxy)classType
.GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(System.ServiceModel.Description.ClientCredentials) })
.Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials });
}
}
}
(五)FetchXML
using System;
using Microsoft.Xrm.Sdk.Discovery;
using Microsoft.Xrm.Sdk.Client;
using System.Configuration;
using Microsoft.Xrm.Sdk;
using Microsoft.Crm.Sdk.Messages;
using System.Linq;
using System.IO;
using System.Xml;
using System.Text;
namespace CRM.FetchXMLTest
{
class Program
{
private static string CreateXml(string xml, int page)
{
StringReader stringReader = new StringReader(xml);
XmlTextReader reader = new XmlTextReader(stringReader);
// Load document
XmlDocument doc = new XmlDocument();
doc.Load(reader);
return CreateXml(doc, page);
}
private static string CreateXml(XmlDocument doc, int page)
{
XmlAttributeCollection attrs = doc.DocumentElement.Attributes;
XmlAttribute pageAttr = doc.CreateAttribute("page");
pageAttr.Value = System.Convert.ToString(page);
attrs.Append(pageAttr);
StringBuilder sb = new StringBuilder(1024);
StringWriter stringWriter = new StringWriter(sb);
XmlTextWriter writer = new XmlTextWriter(stringWriter);
doc.WriteTo(writer);
writer.Close();
return sb.ToString();
}
static void Main(string[] args)
{
string _discoveryServiceAddress = ConfigurationManager.AppSettings["DiscoveryServiceAddress"];
IServiceManagement<IDiscoveryService> serviceManagement = ServiceConfigurationFactory.CreateManagement<IDiscoveryService>(new Uri(_discoveryServiceAddress));
AuthenticationProviderType endpointType = serviceManagement.AuthenticationType;
AuthenticationCredentials authCredentials = GetCredentials(endpointType);
String organizationUri = ConfigurationManager.AppSettings["OrganizationServiceAddress"];
if (!String.IsNullOrWhiteSpace(organizationUri))
{
IServiceManagement<IOrganizationService> orgServiceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(organizationUri));
// Set the credentials.
AuthenticationCredentials credentials = GetCredentials(endpointType);
// Get the organization service proxy.
using (OrganizationServiceProxy organizationProxy = GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials))
{
//organizationProxy.Timeout = new TimeSpan(1, 0, 0, 0);
string fetch2 = @"<fetch mapping='logical'>
<entity name='account'>
<attribute name='accountid'/>
<attribute name='name'/>
</entity>
</fetch> ";
int i = 1;
// Initialize the page number.
int pageNumber = 1;
while (true)
{
// Build fetchXml string with the placeholders.
string xml = CreateXml(fetch2, pageNumber);
EntityCollection returnCollection = organizationProxy.RetrieveMultiple(new Microsoft.Xrm.Sdk.Query.FetchExpression(xml));
foreach (var a in returnCollection.Entities)
{
Console.WriteLine(string.Format("{0}: {1}", i, a["name"]));
i++;
}
// Check for morerecords, if it returns 1.
if (returnCollection.MoreRecords)
{
// Increment the page number to retrieve the next page.
pageNumber++;
}
else
{
// If no more records in the result nodes, exit the loop.
break;
}
}
}
}
}
private static AuthenticationCredentials GetCredentials(AuthenticationProviderType endpointType)
{
string _userName = ConfigurationManager.AppSettings["UserName"];
string _password = ConfigurationManager.AppSettings["Password"];
string _domain = ConfigurationManager.AppSettings["Domain"];
AuthenticationCredentials authCredentials = new AuthenticationCredentials();
switch (endpointType)
{
case AuthenticationProviderType.ActiveDirectory:
authCredentials.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(_userName, _password, _domain);
break;
case AuthenticationProviderType.Federation:
case AuthenticationProviderType.OnlineFederation:
authCredentials.ClientCredentials.UserName.UserName = _userName;
authCredentials.ClientCredentials.UserName.Password = _password;
break;
default:
break;
}
return authCredentials;
}
private static TProxy GetProxy<TService, TProxy>(IServiceManagement<TService> serviceManagement, AuthenticationCredentials authCredentials)
where TService : class
where TProxy : ServiceProxy<TService>
{
Type classType = typeof(TProxy);
if (serviceManagement.AuthenticationType != AuthenticationProviderType.ActiveDirectory)
{
AuthenticationCredentials tokenCredentials = serviceManagement.Authenticate(authCredentials);
// Obtain discovery/organization service proxy for Federated, LiveId and OnlineFederated environments.
// Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and SecurityTokenResponse.
return (TProxy)classType
.GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(SecurityTokenResponse) })
.Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse });
}
// Obtain discovery/organization service proxy for ActiveDirectory environment.
// Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and ClientCredentials.
return (TProxy)classType
.GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(System.ServiceModel.Description.ClientCredentials) })
.Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials });
}
}
}
Retrieveのすべてのレコード
private static List<Entity> GetAllAccounts(OrganizationServiceProxy organizationProxy)
{
string fetch2 = @"<fetch mapping='logical'>
<entity name='account'>
<attribute name='accountid'/>
<attribute name='name'/>
</entity>
</fetch> ";
List<Entity> result = new List<Entity>();
// Initialize the page number.
int pageNumber = 1;
while (true)
{
// Build fetchXml string with the placeholders.
string xml = CreateXml(fetch2, pageNumber);
EntityCollection returnCollection = organizationProxy.RetrieveMultiple(new Microsoft.Xrm.Sdk.Query.FetchExpression(xml));
foreach (var a in returnCollection.Entities)
{
result.Add(a);
}
// Check for morerecords, if it returns 1.
if (returnCollection.MoreRecords)
{
// Increment the page number to retrieve the next page.
pageNumber++;
}
else
{
// If no more records in the result nodes, exit the loop.
break;
}
}
return result;
}
(六)Query Expression
// Get the organization service proxy.
using (OrganizationServiceProxy organizationProxy = GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials))
{
Microsoft.Xrm.Sdk.Query.QueryExpression query = new Microsoft.Xrm.Sdk.Query.QueryExpression
{
EntityName = "account",
ColumnSet = new ColumnSet("name")
};
int i = 1;
query.PageInfo = new PagingInfo();
query.PageInfo.PageNumber = 1;
query.PageInfo.PagingCookie = null;
while (true)
{
// Retrieve the page.
EntityCollection ec = organizationProxy.RetrieveMultiple(query);
if (ec.Entities != null)
{
// Retrieve all records from the result set.
foreach (var a in ec.Entities)
{
Console.WriteLine(string.Format("{0}: {1}", i, a["name"]));
i++;
}
}
// Check for more records, if it returns true.
if (ec.MoreRecords)
{
// Increment the page number to retrieve the next page.
query.PageInfo.PageNumber++;
// Set the paging cookie to the paging cookie returned from current results.
query.PageInfo.PagingCookie = ec.PagingCookie;
}
else
{
// If no more records are in the result nodes, exit the loop.
break;
}
}
}
Retrieveのすべてのレコード
private static List<Entity> GetAllAccounts(OrganizationServiceProxy organizationProxy)
{
List<Entity> result = new List<Entity>();
Microsoft.Xrm.Sdk.Query.QueryExpression query = new Microsoft.Xrm.Sdk.Query.QueryExpression
{
EntityName = "account",
ColumnSet = new ColumnSet("name")
};
int i = 1;
query.PageInfo = new PagingInfo();
query.PageInfo.PageNumber = 1;
query.PageInfo.PagingCookie = null;
while (true)
{
// Retrieve the page.
EntityCollection ec = organizationProxy.RetrieveMultiple(query);
if (ec.Entities != null)
{
// Retrieve all records from the result set.
foreach (var a in ec.Entities)
{
result.Add(a);
}
}
// Check for more records, if it returns true.
if (ec.MoreRecords)
{
// Increment the page number to retrieve the next page.
query.PageInfo.PageNumber++;
// Set the paging cookie to the paging cookie returned from current results.
query.PageInfo.PagingCookie = ec.PagingCookie;
}
else
{
// If no more records are in the result nodes, exit the loop.
break;
}
}
return result;
}