다음을 통해 공유


웹 API 기본 작업 샘플(클라이언트 쪽 JavaScript)

 

게시 날짜: 2017년 1월

적용 대상: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

이 샘플에서는 클라이언트 쪽 JavaScript를 사용하여 엔터티 인스턴스에서 기본 CRUD(만들기, 검색, 업데이트 및 삭제) 및 연결과 연결 해제 작업을 수행하는 방법을 보여줍니다.

참고

이 샘플은 웹 API 기본 작업 샘플에서 자세히 설명된 작업을 구현하며 웹 API 샘플(클라이언트 쪽 JavaScript)에 설명된 공통 JavaScript 작성을 사용합니다.

이 항목의 내용

  • 필수 조건

  • 샘플 실행

  • 코드 샘플

필수 조건

이 샘플을 실행하려면 다음이 필요합니다.

  • Dynamics 365 온라인 또는 온-프레미스 버전 8.0 이상에 대한 액세스.

  • 솔루션을 가져오고 CRUD 작업을 수행할 수 있는 권한 가진 사용자 계정. 일반적으로 시스템 관리자 또는 시스템 사용자 지정자 보안 역할.

샘플 실행

이 예제를 실행하려면 Microsoft CRM 웹 API 기본 작업 샘플(클라이언트 쪽 JavaScript)에서 솔루션 패키지를 다운로드합니다.Microsoft CRM Web API Basic Operations Sample (Client-side JavaScript).zip 파일을 다운로드하고 압축을 풉니다.WebAPIBasicOperations_1_0_0_1_managed.zip 솔루션을 찾아 Dynamics 365 조직으로 가져온 뒤 샘플을 실행합니다. 샘플 솔루션을 가져오는 방법에 대한 지침은 웹 API 샘플(클라이언트 쪽 JavaScript)을 참조하십시오.

코드 샘플

이 샘플에는 두 가지 웹 리소스가 포함됩니다.

  • WebAPIBasicOperations.html

  • WebAPIBasicOperations.js

WebAPIBasicOperations.html

WebAPIBasicOperations.html 웹 리소스는 JavaScript 코드가 실행되는 컨텍스트를 제공합니다.

<html>
<head>
    <title>Microsoft CRM Web API Basic Operations Example</title>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <script src="../ClientGlobalContext.js.aspx" type="text/javascript"></script>
    <script src="scripts/es6promise.js" type="text/javascript"></script>
    <script src="scripts/WebAPIBasicOperations.js" type="text/javascript"></script>

    <style type="text/css">
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        #preferences {
            border: inset;
            padding: 10px 10px;
        }

        #output_area {
            border: inset;
            background-color: gainsboro;
            padding: 10px 10px;
        }
    </style>
</head>
<body>
    <h1>Microsoft CRM Web API Basic Operations Example</h1>
    <p>This page demonstrates the CRM Web API's basic operations using JavaScript.</p>

    <h2>Instructions</h2>
    <p>
        Choose your preferences and run the JavaScript code. 
    Use your browser's developer tools to view the output written to the console (e.g.: in IE11 or Edge, 
    press F12 to load the Developer Tools).
    </p>
    <p>
        Remove sample data (Choose whether you want to delete sample data created during this execution):
            <br />
        <input name="removesampledata" type="radio" value="yes" checked />
        Yes
            <input name="removesampledata" type="radio" value="no" />
        No
    </p>
    <input type="button" name="start_sample" value="Start Sample" onclick="Sdk.startSample()" />

</body>
</html>

WebAPIBasicOperations.js

WebAPIBasicOperations.js 웹 리소스는 이 샘플이 수행하는 작업을 정의하는 JavaScript 라이브러리입니다.

"use strict";
var Sdk = window.Sdk || {};

/**
 * @function getClientUrl
 * @description Get the client URL.
 * @returns {string} The client URL.
 */
Sdk.getClientUrl = function () {
 var context;
 // GetGlobalContext defined by including reference to 
 // ClientGlobalContext.js.aspx in the HTML page.
 if (typeof GetGlobalContext != "undefined") {
  context = GetGlobalContext();
 } else {
  if (typeof Xrm != "undefined") {
   // Xrm.Page.context defined within the Xrm.Page object model for form scripts.
   context = Xrm.Page.context;
  } else {
   throw new Error("Context is not available.");
  }
 }
 return context.getClientUrl();

};

/**
 * An object instantiated to manage detecting the
 * Web API version in conjunction with the 
 * Sdk.retrieveVersion function
 */
Sdk.versionManager = new function () {
 //Start with base version
 var _webAPIMajorVersion = 8;
 var _webAPIMinorVersion = 0;
 //Use properties to increment version and provide WebAPIPath string used by Sdk.request;
 Object.defineProperties(this, {
  "WebAPIMajorVersion": {
   get: function () {
    return _webAPIMajorVersion;
   },
   set: function (value) {
    if (typeof value != "number") {
     throw new Error("Sdk.versionManager.WebAPIMajorVersion property must be a number.")
    }
    _webAPIMajorVersion = parseInt(value, 10);
   }
  },
  "WebAPIMinorVersion": {
   get: function () {
    return _webAPIMinorVersion;
   },
   set: function (value) {
    if (isNaN(value)) {
     throw new Error("Sdk.versionManager._webAPIMinorVersion property must be a number.")
    }
    _webAPIMinorVersion = parseInt(value, 10);
   }
  },
  "WebAPIPath": {
   get: function () {
    return "/api/data/v" + _webAPIMajorVersion + "." + _webAPIMinorVersion;
   }
  }
 })

}

//Setting variables specific to this sample within a container so they won't be 
// overwritten by another scripts code
Sdk.SampleVariables = {
 entitiesToDelete: [],   // Entity URIs to be deleted later (if user so chooses)
 deleteData: true,       // Controls whether sample data are deleted at the end of sample run
 contact1Uri: null,      // e.g.: Peter Cambel
 contactAltUri: null,    // e.g.: Peter_Alt Cambel
 account1Uri: null,      // e.g.: Contoso, Ltd
 account2Uri: null,      // e.g.: Fourth Coffee
 contact2Uri: null,      // e.g.: Susie Curtis
 opportunity1Uri: null,  // e.g.: Adventure Works
 competitor1Uri: null

}


/**
 * @function request
 * @description Generic helper function to handle basic XMLHttpRequest calls.
 * @param {string} action - The request action. String is case-sensitive.
 * @param {string} uri - An absolute or relative URI. Relative URI starts with a "/".
 * @param {object} data - An object representing an entity. Required for create and update actions.
 * @param {object} addHeader - An object with header and value properties to add to the request
 * @returns {Promise} - A Promise that returns either the request object or an error object.
 */
Sdk.request = function (action, uri, data, addHeader) {
 if (!RegExp(action, "g").test("POST PATCH PUT GET DELETE")) { // Expected action verbs.
  throw new Error("Sdk.request: action parameter must be one of the following: " +
      "POST, PATCH, PUT, GET, or DELETE.");
 }
 if (!typeof uri === "string") {
  throw new Error("Sdk.request: uri parameter must be a string.");
 }
 if ((RegExp(action, "g").test("POST PATCH PUT")) && (!data)) {
  throw new Error("Sdk.request: data parameter must not be null for operations that create or modify data.");
 }
 if (addHeader) {
  if (typeof addHeader.header != "string" || typeof addHeader.value != "string") {
   throw new Error("Sdk.request: addHeader parameter must have header and value properties that are strings.");
  }
 }

 // Construct a fully qualified URI if a relative URI is passed in.
 if (uri.charAt(0) === "/") {
  //This sample will try to use the latest version of the web API as detected by the 
  // Sdk.retrieveVersion function.
  uri = Sdk.getClientUrl() + Sdk.versionManager.WebAPIPath + uri;
 }

 return new Promise(function (resolve, reject) {
  var request = new XMLHttpRequest();
  request.open(action, encodeURI(uri), true);
  request.setRequestHeader("OData-MaxVersion", "4.0");
  request.setRequestHeader("OData-Version", "4.0");
  request.setRequestHeader("Accept", "application/json");
  request.setRequestHeader("Content-Type", "application/json; charset=utf-8");
  if (addHeader) {
   request.setRequestHeader(addHeader.header, addHeader.value);
  }
  request.onreadystatechange = function () {
   if (this.readyState === 4) {
    request.onreadystatechange = null;
    switch (this.status) {
     case 200: // Operation success with content returned in response body.
     case 201: // Create success. 
     case 204: // Operation success with no content returned in response body.
      resolve(this);
      break;
     default: // All other statuses are unexpected so are treated like errors.
      var error;
      try {
       error = JSON.parse(request.response).error;
      } catch (e) {
       error = new Error("Unexpected Error");
      }
      reject(error);
      break;
    }
   }
  };
  request.send(JSON.stringify(data));
 });
};

/**
 * @function startSample
 * @description Runs the sample. 
 * This sample demonstrates basic CRUD+ operations. 
 * Results are sent to the debugger's console window.
 */
Sdk.startSample = function () {
 // Initializing.
 Sdk.SampleVariables.deleteData = document.getElementsByName("removesampledata")[0].checked;
 Sdk.SampleVariables.entitiesToDelete = []; // Reset the array.
 Sdk.SampleVariables.contact1Uri = "";
 Sdk.SampleVariables.account1Uri = "";
 Sdk.SampleVariables.account2Uri = "";
 Sdk.SampleVariables.contact2Uri = "";
 Sdk.SampleVariables.opportunity1Uri = "";
 Sdk.SampleVariables.competitor1Uri = "";

 /**
  * Behavior of this sample varies by version
  * So starting by retrieving the version;
  */

 Sdk.retrieveVersion()
 .then(function () {
  return Sdk.basicCreateAndUpdatesAsync()
 })
.then(function () {
 return Sdk.createWithAssociationAsync()
})
.then(function () {
 return Sdk.createRelatedAsync()
})
.then(function () {
 return Sdk.associateExistingAsync()
})
.then(function () {
 return Sdk.deleteSampleData()
})
.catch(function (err) {
 console.log("ERROR: " + err.message);
});

}

Sdk.retrieveVersion = function () {
 return new Promise(function (resolve, reject) {
  Sdk.request("GET", "/RetrieveVersion")
  .then(function (request) {
   try {
    var RetrieveVersionResponse = JSON.parse(request.response);
    var fullVersion = RetrieveVersionResponse.Version;
    var versionData = fullVersion.split(".");
    Sdk.versionManager.WebAPIMajorVersion = parseInt(versionData[0], 10);
    Sdk.versionManager.WebAPIMinorVersion = parseInt(versionData[1], 10);
    resolve();
   } catch (err) {
    reject(new Error("Error processing version: " + err.message))
   }
  })
  .catch(function (err) {
   reject(new Error("Error retrieving version: " + err.message))
  })
 });
};

Sdk.basicCreateAndUpdatesAsync = function () {
 return new Promise(function (resolve, reject) {

  // Section 1.
  //
  // Create the contact using POST request. 
  // A new entry will be added regardless if a contact with this info already exists in the system or not.
  console.log("--Section 1 started--");
  var contact = {};
  contact.firstname = "Peter";
  contact.lastname = "Cambel";

  var entitySetName = "/contacts";

  Sdk.request("POST", entitySetName, contact)
 .then(function (request) {
  // Process response from previous request.
  Sdk.SampleVariables.contact1Uri = request.getResponseHeader("OData-EntityId");
  Sdk.SampleVariables.entitiesToDelete.push(Sdk.SampleVariables.contact1Uri); // To delete later
  console.log("Contact 'Peter Cambel' created with URI: %s", Sdk.SampleVariables.contact1Uri);

  // Setup for next request.
  //
  // Update contact.
  // Add property values to a specific contact using PATCH request.
  var contact = {};
  contact.annualincome = 80000.00;
  contact.jobtitle = "Junior Developer";
  return Sdk.request("PATCH", Sdk.SampleVariables.contact1Uri, contact)
 })
 .then(function () {
  // Process response from previous request.
  console.log("Contact 'Peter Cambel' updated with job title and annual income.");

  // Setup for next request.
  //
  // Retrieve selected properties of a Contact entity using GET request. 
  // NOTE: It is performance best practice to select only the properties you need.

  // Retrieved contact properties.
  var properties = [
   "fullname",
   "annualincome",
   "jobtitle",
   "description"].join();

  // NOTE: For performance best practices, use $select to limit the properties you want to return
  // See also: https://msdn.microsoft.com/en-us/library/gg334767.aspx#bkmk_requestProperties
  var query = "?$select=" + properties;
  return Sdk.request("GET", Sdk.SampleVariables.contact1Uri + query, null);
 })
 .then(function (request) {
  // Process response from previous request.
  var contact1 = JSON.parse(request.response);
  var successMsg = "Contact '%s' retrieved:\n"
      + "\tAnnual income: %s \n"
      + "\tJob title: %s \n"
      + "\tDescription: %s";
  console.log(successMsg,
      contact1.fullname,      // This property is read-only. Calculated from firstname and lastname.
      contact1.annualincome,
      contact1.jobtitle,
      contact1.description); // Description will be "null" because it has not been set yet.

  // Setup for next request.
  //
  // Update properties.
  // Set new values for some of the properties and apply the values to the server via PATCH request.
  // Notice that we are updating the jobtitle and annualincome properties and adding value to the 
  // description property in the same request.
  var contact = {};
  contact.jobtitle = "Senior Developer";
  contact.annualincome = 95000.00;
  contact.description = "Assignment to-be-determined. ";
  return Sdk.request("PATCH", Sdk.SampleVariables.contact1Uri, contact);
 })
 .then(function () {
  // Process response from previous request.
  console.log("Contact 'Peter Cambel' updated:\n"
                      + "\tJob title: Senior Developer, \n"
                      + "\tAnnual income: 95000, \n"
                      + "\tDescription: Assignment to-be-determined.");

  // Setup for next request.
  //
  // Set value for a single property using PUT request.
  // In this case, we are setting the telephone1 property to "555-0105".
  var value = { value: "555-0105" };
  return Sdk.request("PUT", Sdk.SampleVariables.contact1Uri + "/telephone1", value);
 })
 .then(function () {
  // Process response from previous request.
  console.log("Contact 'Peter Cambel' phone number updated.");

  // Setup for next request.
  //
  // Retrieve single value property.
  // Get a value of a single property using GET request.
  // In this case, telephone1 is retrieved. We should get back "555-0105".
  return Sdk.request("GET", Sdk.SampleVariables.contact1Uri + "/telephone1", null);
 })
 .then(function (request) {
  // Process response from previous request.
  var phoneNumber = JSON.parse(request.response);
  console.log("Contact's phone number is: %s", phoneNumber.value);
 })
 .then(function () {
  // Setup for next request.
  //The following operations require version 8.2 or higher
  if (Sdk.versionManager.WebAPIMajorVersion > 8 ||
   (Sdk.versionManager.WebAPIMajorVersion == 8 && Sdk.versionManager.WebAPIMinorVersion >= 2)
   ) {
   // Starting with December 2016 update (v8.2), a contact instance can be 
   // created and its properties returned in one operation by using a 
   //'Prefer: return=representation' header.
   var contactAlt = {};
   contactAlt.firstname = "Peter_Alt";
   contactAlt.lastname = "Cambel";
   contactAlt.jobtitle = "Junior Developer";
   contactAlt.annualincome = 80000;
   contactAlt.telephone1 = "555-0110";
   var properties = [
    "fullname",
    "annualincome",
    "jobtitle"].join();
   var query = "?$select=" + properties;
   // Create contact and return its state (in the body).
   var retRepHeader = { header: "Prefer", value: "return=representation" };
   Sdk.request("POST", entitySetName + query, contactAlt, retRepHeader)
  .then(function (request) {
   var contactA = JSON.parse(request.response);
   //Because 'OData-EntityId' header not returned in a 201 response, you must instead 
   // construct the URI.
   Sdk.SampleVariables.contactAltUri = Sdk.getClientUrl() +
    Sdk.versionManager.WebAPIPath +
    "/contacts(" +
    contactA.contactid +
    ")";
   Sdk.SampleVariables.entitiesToDelete.push(Sdk.SampleVariables.contactAltUri);
   var successMsg = "Contact '%s' created:\n"
       + "\tAnnual income: %s \n"
       + "\tJob title: %s \n";
   console.log(successMsg,
       contactA.fullname,
       contactA.annualincome,
       contactA.jobtitle);
   console.log("Contact URI: %s", Sdk.SampleVariables.contactAltUri);
  })
  .then(function () {
   // Setup for next request.
   //Similarly, the December 2016 update (v8.2) also enables returning selected properties   
   //after an update operation (PATCH), with the 'Prefer: return=representation' header.
   var contactAlt = {};
   contactAlt.jobtitle = "Senior Developer";
   contactAlt.annualincome = 95000;
   contactAlt.description = "MS Azure and Dynamics 365 Specialist";
   var properties = [
      "fullname",
      "annualincome",
      "jobtitle",
      "description"].join();
   var query = "?$select=" + properties;
   // Update contact and return its state (in the body).
   var retRepHeader = { header: "Prefer", value: "return=representation" };
   return Sdk.request("PATCH", Sdk.SampleVariables.contactAltUri + query, contactAlt, retRepHeader);
  })
  .then(function (request) {
   // Process response from previous request.
   var contactA = JSON.parse(request.response);
   var successMsg = "Contact '%s' updated:\n"
       + "\tAnnual income: %s \n"
       + "\tJob title: %s \n";
   console.log(successMsg,
       contactA.fullname,
       contactA.annualincome,
       contactA.jobtitle);
   //End this series of operations:
   resolve();
  })
  .catch(function (err) {
   reject(err);
  });
  }
  else {
   resolve();
  }
 })
 .catch(function (err) {
  reject(err);
 });
 });
};

Sdk.createWithAssociationAsync = function () {
 return new Promise(function (resolve, reject) {
  // Section 2.
  //
  // Create a new account entity and associate it with an existing contact using POST request.
  console.log("\n--Section 2 started--");
  var account = {};
  account.name = "Contoso, Ltd.";
  account.telephone1 = "555-5555";
  account["primarycontactid@odata.bind"] = Sdk.SampleVariables.contact1Uri; //relative URI ok. E.g.: "/contacts(###)".

  var entitySetName = "/accounts";

  Sdk.request("POST", entitySetName, account)
 .then(function (request) {
  // Process response from previous request.
  Sdk.SampleVariables.account1Uri = request.getResponseHeader("OData-EntityId");
  Sdk.SampleVariables.entitiesToDelete.push(Sdk.SampleVariables.account1Uri);
  console.log("Account 'Contoso, Ltd.' created.");

  // Setup for next request.
  //
  // Retrieve account's primary contact with selected properties using GET request and 'expand' query.
  var contactProperties = [
      "fullname",
      "jobtitle",
      "annualincome"
  ].join();
  var query = "?$select=name,telephone1&$expand=primarycontactid($select=" + contactProperties + ")";
  return Sdk.request("GET", Sdk.SampleVariables.account1Uri + query, null);
 })
 .then(function (request) {
  // Process response from previous request.
  var account1 = JSON.parse(request.response);
  var successMsg = "Account '%s' has primary contact '%s':  \n"
                  + "\tJob title:  %s \n"
                  + "\tAnnual income:  %s ";
  console.log(successMsg,
      account1.name,
      account1.primarycontactid.fullname,
      account1.primarycontactid.jobtitle,
      account1.primarycontactid.annualincome);
  //End this series of operations:
  resolve();
 })
 .catch(function (err) {
  reject(err);
 });
 });
};

Sdk.createRelatedAsync = function () {
 return new Promise(function (resolve, reject) {

  // Section 3.
  //
  // Create related entities (deep insert).
  // Create the following entities in one operation using deep insert technique:
  //   account
  //   |--- contact
  //        |--- tasks
  // Then retrieve properties of these entities
  //
  // Constructing the entity relationship.
  console.log("\n--Section 3 started--");
  var account = {};
  account.name = "Fourth Coffee";
  account.primarycontactid = {
   firstname: "Susie",
   lastname: "Curtis",
   jobtitle: "Coffee Master",
   annualincome: 48000.00,
   Contact_Tasks: [
       {
        subject: "Sign invoice",
        description: "Invoice #12321",
        scheduledend: new Date("April 19th, 2016")
       },
       {
        subject: "Setup new display",
        description: "Theme is - Spring is in the air",
        scheduledstart: new Date("4/20/2016")
       },
       {
        subject: "Conduct training",
        description: "Train team on making our new blended coffee",
        scheduledstart: new Date("6/1/2016")
       }
   ]
  };

  var entitySetName = "/accounts";
  Sdk.request("POST", entitySetName, account)
 .then(function (request) {
  // Process response from previous request.
  Sdk.SampleVariables.account2Uri = request.getResponseHeader("OData-EntityId");
  Sdk.SampleVariables.entitiesToDelete.push(Sdk.SampleVariables.account2Uri);
  console.log("Account 'Fourth Coffee' created.");

  // Setup for next request.
  //
  // Retrieve account entity info using GET request and 'expand' query.
  var contactProperties = [
   "fullname",
   "jobtitle",
   "annualincome"].join();

  // Expand on primarycontactid to select some of contact's properties.
  // NOTE: With $expand, the CRM server will return values for the selected properties. 
  // The CRM Web API only supports expansions one level deep.
  // See also: https://msdn.microsoft.com/en-us/library/mt607871.aspx#bkmk_expandRelated
  var query = "?$select=name&$expand=primarycontactid($select=" + contactProperties + ")";
  return Sdk.request("GET", Sdk.SampleVariables.account2Uri + query, null);
 })
 .then(function (request) {
  // Process response from previous request.
  var account2 = JSON.parse(request.response);
  var successMsg = "Account '%s' has primary contact '%s':\n"
      + "\tJob title:  %s \n"
      + "\tAnnual income:  %s";
  console.log(successMsg,
      account2.name,
      account2.primarycontactid.fullname,
      account2.primarycontactid.jobtitle,
      account2.primarycontactid.annualincome);

  // Setup for next request.
  //
  // Retrieve contact entity and expanding on its tasks using GET request.
  Sdk.SampleVariables.contact2Uri = Sdk.getClientUrl() + Sdk.versionManager.WebAPIPath + "/contacts(" + account2.primarycontactid.contactid + ")"; //Full URI.
  Sdk.SampleVariables.entitiesToDelete.push(Sdk.SampleVariables.contact2Uri); // For Susie Curtis
  var contactProperties = ["fullname", "jobtitle"].join();
  var contactTaskProperties = ["subject", "description", "scheduledstart", "scheduledend"].join();

  // Expand on contact_tasks to select some of its properties for each task.
  var query = "?$select=" + contactProperties +
      "&$expand=Contact_Tasks($select=" + contactTaskProperties + ")";
  return Sdk.request("GET", Sdk.SampleVariables.contact2Uri + query, null);
 })
 .then(function (request) {
  // Process response from previous request.
  var contact2 = JSON.parse(request.response);
  console.log("Contact '%s' has the following assigned tasks:", contact2.fullname);

  // construct the output string.
  var successMsg = "Subject: %s \n"
  + "\tDescription: %s \n"
  + "\tStart: %s \n"
  + "\tEnd: %s \n";

  for (var i = 0; i < contact2.Contact_Tasks.length; i++) {
   console.log(successMsg,
       contact2.Contact_Tasks[i].subject,
       contact2.Contact_Tasks[i].description,
       contact2.Contact_Tasks[i].scheduledstart,
       contact2.Contact_Tasks[i].scheduledend
   );
  }

  //End this series of operations:
  resolve();
 })
 .catch(function (err) {
  reject(err);
 });
 });
};

Sdk.associateExistingAsync = function () {
 return new Promise(function (resolve, reject) {

  // Section 4
  //
  // Entity associations:
  // Associate to existing entities via the different relationship types:
  // 1) 1:N relationship - Associate an existing contact to an existing account 
  //      (e.g.: contact - Peter Cambel to account - Fourth Coffee).
  // 2) N:N relationship - Associate an competitor to opportunity.

  console.log("\n--Section 4 started--");
  var contact = {};
  contact["@odata.id"] = Sdk.SampleVariables.contact1Uri;

  Sdk.request("POST", Sdk.SampleVariables.account2Uri + "/contact_customer_accounts/$ref", contact)
 .then(function () {
  // Process response from previous request.
  console.log("Contact 'Peter Cambel' associated to account 'Fourth Coffee'.");

  // Setup for next request.
  //
  // Verify that the reference was made as expected.
  var contactProperties = ["fullname", "jobtitle"].join();

  // This returns a collection of all associated contacts...in a "value" array.
  var query = "/contact_customer_accounts?$select=" + contactProperties;
  return Sdk.request("GET", Sdk.SampleVariables.account2Uri + query, null);
 })
 .then(function (request) {
  // Process response from previous request.
  var relatedContacts = JSON.parse(request.response).value; //collection is in the "value" array.
  var successMsg = "\tName: %s, "
                  + "Job title: %s ";

  console.log("Contact list for account 'Fourth Coffee': ");

  for (var i = 0; i < relatedContacts.length; i++) {
   console.log(successMsg,
       relatedContacts[i].fullname,
       relatedContacts[i].jobtitle
   );
  }

  // Setup for next request.
  //
  // Disassociate a contact from an account.
  return Sdk.request("DELETE", Sdk.SampleVariables.account2Uri + "/contact_customer_accounts/$ref?$id=" + Sdk.SampleVariables.contact1Uri, null);
 })
 .then(function () {
  // Process response from previous request.
  console.log("Contact 'Peter Cambel' disassociated from account 'Fourth Coffee'.");

  // Setup for next request.
  //
  // N:N relationship:
  // Associate a competitor to an opportunity.
  var competitor = {};
  competitor.name = "Adventure Works";
  competitor.strengths = "Strong promoter of private tours for multi-day outdoor adventures.";

  var entitySetName = "/competitors";
  return Sdk.request("POST", entitySetName, competitor);
 })
 .then(function (request) {
  // Process response from previous request.
  Sdk.SampleVariables.competitor1Uri = request.getResponseHeader("OData-EntityId");
  Sdk.SampleVariables.entitiesToDelete.push(Sdk.SampleVariables.competitor1Uri);
  console.log("Competitor 'Adventure Works' created.");

  // Setup for next request.
  // 
  // Create a new opportunity...
  var opportunity = {};
  opportunity.name = "River rafting adventure";
  opportunity.description = "Sales team on a river-rafting offsite and team building.";
  var entitySetName = "/opportunities";
  return Sdk.request("POST", entitySetName, opportunity);
 })
 .then(function (request) {
  // Process response from previous request.
  Sdk.SampleVariables.opportunity1Uri = request.getResponseHeader("OData-EntityId");
  Sdk.SampleVariables.entitiesToDelete.push(Sdk.SampleVariables.opportunity1Uri);
  console.log("Opportunity 'River rafting adventure' created.");

  // Setup for next request.
  //
  // Associate competitor to opportunity.
  var competitor = {};
  competitor["@odata.id"] = Sdk.SampleVariables.competitor1Uri;
  return Sdk.request("POST", Sdk.SampleVariables.opportunity1Uri + "/opportunitycompetitors_association/$ref", competitor);
 })
 .then(function () {
  // Process response from previous request.
  console.log("Opportunity 'River rafting adventure' associated with competitor 'Adventure Works'.");

  // Setup for next request.
  //
  // Retrieve competitor entity and expanding on its opportunitycompetitors_association
  // for all opportunities, using GET request.
  var opportunityProperties = ["name", "description"].join();
  var competitorProperties = ["name"].join();
  var query = "?$select=" + competitorProperties +
      "&$expand=opportunitycompetitors_association($select=" + opportunityProperties + ")";
  return Sdk.request("GET", Sdk.SampleVariables.competitor1Uri + query, null);
 })
 .then(function (request) {
  // Process response from previous request.
  var competitor1 = JSON.parse(request.response);
  console.log("Competitor '%s' has the following opportunities:", competitor1.name);
  var successMsg = "\tName: %s, \n"
                 + "\tDescription: %s";
  for (var i = 0; i < competitor1.opportunitycompetitors_association.length; i++) {
   console.log(successMsg,
       competitor1.opportunitycompetitors_association[i].name,
       competitor1.opportunitycompetitors_association[i].description
   );
  }

  // Setup for next request.
  //
  // Disassociate competitor from opportunity.
  return Sdk.request("DELETE", Sdk.SampleVariables.opportunity1Uri +
          "/opportunitycompetitors_association/$ref?$id=" + Sdk.SampleVariables.competitor1Uri, null);
 })
 .then(function () {
  // Process response from previous request.
  console.log("Opportunity 'River rafting adventure' disassociated with competitor 'Adventure Works'");
  //End this series of operations:
  resolve();
 })
 .catch(function (err) {
  reject(err);
 });
 });
};

Sdk.deleteSampleData = function () {
 return new Promise(function (resolve, reject) {

  // House cleaning - deleting sample data
  // NOTE: If instances have a parent-child relationship, then deleting the parent will, 
  // by default, automatically cascade delete child instances. In this program, 
  // tasks related using the Contact_Tasks relationship have contact as their parent. 
  // Other relationships may behave differently.
  // See also: https://msdn.microsoft.com/en-us/library/gg309412.aspx#BKMK_CascadingBehavior
  console.log("\n--Section 5 started--");
  if (Sdk.SampleVariables.deleteData) {
   for (var i = 0; i < Sdk.SampleVariables.entitiesToDelete.length; i++) {
    console.log("Deleting entity: " + Sdk.SampleVariables.entitiesToDelete[i]);
    Sdk.request("DELETE", Sdk.SampleVariables.entitiesToDelete[i], null)
    .catch(function (err) {
     reject(new Error("ERROR: Delete failed --Reason: \n\t" + err.message))
    });
   }
   resolve();
  } else {
   console.log("Sample data not deleted.");
   resolve();
  }

 });
};

참고 항목

Microsoft Dynamics 365 웹 API 사용
웹 API를 사용하여 엔터티 만들기
웹 API를 사용하여 엔터티 검색
웹 API를 사용하여 엔터티 업데이트 및 삭제
웹 API 샘플
웹 API 기본 작업 샘플
웹 API 기본 작업 샘플(C#)
웹 API 샘플(클라이언트 쪽 JavaScript)
웹 API 쿼리 데이터 샘플(클라이언트 쪽 JavaScript)
웹 API 조건부 작업 샘플(클라이언트 쪽 JavaScript)
웹 API 함수 및 동작 샘플(클라이언트 쪽 JavaScript)

Microsoft Dynamics 365

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