웹 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. 저작권 정보