Eksempel på Web API-forespørgselsdata (JavaScript på klientsiden)
Udgivet: januar 2017
Gælder for: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online
Dette eksempel demonstrerer, hvordan du udfører grundlæggende forespørgsler ved hjælp af Dynamics 365 Web API ved hjælp af JavaScript på klientsiden
Bemærk
Dette eksempel implementerer de handlinger, der er beskrevet i Eksempel på Web API-forespørgselsdata og bruger de fælles JavaScript-konstruktioner på klientsiden, som er beskrevet i Web API-eksempler (JavaScript på klientsiden).
Dette emne indeholder
Forudsætninger
Køre dette eksempel
Kodeeksempel
Forudsætninger
Hvis du vil køre dette eksempel, er følgende påkrævet:
Adgang til Dynamics 365 online eller lokale version 8.0 eller nyere.
En brugerkonto med rettigheder til at importere løsninger og udføre CRUD-handlinger, typisk med sikkerhedsrollen systemadministrator eller systemtilpasser.
Køre dette eksempel
Hvis du vil køre dette eksempel, skal du gå til Eksempel på Microsoft CRM Web API-forespørgselsdata (JavaScript på klientsiden) og hente eksempelfilen for Microsoft CRM Web API Query Data Sample (Client-side JavaScript).zip. Udpak indholdet af eksempelarkivet, og find filen for den administrerede WebAPIQueryData_1_0_0_0_managed.zip-løsning. Importér den administrerede løsning i din Dynamics 365-organisation, og kør eksemplet. Vejledning i at importere eksempelløsningen finder du under Web API-eksempler (JavaScript på klientsiden).
Kodeeksempel
Dette eksempel indeholder to webressourcer:
WebAPIQuery.html
WebAPIQuery.js
WebAPIQuery.html
WebAPIQuery.html-webressourcen leverer den kontekst, hvor JavaScript-koden skal køres.
<!DOCTYPE html>
<html>
<head>
<title>Microsoft CRM Web API Query Example</title>
<meta charset="utf-8" />
<script src="../ClientGlobalContext.js.aspx" type="text/javascript"></script>
<script src="scripts/es6promise.js"></script>
<script src="scripts/WebAPIQuery.js"></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 Query Example</h1>
<p>This page demonstrates the CRM Web API's Query 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>
<form id="preferences">
<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_samples" value="Start Sample" onclick="Sdk.startSample()" />
</form>
</body>
</html>
WebAPIQuery.js
WebAPIQuery.js-webressourcen er det JavaScript-bibliotek, der definerer de handlinger, som dette eksempel udfører.
"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();
}
// Global variables.
var entitiesToDelete = []; // Entity URIs to be deleted (if user chooses to delete sample data)
var deleteData = true; // Delete data by default unless user chooses not to delete.
var clientUrl = Sdk.getClientUrl(); // e.g.: https://org.crm.dynamics.com
var webAPIPath = "/api/data/v8.1"; // Path to the web API.
var account1Uri; // e.g.: Contoso Inc (sample)
var contact1Uri; // e.g.: Yvonne McKey (sample)
var page2Uri; // URI of next page in pagination sample.
// Entity properties to select in a request.
var contactProperties = ["fullname", "jobtitle", "annualincome"];
var accountProperties = ["name"];
var taskProperties = ["subject", "description"];
/**
* @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 action.
* @param {boolean} formattedValue - If "true" then include formatted value; "false" otherwise.
* For more info on formatted value, see:
* https://msdn.microsoft.com/en-us/library/gg334767.aspx#bkmk_includeFormattedValues
* @param {number} maxPageSize - Indicate the page size. Default is 10 if not defined.
* @returns {Promise} - A Promise that returns either the request object or an error object.
*/
Sdk.request = function (action, uri, data, formattedValue, maxPageSize) {
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 === null || data === undefined)) {
throw new Error("Sdk.request: data parameter must not be null for operations that create or modify data.");
}
if (maxPageSize === null || maxPageSize === undefined) {
maxPageSize = 10; // Default limit is 10 entities per page.
}
// Construct a fully qualified URI if a relative URI is passed in.
if (uri.charAt(0) === "/") {
uri = clientUrl + 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");
request.setRequestHeader("Prefer", "odata.maxpagesize=" + maxPageSize);
if (formattedValue) {
request.setRequestHeader("Prefer",
"odata.include-annotations=OData.Community.Display.V1.FormattedValue");
}
request.onreadystatechange = function () {
if (this.readyState === 4) {
request.onreadystatechange = null;
switch (this.status) {
case 200: // Success with content returned in response body.
case 204: // 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));
});
};
/**
* @funnction output
* @description Generic helper function to output data to console.
* @param {array} collection - Array of entities.
* @param {string} label - Text label for what the collection contains.
* @param {array} properties - Array of properties appropriate for the collection.
*/
Sdk.output = function (collection, label, properties) {
console.log(label);
collection.forEach(function (row, i) {
var prop = [];
properties.forEach(function (p) {
var f = p + "@OData.Community.Display.V1.FormattedValue";
prop.push((row[f] ? row[f] : row[p])); // Get formatted value if one exists for this property.
})
console.log("\t%s) %s", i + 1, prop.join(", "));
});
}
/**
* @function startSample
* @description Runs the sample.
* This sample demonstrates basic query operations.
* Results are sent to the debugger's console window.
*/
Sdk.startSample = function () {
// Initializing...
deleteData = document.getElementsByName("removesampledata")[0].checked;
entitiesToDelete = []; //Reset the array.
account1Uri = "";
contact1Uri = "";
page2Uri = "";
console.log("-- Sample started --");
console.log("Create sample data:");
// Add some data to the CRM server so we can query against it.
// Using Deep Insert, we create all the sample data in one request.
// Data structure:
// Accounts
// |--- primarycontactid
// |--- Contact_Tasks (3 tasks)
// |--- Account_Tasks (3 tasks)
// |--- contact_customer_accounts (9 child contacts, each with 3 tasks)
// |--- Contacts
// |--- Contact_Tasks
//
var sampleData = {
"name": "Contoso, Ltd. (sample)",
"primarycontactid": {
"firstname": "Yvonne", "lastname": "McKay (sample)", "jobtitle": "Coffee Master",
"annualincome": 45000, "Contact_Tasks": [
{ "subject": "Task 1", "description": "Task 1 description" },
{ "subject": "Task 2", "description": "Task 2 description" },
{ "subject": "Task 3", "description": "Task 3 description" }
]
}, "Account_Tasks": [
{ "subject": "Task 1", "description": "Task 1 description" },
{ "subject": "Task 2", "description": "Task 2 description" },
{ "subject": "Task 3", "description": "Task 3 description" }
],
"contact_customer_accounts": [
{
"firstname": "Susanna", "lastname": "Stubberod (sample)", "jobtitle": "Senior Purchaser",
"annualincome": 52000, "Contact_Tasks": [
{ "subject": "Task 1", "description": "Task 1 description" },
{ "subject": "Task 2", "description": "Task 2 description" },
{ "subject": "Task 3", "description": "Task 3 description" }
]
},
{
"firstname": "Nancy", "lastname": "Anderson (sample)", "jobtitle": "Activities Manager",
"annualincome": 55500, "Contact_Tasks": [
{ "subject": "Task 1", "description": "Task 1 description" },
{ "subject": "Task 2", "description": "Task 2 description" },
{ "subject": "Task 3", "description": "Task 3 description" }
]
},
{
"firstname": "Maria", "lastname": "Cambell (sample)", "jobtitle": "Accounts Manager",
"annualincome": 31000, "Contact_Tasks": [
{ "subject": "Task 1", "description": "Task 1 description" },
{ "subject": "Task 2", "description": "Task 2 description" },
{ "subject": "Task 3", "description": "Task 3 description" }
]
},
{
"firstname": "Nancy", "lastname": "Anderson (sample)", "jobtitle": "Logistics Specialist",
"annualincome": 63500, "Contact_Tasks": [
{ "subject": "Task 1", "description": "Task 1 description" },
{ "subject": "Task 2", "description": "Task 2 description" },
{ "subject": "Task 3", "description": "Task 3 description" }
]
},
{
"firstname": "Scott", "lastname": "Konersmann (sample)", "jobtitle": "Accounts Manager",
"annualincome": 38000, "Contact_Tasks": [
{ "subject": "Task 1", "description": "Task 1 description" },
{ "subject": "Task 2", "description": "Task 2 description" },
{ "subject": "Task 3", "description": "Task 3 description" }
]
},
{
"firstname": "Robert", "lastname": "Lyon (sample)", "jobtitle": "Senior Technician",
"annualincome": 78000, "Contact_Tasks": [
{ "subject": "Task 1", "description": "Task 1 description" },
{ "subject": "Task 2", "description": "Task 2 description" },
{ "subject": "Task 3", "description": "Task 3 description" }
]
},
{
"firstname": "Paul", "lastname": "Cannon (sample)", "jobtitle": "Ski Instructor",
"annualincome": 68500, "Contact_Tasks": [
{ "subject": "Task 1", "description": "Task 1 description" },
{ "subject": "Task 2", "description": "Task 2 description" },
{ "subject": "Task 3", "description": "Task 3 description" }
]
},
{
"firstname": "Rene", "lastname": "Valdes (sample)", "jobtitle": "Data Analyst III",
"annualincome": 86000, "Contact_Tasks": [
{ "subject": "Task 1", "description": "Task 1 description" },
{ "subject": "Task 2", "description": "Task 2 description" },
{ "subject": "Task 3", "description": "Task 3 description" }
]
},
{
"firstname": "Jim", "lastname": "Glynn (sample)", "jobtitle": "Senior International Sales Manager",
"annualincome": 81400, "Contact_Tasks": [
{ "subject": "Task 1", "description": "Task 1 description" },
{ "subject": "Task 2", "description": "Task 2 description" },
{ "subject": "Task 3", "description": "Task 3 description" }
]
}
]
};
var uri = "/accounts"; // A relative URI to the account entity.
Sdk.request("POST", uri, sampleData) // Adding sample data so we can query against it.
.then(function (request) {
// Process request.
account1Uri = request.getResponseHeader("OData-EntityId");
entitiesToDelete.push(account1Uri); // To delete later.
console.log("Account 'Contoso, Ltd. (sample)' created with 1 primary contact and 9 associated contacts.");
// Get primary contact info.
// Most queries are done using this contact.
var uri = account1Uri + "/primarycontactid/$ref"; // Request for the URI only.
return Sdk.request("GET", uri);
})
.then(function (request) {
contact1Uri = JSON.parse(request.response)["@odata.id"];
entitiesToDelete.push(contact1Uri); // To delete later.
console.log("Has primary contact 'Yvonne McKay (sample)' with URI: %s\n", contact1Uri);
// Basic query:
// Query using $select option against a contact entity to get the properties you want.
// For performance best practice, always use $select otherwise all properties are returned.
console.log("-- Basic Query --");
var query = "?$select=" + contactProperties.join(); // Array defined in the global scope.
return Sdk.request("GET", contact1Uri + query, null, true);
})
.then(function (request) {
var contact1 = JSON.parse(request.response);
console.log("Contact basic info:\n\tFullname: '%s'\n\tJobtitle: '%s'\n\tAnnualincome: '%s' (unformatted)",
contact1.fullname, contact1.jobtitle, contact1.annualincome);
console.log("\tAnnualincome: %s (formatted)\n",
contact1["annualincome@OData.Community.Display.V1.FormattedValue"]);
// Filter criteria:
// Applying filters to get targeted data.
// 1) Using standard query functions (e.g.: contains, endswith, startswith)
// 2) Using CRM query functions (e.g.: LastXhours, Last7Days, Today, Between, In, ...)
// 3) Using filter operators and logical operators (e.g.: eq, ne, gt, and, or, etc…)
// 4) Set precedence using parenthesis (e.g.: ((criteria1) and (criteria2)) or (criteria3)
// For more info, see: https://msdn.microsoft.com/en-us/library/gg334767.aspx#bkmk_filter
console.log("-- Filter Criteria --");
// Filter 1: Using standard query functions to filter results.
// In this operation, we will query for all contacts with fullname containing the string "(sample)".
var filter = "&$filter=contains(fullname,'(sample)')";
var query = "?$select=" + contactProperties.join() + filter;
return Sdk.request("GET", "/contacts" + query, null, true);
})
.then(function (request) {
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Contacts filtered by fullname containing '(sample)':", contactProperties);
// Filter 2: Using CRM query functions to filter results.
// In this operation, we will query for all contacts that was created in the last hour.
// For complete list of CRM query functions, see:
// https://msdn.microsoft.com/en-us/library/mt607843.aspx
var filter = "&$filter=Microsoft.Dynamics.CRM.LastXHours(PropertyName='createdon',PropertyValue='1')";
var query = "?$select=" + contactProperties.join() + filter;
return Sdk.request("GET", "/contacts" + query, null, true); // Remember page size limit is set to 10.
})
.then(function(request){
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Contacts that were created within the last 1hr:", contactProperties);
// Filter 3: Using operators
// Building on the previous operation, we will further limit the results by the contact's income.
// For more info on standard filter operators, see:
// https://msdn.microsoft.com/en-us/library/gg334767.aspx#bkmk_filter
var filter = "&$filter=contains(fullname,'(sample)') and annualincome gt 55000";
var query = "?$select=" + contactProperties.join() + filter;
return Sdk.request("GET", "/contacts" + query, null, true);
})
.then(function (request) {
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Contacts filtered by fullname and annualincome (<$55,000):", contactProperties);
// Filter 4: Set precedence using parenthesis.
// Continue building on the previous operation, we will further limit results by job title.
// Parenthesis and the order of filter statements can impact results returned.
var filter = "&$filter=contains(fullname,'(sample)') " +
"and (contains(jobtitle,'senior') or contains(jobtitle,'specialist')) and annualincome gt 55000";
var query = "?$select=" + contactProperties.join() + filter;
return Sdk.request("GET", "/contacts" + query, null, true);
})
.then(function (request) {
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Contacts filtered by fullname, annualincome and jobtitle (Senior or Specialist):",
contactProperties);
// Order results:
// Filtered results can be order in descending or ascending order.
console.log("\n-- Order Results --");
var filter = "&$filter=contains(fullname,'(sample)') " +
"&$orderby=jobtitle asc, annualincome desc";
var query = "?$select=" + contactProperties.join() + filter;
return Sdk.request("GET", "/contacts" + query, null, true);
})
.then(function (request) {
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Contacts ordered by jobtitle (Ascending) and annualincome (descending):",
contactProperties);
// Parameterized Aliases.
// Aliases can be used as parameters in a query. These parameters can be used in $filter and $orderby options.
// Using the previous operation as basis, parameterizing the query will give us the same results.
// For more info, see: https://msdn.microsoft.com/en-us/library/gg309638.aspx#bkmk_passParametersToFunctions
console.log("\n-- Parameterized Aliases --");
var filter = "&$filter=contains(@p1,'(sample)') " +
"&$orderby=@p2 asc, @p3 desc&@p1=fullname&@p2=jobtitle&@p3=annualincome";
var query = "?$select=" + contactProperties.join() + filter;
return Sdk.request("GET", "/contacts" + query, null, true);
})
.then(function (request) {
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Contacts list using parameterized aliases:", contactProperties);
// Limit records returned.
// To further limit the records returned, use the $top query option.
// Specifying a limit number for $top will return at most that number of results per request.
// Extra results are ignored.
console.log("\n-- Top Results --");
var filter = "&$filter=contains(fullname,'(sample)')&$top=5";
var query = "?$select=" + contactProperties.join() + filter;
return Sdk.request("GET", "/contacts" + query, null, true);
})
.then(function (request) {
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Contacts top 5 results:", contactProperties);
// Result count.
// Count the number of results matching the filter criteria.
// 1) Get a count of a collection without the data.
// 2) Get a count along with the data.
// HINT: Use count together with the "odata.maxpagesize" to calculate the number of pages in the query.
// NOTE: CRM has a max record limit of 5000 records per response.
console.log("\n-- Result Count --");
return Sdk.request("GET", "/contacts/$count"); // Count is returned in response body.
})
.then(function (request) {
console.log("The contacts collection has %s contacts.", request.response); // Count maximum is 5000.
// 2) Get filtered result with a count
var filter = "&$filter=contains(jobtitle,'senior') or contains(jobtitle, 'manager')&$count=true";
var query = "?$select=" + contactProperties.join() + filter;
return Sdk.request("GET", "/contacts" + query, null, true);
})
.then(function (request) {
var count = JSON.parse(request.response)["@odata.count"];
console.log("%s contacts have either 'Manager' or 'Senior' designation in their jobtitle.", count);
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Manager or Senior:", contactProperties);
// Pagination:
// For large data sets, you can limit the number of records returned per page.
// Then offer a "next page" and "previous page" links for users to browse through all the data.
// NOTE: This is why you should not use $top with maxpagesize. $top will limit results returned
// preventing you from accessing all possible results in the query.
// For example: If your query has 10 entities in the result and you limit your result to $top=5
// then, you can't get to the remaining 5 results; but with "maxpagesize" (without $top), you can.
// HINT: Save the URI of the current page so users can go "next" and "previous".
console.log("\n-- Pagination --");
var filter = "&$filter=contains(fullname,'(sample)')&$count=true";
var query = "?$select=" + contactProperties.join() + filter;
return Sdk.request("GET", "/contacts" + query, null, true, 4); // 4 records per page.
})
.then(function (request) {
var count = JSON.parse(request.response)["@odata.count"];
var maxpages = Math.ceil(count / 4);
console.log("Contacts total: %s \tContacts per page: %s.\tOutputting first 2 pages.", count, 4);
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Page 1 of " + maxpages + ":", contactProperties);
// Getting the next page.
page2Uri = JSON.parse(request.response)["@odata.nextLink"]; // This URI is already encoded.
return Sdk.request("GET", decodeURI(page2Uri), null, true, 4); // URI re-encoded in the request function.
})
.then(function (request) {
var count = JSON.parse(request.response)["@odata.count"];
var maxpages = Math.ceil(count / 4);
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Page 2 of " + maxpages + ":", contactProperties);
// Using expand option to retrieve additional information.
// It is common for entities to have associations with other entities in the system and you might want
// to also retrieve this information in the same request. To retrieve information on associated entities,
// use the $expand query option on navigation properties.
// 1) Expand using single-valued navigation properties (e.g.: via the 'primarycontactid')
// 2) Expand using partner property (e.g.: from contact to account via the 'account_primary_contact')
// 3) Expand using collection-valued navigation properties (e.g.: via the 'contact_customer_accounts')
// 4) Expand using multiple navigation property types in a single request.
// NOTE: Expansions can only go 1 level deep.
// For performance best practice, always use $select statement in an expand option.
console.log("\n-- Expanding Results --");
// 1) Expand using single-valued navigation properties (e.g.: via the 'primarycontactid')
var expand = "&$expand=primarycontactid($select=" + contactProperties.join() + ")";
var query = "?$select=" + accountProperties.join() + expand;
return Sdk.request("GET", account1Uri + query, null, true);
})
.then(function (request) {
var account = JSON.parse(request.response);
var str = "Account '%s' has the following primary contact person:\n\t" +
"Fullname: '%s' \n\tJobtitle: '%s' \n\tAnnualincome: '%s'";
console.log(str, account.name,
account.primarycontactid.fullname,
account.primarycontactid.jobtitle,
account.primarycontactid.annualincome);
// 2) Expand using partner property (e.g.: from contact to account via the 'account_primary_contact')
var expand = "&$expand=account_primary_contact($select=" + accountProperties.join() + ")";
var query = "?$select=" + contactProperties.join() + expand;
return Sdk.request("GET", contact1Uri + query, null, true);
})
.then(function (request) {
var contact = JSON.parse(request.response);
var label = "Contact '" + contact.fullname + "' is the primary contact for the following accounts:";
Sdk.output(contact.account_primary_contact, label, accountProperties);
// 3) Expand using collection-valued navigation properties (e.g.: via the 'contact_customer_accounts')
var expand = "&$expand=contact_customer_accounts($select=" + contactProperties.join() + ")"
var query = "?$select=" + accountProperties.join() + expand;
return Sdk.request("GET", account1Uri + query, null, true);
})
.then(function (request) {
var account = JSON.parse(request.response);
var label = "Account '" + account.name + "' has the following contact customers:";
var collection = account.contact_customer_accounts;
Sdk.output(collection, label, contactProperties);
// 4) Expand using multiple navigation property types in a single request.
// For example: expanding on primiarycontactid, contact_customer_accounts, and Account_Tasks.
console.log("\n-- Expanding multiple property types in one request -- ");
var expand = "&$expand=primarycontactid($select=" + contactProperties.join() + ")," +
"contact_customer_accounts($select=" + contactProperties.join() + ")," +
"Account_Tasks($select=" + taskProperties.join() + ")";
var query = "?$select=" + accountProperties.join() + expand;
return Sdk.request("GET", account1Uri + query, null, true);
})
.then(function (request) {
var account = JSON.parse(request.response);
var label = "Account '%s' has the following primary contact person:\n\t" +
"Fullname: '%s' \n\tJobtitle: '%s' \n\tAnnualincome: '%s'";
console.log(label, account.name,
account.primarycontactid.fullname,
account.primarycontactid.jobtitle,
account.primarycontactid.annualincome);
// Handling each collection separately.
label = "Account '" + account.name + "' has the following related contacts:";
var collection = account.contact_customer_accounts;
Sdk.output(collection, label, contactProperties);
label = "Account '" + account.name + "' has the following tasks:";
collection = account.Account_Tasks;
Sdk.output(collection, label, taskProperties);
// FetchXML
// Using FetchXML to query for all contacts whose fullname contains '(sample)'.
// NOTE: XML string must be URI encoded.
// For more information, see: https://msdn.microsoft.com/en-us/library/gg328117.aspx
console.log("\n-- FetchXML -- ");
var fetchXML = "<fetch mapping=\"logical\" output-format=\"xml-platform\" version=\"1.0\" distinct=\"false\"> \
<entity name=\"contact\"> \
<attribute name=\"fullname\" /> \
<attribute name=\"jobtitle\" /> \
<attribute name=\"annualincome\" /> \
<order descending=\"true\" attribute=\"fullname\" /> \
<filter type=\"and\"> \
<condition value=\"%(sample)%\" attribute=\"fullname\" operator=\"like\" /> \
</filter> \
</entity> \
</fetch> ";
return Sdk.request("GET", "/contacts?fetchXml=" + encodeURIComponent(fetchXML), null, true);
})
.then(function(request){
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Contacts Fetched by fullname containing '(sample)':", contactProperties);
// FetchXML pagination.
// Noticed the attribute "page=3" and "count=4" in this XML.
// We want to retrieve entities in page 3 but limit results to only 4 entities.
// If the result return zero records for the page, that means we have reached the end of the result set.
// For more info, see: https://msdn.microsoft.com/en-us/library/mt607533.aspx#bkmk_useFetchXML
var fetchXML = "<fetch mapping=\"logical\" output-format=\"xml-platform\" version=\"1.0\" \
distinct=\"false\" page=\"3\" count=\"4\"> \
<entity name=\"contact\"> \
<attribute name=\"fullname\" /> \
<attribute name=\"jobtitle\" /> \
<attribute name=\"annualincome\" /> \
<order descending=\"true\" attribute=\"fullname\" /> \
<filter type=\"and\"> \
<condition value=\"%(sample)%\" attribute=\"fullname\" operator=\"like\" /> \
</filter> \
</entity> \
</fetch> ";
return Sdk.request("GET", "/contacts?fetchXml=" + encodeURIComponent(fetchXML), null, true);
})
.then(function(request){
var collection = JSON.parse(request.response).value;
if (collection.length == 0) {
console.log("There are no records on this page."); // We have reached the end of our query result set.
} else {
Sdk.output(collection, "Contacts Fetched by fullname containing '(sample)' - Page 3:", contactProperties);
}
// Using predefined queries.
// 1) Saved query
// 2) User query
// For more info, see:
// https://msdn.microsoft.com/en-us/library/mt607533.aspx
// Saved Query
// Get the Saved Query "Active Accounts" and display results to output.
console.log("\n-- Saved Query -- ");
var filter = "&$filter=name eq 'Active Accounts'";
var query = "?$select=name,savedqueryid" + filter;
return Sdk.request("GET", "/savedqueries" + query, null, true); // Requesting for saved query GUID.
})
.then(function(request){
// Get the savedqueryid GUID and then use it to request for the entities in that query.
var activeAccount = JSON.parse(request.response).value[0]; // Get the first matched.
var savedqueryid = activeAccount.savedqueryid;
// Request for the saved query results
return Sdk.request("GET", "/accounts?savedQuery=" + savedqueryid, null, true);
})
.then (function (request){
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Saved Query (Active Accounts):", accountProperties);
// User Query
// Create a user query then get it from the server and execute that query for results.
// For more info, see: https://msdn.microsoft.com/en-us/library/gg509053.aspx
console.log("\n-- User Query -- ");
var userquery = {
"name": "My User Query",
"description": "User query to display contact info.",
"querytype": 0,
"returnedtypecode": "contact",
"fetchxml": "<fetch mapping=\"logical\" output-format=\"xml-platform\" version=\"1.0\" distinct=\"false\"> \
<entity name=\"contact\"> \
<attribute name=\"fullname\" /> \
<attribute name=\"contactid\" /> \
<attribute name=\"jobtitle\" /> \
<attribute name=\"annualincome\" /> \
<order descending=\"false\" attribute=\"fullname\" /> \
<filter type=\"and\"> \
<condition value=\"%(sample)%\" attribute=\"fullname\" operator=\"like\" /> \
<condition value=\"%Manager%\" attribute=\"jobtitle\" operator=\"like\" /> \
<condition value=\"55000\" attribute=\"annualincome\" operator=\"gt\" /> \
</filter> \
</entity> \
</fetch> "
};
return Sdk.request("POST", "/userqueries", userquery, true); // Create the user query.
})
.then(function (request){
// Look up the user query we just created
// then use it to request for the entities in that query.
var filter = "&$filter=name eq 'My User Query'";
var query = "?$select=name,userqueryid," + filter;
return Sdk.request("GET", "/userqueries" + query, null, true);
})
.then(function (request) {
var userQuery = JSON.parse(request.response).value[0]; // Get the first matched.
var userqueryid = userQuery.userqueryid;
entitiesToDelete.push(clientUrl + webAPIPath + "/userqueries(" + userqueryid + ")");
// Request for the user query results
return Sdk.request("GET", "/contacts?userQuery=" + userqueryid, null, true);
})
.then(function (request) {
var collection = JSON.parse(request.response).value;
Sdk.output(collection, "Saved User Query:", contactProperties);
// House cleaning - deleting sample data
// For more info on cascading delete, see:
// https://msdn.microsoft.com/en-us/library/gg309412.aspx#BKMK_CascadingBehavior
console.log("\n-- Deleting Sample Data --");
if (deleteData) {
for (var i = 0; i < entitiesToDelete.length; i++) {
console.log("Deleting entity: " + entitiesToDelete[i]);
Sdk.request("DELETE", entitiesToDelete[i], null)
.catch(function (err) {
console.log("ERROR: Delete failed --Reason: \n\t" + err.message);
});
}
} else {
console.log("Sample data not deleted.");
}
})
.catch(function (error) {
console.log(error.message);
});
}
Se også
Brug Microsoft Dynamics 365 Web API
Forespørg på data ved hjælp af Web-API'en
Web API-eksempler
Eksempel på Web API-forespørgselsdata
Eksempel på Web API-forespørgselsdata (C#)
Web API-eksempler (JavaScript på klientsiden)
Eksempel på Web API Basic operationer (JavaScript på klientsiden)
Eksempel på Web API Conditional operationer (JavaScript på klientsiden)
Eksempel på web-API-funktioner og handlinger (JavaScript på klientsiden)
Microsoft Dynamics 365
© 2017 Microsoft. Alle rettigheder forbeholdes. Ophavsret