다음을 통해 공유


샘플: JavaScript와 함께 OData 끝점을 사용하여 여러 레코드 검색

 

게시 날짜: 2016년 11월

적용 대상: Dynamics CRM 2015

이 샘플 코드는 Microsoft Dynamics CRM 2015 및 Microsoft Dynamics CRM Online 2015 업데이트용입니다. Microsoft Dynamics CRM SDK 패키지를 다운로드합니다. 다운로드 패키지의 다음 위치에서 확인할 수 있습니다.

SDK/SampleCode/JS/RESTEndpoint/JavaScriptRESTRetrieveMultiple

이 샘플이 어떻게 작동되는지 확인하려면 다운로드 파일에 포함된 JavaScriptRESTRetrieveMultiple_1_0_0_0_managed.zip 관리형 솔루션을 설치할(가져올) 수 있습니다. 이 관리 솔루션을 설치하고 아래 이름을 사용하여 웹 리소스를 만들려면 관리형 솔루션을 제거(삭제)하지 않는 한 솔루션 게시자 사용자 지정 접두사는 “sample”일 수 없습니다.

요구 사항

솔루션을 설치한 후 솔루션의 구성 페이지에서 이 샘플을 볼 수 있습니다.

샘플 사용자 인터페이스

이 샘플에서는 다음과 같은 네 가지 웹 리소스를 사용합니다.

  • sample_/JavaScriptRESTRetrieveMultiple.htm
    데이터를 검색하기 위해 SDK.REST.retrieveMultipleRecords 함수를 호출하는 사용자 인터페이스와 함수를 제공하는 HTML 페이지. 이 페이지는 샘플 솔루션의 구성 페이지로 설정됩니다.

  • sample_/Scripts/SDK.REST.js
    이 JavaScript 라이브러리는 SDK.REST.retrieveMultipleRecords 함수뿐 아니라 웹 리소스에 대해 REST 끝점을 사용하도록 다른 함수를 제공합니다.

  • sample_/Styles/JavaScriptRESTRetrieveMultiple.css
    이 CSS 스타일 시트 파일은 sample_/JavaScriptRESTRetrieveMultiple.htm에 대한 스타일을 제공합니다.

참고

사용자 지정 접두사 "sample_"은 코드에 사용되지 않습니다. 이러한 샘플은 게시자의 사용자 지정 접두사를 사용하여 작동합니다. 하지만 시뮬레이션된 Scripts and Styles 폴더의 상대 경로는 웹 리소스 이름에 포함되어야 합니다.

보여 주기

기본적으로 REST 끝점에서 반환된 레코드 수는 50개로 제한됩니다. 이 샘플에서는 이러한 제한에 상관 없이 여러 레코드를 검색하는 방법을 보여 줍니다.

이 샘플은 다음과 같은 방법을 사용합니다.

  1. document.onreadystatechange 이벤트 처리기에는 다양한 UI 요소를 전역 변수로 설정하고 거래처 검색 단추(btnRetrieveAccounts)에 대해 retrieveAccounts 함수를 클릭 이벤트 처리기로 설정한 후 btnRetrieveAccounts 단추에 대해 click 메서드를 호출하는 코드가 포함되어 있습니다.

  2. retrieveAccounts 함수는 accountGrid를 정리하고 numberOfAccountsToRetrieve 선택 컨트롤에서 검색할 레코드 수를 검색합니다. 이 값은 SDK.REST.retrieveMultipleRecords 옵션 매개 변수에 전달되는 OData 시스템 쿼리 옵션에 추가됩니다.

  3. SDK.REST.retrieveMultipleRecords 메서드는 다음 매개 변수를 허용합니다.

    • type: 검색할 엔터티 유형 레코드의 스키마 이름. 이 예제에서는 거래처 레코드를 검색하도록 "거래처"를 사용합니다.

    • options: 반환된 데이터를 제어하는 OData 시스템 쿼리 옵션을 나타내는 문자열. 이 예제에서 거래처 NameTelephone1 특성이 설정되고 $top 쿼리 옵션은 레코드 제한 기본값인 50 이상의 값으로 설정됩니다.

    • successCallback: 반환되는 레코드의 각 페이지에 호출되고 전달되는 함수. 이 예제에서는 retrieveAccountsCallBack 함수를 사용합니다.

    • errorCallback: 실패한 응답에서 호출되고 전달되는 함수. 이 예제에서는 alert 함수를 사용하여 모든 오류 메시지를 표시하는 익명의 함수를 사용합니다.

    • OnComplete: 모든 요청된 레코드가 반환될 때 호출되는 함수. 이 예제에서는 accountsRetrieveComplete 함수를 사용합니다.

  4. SDK.REST.retrieveMultipleRecords 함수는 요청된 거래처 레코드를 검색하고 요청을 보내도록 XMLHttpRequest를 준비합니다.

    • 요청 onreadystatechange 이벤트 처리기 내에서 첫 번째 결과 50개는 successCallback으로 retrieveAccountsCallBack 함수에 다시 전달됩니다. 이 함수는 각 레코드에 대해 HTML 행을 생성하여 accountsGrid 테이블에 추가합니다.

    • $top 쿼리 옵션을 사용하여 요청된 총 레코드 수가 아직 검색되지 않은 경우 __next 개체에는 다음 50개의 레코드 집합을 검색하도록 URL이 포함됩니다. URL은 쿼리 옵션을 추출하기 위해 조작된 후 SDK.REST.retrieveMultipleRecords 함수에 전달됩니다. 요청된 레코드 수가 반환되거나 반환할 레코드가 더 이상 없을 때까지 이 자체 참조 함수 호출은 반복됩니다.

    • __next 개체가 더 이상 결과를 반환하지 않으면 accountsRetrieveComplete 함수가 OnComplete 함수로 실행됩니다. 이 함수는 반환되는 총 레코드 수를 설정하고 성공 메시지를 표시합니다.

  5. 기본값으로 페이지가 로드된 후 검색할 최대 거래처 수(numberOfAccountsToRetrieve) 선택 컨트롤을 사용하여 다른 수의 레코드를 요청하고 거래처 검색(btnRetrieveAccounts) 단추를 사용하여 다른 요청을 보낼 수 있습니다.

sample_/JavaScriptRESTRetrieveMultiple.htm


<html lang="en-us">
<head>
 <title>REST Endpoint Paging with JScript</title>
 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
 <script src="../ClientGlobalContext.js.aspx" type="text/javascript"></script>
 <script src="Scripts/SDK.REST.js" type="text/javascript"></script>
 <link href="Styles/JavaScriptRESTRetrieveMultiple.css" rel="stylesheet" type="text/css" />
 <script type="text/javascript">
  var accountsGrid; //The tbody element of the accountsTable
  var numberOfAccountsToRetrieve; // The select control with options for the number of records to retrieve.
  var btnRetrieveAccounts; //The button to retrieve accounts
  var accountsRetrieved; //The span displaying the number of account records retrieved.
  var successMessage; // The message displayed when records are returned.
  var totalAccountCount = 0;
  document.onreadystatechange = function () {
   if (document.readyState == "complete") {
    btnRetrieveAccounts = document.getElementById("btnRetrieveAccounts");
    accountsGrid = document.getElementById("accountsGrid");
    numberOfAccountsToRetrieve = document.getElementById("numberOfAccountsToRetrieve");
    accountsRetrieved = document.getElementById("accountsRetrieved");
    successMessage = document.getElementById("successMessage");
    btnRetrieveAccounts.onclick = retrieveAccounts;
    btnRetrieveAccounts.click();
   }
  }
  function retrieveAccounts() {
   ///<summary>
   /// Retrieves accounts by passing a filter to the SDK.RestEndpointPaging.RetrieveRecords function
   ///</summary>
   clearaccountsGrid();
   var number = parseInt(numberOfAccountsToRetrieve.options[numberOfAccountsToRetrieve.selectedIndex].value, 10);
   var options = "$select=Name,Telephone1&amp;$top=" + number;
   //The retrieveAccountsCallBack function is passed through as the successCallBack.
   SDK.REST.retrieveMultipleRecords("Account", options, retrieveAccountsCallBack, function (error) { alert(error.message); }, accountsRetrieveComplete);
  }
  function retrieveAccountsCallBack(retrievedAccounts) {
   ///<summary>
   /// This function is passed through the request and is iterated for each page of data
   /// This function appends rows to the accountsGrid.
   ///</summary>
   totalAccountCount = totalAccountCount + retrievedAccounts.length;
   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);
    var mainPhoneCell = document.createElement("td");
    setElementText(mainPhoneCell, (account.Telephone1 == null) ? "" : account.Telephone1);
    mainPhoneCell.className = "rightColumn";
    row.appendChild(mainPhoneCell);
    accountsGrid.appendChild(row);
   }
  }
  function accountsRetrieveComplete() {
   ///<summary>
   /// This function is called after all the records have been returned to update the actual total number of records.
   ///</summary>
   accountsRetrieved.innerText = totalAccountCount;
   successMessage.style.display = "block";
  }
  function clearaccountsGrid() {
   ///<summary>
   /// This function initializes the totalAccountCount and  clears all the rows from the accountsGrid
   /// in preparation for adding a new set of rows.
   ///</summary>
   successMessage.style.display = "none";
   totalAccountCount = 0;
   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; }
  }
 </script>
</head>
<body>
 <table id="tableHeadings" summary="This table provides the headings for the list of accounts displayed in a grid.">
  <thead>
   <tr>
    <th class="leftColumn">
     Account Name
    </th>
    <th class="rightColumn">
     Main Phone
    </th>
   </tr>
  </thead>
 </table>


 <div id="tableContainer">
  <table id="accountsTable" rules="groups" summary="This table displays the accounts retrieved.">
   <tbody id="accountsGrid" />
  </table>


 </div>
 <div id="controlsContainer">
  <div>
   <span>Maximum Number of Accounts to Retrieve:
    <select id="numberOfAccountsToRetrieve">
     <option value="10" selected="selected">10</option>
     <option value="100" selected="selected">100</option>
     <option value="300">300</option>
     <option value="600">600</option>
     <option value="900">900</option>
    </select>
    <button id="btnRetrieveAccounts">
     Retrieve Accounts</button>
   </span>
  </div>
  <div id="successMessage" style="display: none;">
   Total Number of Accounts Retrieved : <span id="accountsRetrieved"></span>
  </div>
 </div>
</body>
</html>

sample_/Scripts/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."); }
  }
 },
 _getClientUrl: function () {
  ///<summary>
  /// Private function to return the server URL from the context
  ///</summary>
  ///<returns>String</returns>
  var clientUrl = this._context().getClientUrl()

  return clientUrl;
 },
 _ODataPath: function () {
  ///<summary>
  /// Private function to return the path to the REST endpoint.
  ///</summary>
  ///<returns>String</returns>
  return this._getClientUrl() + "/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 https://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 */) {
    req.onreadystatechange = null;
    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 + "&amp;$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 */) {
    req.onreadystatechange = null;
    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 */) {
    req.onreadystatechange = null;
    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 */) {
    req.onreadystatechange = null;
    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 */) {
    req.onreadystatechange = null;
    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 */) {
    req.onreadystatechange = null;
    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 */) {
    req.onreadystatechange = null;
    if (this.status == 204 || this.status == 1223) {
     successCallback();
    }
    else {
     errorCallback(SDK.REST._errorHandler(this));
    }
   }
  };
  req.send();
 },
 __namespace: true
};

sample_/Styles/JavaScriptRESTRetrieveMultiple.css

참고 항목

OData 끝점을 사용하여 Microsoft Dynamics CRM 2015 데이터 쿼리
반환된 레코드 수 제한
Ajax 및 JScript 웹 리소스와 함께 OData 끝점 사용
샘플: JavaScript와 함께 OData 끝점을 사용하여 레코드 연결 및 연결 해제
웹 리소스와 함께 OData 끝점 사용
기술 문서: REST 끝점과 함께 옵션 집합 옵션 사용 - JScript

© 2017 Microsoft. All rights reserved. 저작권 정보