2 |
Loading...
3 |
4 |
5 |
6 |
7 | Add
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Edit |
20 | Delete
21 |
22 |
23 | Save |
24 | Cancel
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/JS/Examples/SinglePage/app/views/userData.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Claim
6 | Value
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/JS/README.md:
--------------------------------------------------------------------------------
1 |
2 | Current Version CDN - https://xrmtoolscode.azureedge.net/CRMWebAPI.js
3 |
4 | You can find more query example information [here]( https://github.com/davidyack/Xrm.Tools.CRMWebAPI/wiki/Query-Examples )
5 |
6 | # Usage example
7 |
8 | ```javascript
9 |
10 |
11 | var apiconfig = { APIUrl: 'https://orgname.crm.dynamics.com/api/data/v8.0/', AccessToken: "
" };
12 |
13 | var crmAPI = new CRMWebAPI(apiconfig);
14 |
15 | crmAPI
16 | .Create("accounts", { "name": "test2" })
17 | .then(
18 | function(r){
19 | console.log('Created: ' + r);
20 | return crmAPI.Update('accounts', r, { "name": "test2updated"});
21 | },
22 | function(e){
23 | console.log(e);
24 | })
25 | .then(
26 | function(r){
27 | console.log('Updated: ' + r.EntityID);
28 | return crmAPI.Delete('accounts', r.EntityID);
29 | },
30 | function(e){
31 | console.log(e);
32 | })
33 | .then(
34 | function(r){
35 | console.log('Deleted');
36 | }, function(e){
37 | console.log(e);
38 | })
39 | ```
40 | Working with Metadata - include CRMWebAPIMetadata.js
41 |
42 | Current Version CDN - https://xrmtoolscode.azureedge.net/CRMWebAPIMetadata.js
43 |
44 | Methods
45 | - GetOptionSetByName
46 | - GetOptionSetUserLabels - returns Label/Value array
47 | - GetEntityDisplayNameList(LCID) - returns object with DisplayName,DisplayCollectionName,LogicalName,LogicalCollectionName for LCID - or pass null for default LCID
48 |
49 | #Metadata Usage example
50 | ```javascript
51 |
52 | crmAPI
53 | .GetOptionSetUserLabels("my_optionsetname")
54 | .then(
55 | function(r){
56 | console.log('Display Labels: ' + r);
57 |
58 | },
59 | function(e){
60 | console.log(e);
61 | })
62 |
63 |
64 | crmAPI.GetEntityDisplayNameList(1033).then(function(result)
65 | {
66 | //do stuff here...
67 |
68 | });
69 |
70 | ```
71 |
--------------------------------------------------------------------------------
/JS/lib/Releases/CRMWebAPIMetadata-1.0.0.js:
--------------------------------------------------------------------------------
1 | CRMWebAPI.prototype.GetOptionSetByName = function (optionSetName) {
2 | var self = this;
3 | return new Promise(function (resolve, reject) {
4 |
5 | self.GetList('GlobalOptionSetDefinitions',
6 | {Select:['Name']}).then(
7 | function (r)
8 | {
9 | r.List.forEach(function(set)
10 | {
11 | if (set.Name == optionSetName)
12 | {
13 | self.Get('GlobalOptionSetDefinitions',set.MetadataId).then(
14 | function(res){
15 | resolve(res);
16 | },function(err){console.log(err)}
17 | )
18 | }
19 | }
20 | )
21 | },
22 | function(e){
23 | console.log(e)
24 | reject(e)
25 | })
26 | });
27 | };
28 |
29 | CRMWebAPI.prototype.GetOptionSetUserLabels = function (optionSetName) {
30 | var self = this;
31 | return new Promise(function (resolve, reject) {
32 |
33 | self.GetOptionSetByName(optionSetName).then(
34 | function (result)
35 | {
36 | var displayList = new Array();
37 | result.Options.forEach(function (option)
38 | {
39 | var displayOption = new Object;
40 | displayOption.Value = option.Value;
41 | displayOption.Label = option.Label.UserLocalizedLabel.Label;
42 | displayList.push(displayOption);
43 | });
44 | resolve(displayList);
45 | }
46 | ,
47 | function (err)
48 | {
49 | console.log(err)
50 | reject(err);
51 | }
52 | );
53 | });
54 |
55 | }
--------------------------------------------------------------------------------
/JS/lib/Releases/CRMWebAPIMetadata-1.1.0.js:
--------------------------------------------------------------------------------
1 | CRMWebAPI.prototype.GetOptionSetByName = function (optionSetName) {
2 | var self = this;
3 | return new Promise(function (resolve, reject) {
4 |
5 | self.GetList('GlobalOptionSetDefinitions',
6 | {Select:['Name']}).then(
7 | function (r)
8 | {
9 | r.List.forEach(function(set)
10 | {
11 | if (set.Name == optionSetName)
12 | {
13 | self.Get('GlobalOptionSetDefinitions',set.MetadataId).then(
14 | function(res){
15 | resolve(res);
16 | },function(err){console.log(err)}
17 | )
18 | }
19 | }
20 | )
21 | },
22 | function(e){
23 | console.log(e)
24 | reject(e)
25 | })
26 | });
27 | };
28 |
29 | CRMWebAPI.prototype.GetOptionSetUserLabels = function (optionSetName) {
30 | var self = this;
31 | return new Promise(function (resolve, reject) {
32 |
33 | self.GetOptionSetByName(optionSetName).then(
34 | function (result)
35 | {
36 | var displayList = new Array();
37 | result.Options.forEach(function (option)
38 | {
39 | var displayOption = new Object;
40 | displayOption.Value = option.Value;
41 | displayOption.Label = option.Label.UserLocalizedLabel.Label;
42 | displayList.push(displayOption);
43 | });
44 | resolve(displayList);
45 | }
46 | ,
47 | function (err)
48 | {
49 | console.log(err)
50 | reject(err);
51 | }
52 | );
53 | });
54 |
55 | }
56 |
57 | CRMWebAPI.prototype.GetEntityDisplayNameList = function (LCID) {
58 | var self = this;
59 | return new Promise(function (resolve, reject) {
60 |
61 |
62 | self.GetList('EntityDefinitions',
63 | {Select:['DisplayName','DisplayCollectionName','LogicalName','LogicalCollectionName']}).then(
64 | function (r)
65 | {
66 | var list = new Array();
67 | r.List.forEach(function(entity)
68 | {
69 | var edm = new Object();
70 | edm.LogicalName = entity.LogicalName;
71 | edm.LogicalCollectionName = entity.LogicalCollectionName;
72 | if ((entity.DisplayName.LocalizedLabels != null) && (entity.DisplayName.LocalizedLabels.length > 0))
73 | {
74 | edm.DisplayName = entity.DisplayName.LocalizedLabels[0].Label;
75 | if (LCID != null)
76 | entity.DisplayName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayName = label.Label});
77 | }
78 | else
79 | edm.DisplayName = edm.LogicalName;
80 | if ((entity.DisplayCollectionName.LocalizedLabels != null) && (entity.DisplayCollectionName.LocalizedLabels.length > 0))
81 | {
82 | edm.DisplayCollectionName = entity.DisplayCollectionName.LocalizedLabels[0].Label;
83 | if (LCID != null)
84 | entity.DisplayCollectionName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayCollectionName = label.Label});
85 | }
86 | else
87 | edm.DisplayCollectionName = entity.LogicalCollectionName;
88 | list.push(edm);
89 | }
90 | )
91 | resolve(list);
92 | },
93 | function(e){
94 | console.log(e)
95 | reject(e)
96 | })
97 | });
98 | };
--------------------------------------------------------------------------------
/JS/lib/Releases/CRMWebAPIMetadata-1.1.1.js:
--------------------------------------------------------------------------------
1 | CRMWebAPI.prototype.GetOptionSetByName = function (optionSetName) {
2 | var self = this;
3 | return new Promise(function (resolve, reject) {
4 |
5 | self.GetList('GlobalOptionSetDefinitions',
6 | {Select:['Name']}).then(
7 | function (r)
8 | {
9 | r.List.forEach(function(set)
10 | {
11 | if (set.Name == optionSetName)
12 | {
13 | self.Get('GlobalOptionSetDefinitions',set.MetadataId).then(
14 | function(res){
15 | resolve(res);
16 | },function(err){console.log(err)}
17 | )
18 | }
19 | }
20 | )
21 | },
22 | function(e){
23 | console.log(e)
24 | reject(e)
25 | })
26 | });
27 | };
28 |
29 | CRMWebAPI.prototype.GetOptionSetUserLabels = function (optionSetName) {
30 | var self = this;
31 | return new Promise(function (resolve, reject) {
32 |
33 | self.GetOptionSetByName(optionSetName).then(
34 | function (result)
35 | {
36 | var displayList = new Array();
37 | result.Options.forEach(function (option)
38 | {
39 | var displayOption = new Object;
40 | displayOption.Value = option.Value;
41 | displayOption.Label = option.Label.UserLocalizedLabel.Label;
42 | displayList.push(displayOption);
43 | });
44 | resolve(displayList);
45 | }
46 | ,
47 | function (err)
48 | {
49 | console.log(err)
50 | reject(err);
51 | }
52 | );
53 | });
54 |
55 | }
56 |
57 | CRMWebAPI.prototype.GetEntityDisplayNameList = function (LCID) {
58 | var self = this;
59 | return new Promise(function (resolve, reject) {
60 |
61 |
62 | self.GetList('EntityDefinitions',
63 | {Select:['MetadataId','DisplayName','DisplayCollectionName','LogicalName','LogicalCollectionName','PrimaryIdAttribute']}).then(
64 | function (r)
65 | {
66 | var list = new Array();
67 | r.List.forEach(function(entity)
68 | {
69 | var edm = new Object();
70 | edm.MetadataId = entity.MetadataId;
71 | edm.LogicalName = entity.LogicalName;
72 | edm.LogicalCollectionName = entity.LogicalCollectionName;
73 | edm.PrimaryIdAttribute = entity.PrimaryIdAttribute;
74 | if ((entity.DisplayName.LocalizedLabels != null) && (entity.DisplayName.LocalizedLabels.length > 0))
75 | {
76 | edm.DisplayName = entity.DisplayName.LocalizedLabels[0].Label;
77 | if (LCID != null)
78 | entity.DisplayName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayName = label.Label});
79 | }
80 | else
81 | edm.DisplayName = edm.LogicalName;
82 | if ((entity.DisplayCollectionName.LocalizedLabels != null) && (entity.DisplayCollectionName.LocalizedLabels.length > 0))
83 | {
84 | edm.DisplayCollectionName = entity.DisplayCollectionName.LocalizedLabels[0].Label;
85 | if (LCID != null)
86 | entity.DisplayCollectionName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayCollectionName = label.Label});
87 | }
88 | else
89 | edm.DisplayCollectionName = entity.LogicalCollectionName;
90 | list.push(edm);
91 | }
92 | )
93 | resolve(list);
94 | },
95 | function(e){
96 | console.log(e)
97 | reject(e)
98 | })
99 | });
100 | };
--------------------------------------------------------------------------------
/JS/lib/Releases/CRMWebAPIMetadata-1.1.2.js:
--------------------------------------------------------------------------------
1 | CRMWebAPI.prototype.GetOptionSetByName = function (optionSetName) {
2 | var self = this;
3 | return new Promise(function (resolve, reject) {
4 |
5 | self.GetList('GlobalOptionSetDefinitions',
6 | {Select:['Name']}).then(
7 | function (r)
8 | {
9 | r.List.forEach(function(set)
10 | {
11 | if (set.Name == optionSetName)
12 | {
13 | self.Get('GlobalOptionSetDefinitions',set.MetadataId).then(
14 | function(res){
15 | resolve(res);
16 | },function(err){console.log(err)}
17 | )
18 | }
19 | }
20 | )
21 | },
22 | function(e){
23 | console.log(e)
24 | reject(e)
25 | })
26 | });
27 | };
28 |
29 | CRMWebAPI.prototype.GetOptionSetUserLabels = function (optionSetName) {
30 | var self = this;
31 | return new Promise(function (resolve, reject) {
32 |
33 | self.GetOptionSetByName(optionSetName).then(
34 | function (result)
35 | {
36 | var displayList = new Array();
37 | result.Options.forEach(function (option)
38 | {
39 | var displayOption = new Object;
40 | displayOption.Value = option.Value;
41 | displayOption.Label = option.Label.UserLocalizedLabel.Label;
42 | displayList.push(displayOption);
43 | });
44 | resolve(displayList);
45 | }
46 | ,
47 | function (err)
48 | {
49 | console.log(err)
50 | reject(err);
51 | }
52 | );
53 | });
54 |
55 | }
56 |
57 | CRMWebAPI.prototype.GetEntityDisplayNameList = function (LCID) {
58 | var self = this;
59 | return new Promise(function (resolve, reject) {
60 |
61 |
62 | self.GetList('EntityDefinitions',
63 | {Filter:'IsPrivate eq false',Select:['MetadataId','DisplayName','DisplayCollectionName','LogicalName','LogicalCollectionName','PrimaryIdAttribute']}).then(
64 | function (r)
65 | {
66 | var list = new Array();
67 | r.List.forEach(function(entity)
68 | {
69 | var edm = new Object();
70 | edm.MetadataId = entity.MetadataId;
71 | edm.LogicalName = entity.LogicalName;
72 | edm.LogicalCollectionName = entity.LogicalCollectionName;
73 | edm.PrimaryIdAttribute = entity.PrimaryIdAttribute;
74 | if ((entity.DisplayName.LocalizedLabels != null) && (entity.DisplayName.LocalizedLabels.length > 0))
75 | {
76 | edm.DisplayName = entity.DisplayName.LocalizedLabels[0].Label;
77 | if (LCID != null)
78 | entity.DisplayName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayName = label.Label});
79 | }
80 | else
81 | edm.DisplayName = edm.LogicalName;
82 | if ((entity.DisplayCollectionName.LocalizedLabels != null) && (entity.DisplayCollectionName.LocalizedLabels.length > 0))
83 | {
84 | edm.DisplayCollectionName = entity.DisplayCollectionName.LocalizedLabels[0].Label;
85 | if (LCID != null)
86 | entity.DisplayCollectionName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayCollectionName = label.Label});
87 | }
88 | else
89 | edm.DisplayCollectionName = entity.LogicalCollectionName;
90 | edm.LogicalDisplayName = edm.DisplayName +'(' + edm.LogicalName + ')'
91 | edm.LogicalDisplayCollectionName = edm.DisplayCollectionName +'(' + edm.LogicalCollectionName + ')'
92 | list.push(edm);
93 | }
94 | )
95 | resolve(list);
96 | },
97 | function(e){
98 | console.log(e)
99 | reject(e)
100 | })
101 | });
102 | };
--------------------------------------------------------------------------------
/JS/lib/Releases/CRMWebAPIMetadata-1.1.3.js:
--------------------------------------------------------------------------------
1 | CRMWebAPI.prototype.GetOptionSetByName = function (optionSetName) {
2 | var self = this;
3 | return new Promise(function (resolve, reject) {
4 |
5 | self.GetList('GlobalOptionSetDefinitions',
6 | {Select:['Name']}).then(
7 | function (r)
8 | {
9 | r.List.forEach(function(set)
10 | {
11 | if (set.Name == optionSetName)
12 | {
13 | self.Get('GlobalOptionSetDefinitions',set.MetadataId).then(
14 | function(res){
15 | resolve(res);
16 | },function(err){console.log(err)}
17 | )
18 | }
19 | }
20 | )
21 | },
22 | function(e){
23 | console.log(e)
24 | reject(e)
25 | })
26 | });
27 | };
28 |
29 | CRMWebAPI.prototype.GetOptionSetUserLabels = function (optionSetName) {
30 | var self = this;
31 | return new Promise(function (resolve, reject) {
32 |
33 | self.GetOptionSetByName(optionSetName).then(
34 | function (result)
35 | {
36 | var displayList = new Array();
37 | result.Options.forEach(function (option)
38 | {
39 | var displayOption = new Object;
40 | displayOption.Value = option.Value;
41 | displayOption.Label = option.Label.UserLocalizedLabel.Label;
42 | displayList.push(displayOption);
43 | });
44 | resolve(displayList);
45 | }
46 | ,
47 | function (err)
48 | {
49 | console.log(err)
50 | reject(err);
51 | }
52 | );
53 | });
54 |
55 | }
56 |
57 | CRMWebAPI.prototype.GetEntityDisplayNameList = function (LCID) {
58 | var self = this;
59 | return new Promise(function (resolve, reject) {
60 |
61 |
62 | self.GetList('EntityDefinitions',
63 | {Filter:'IsPrivate eq false',Select:['MetadataId','EntitySetName','DisplayName',
64 | 'DisplayCollectionName','LogicalName','LogicalCollectionName','PrimaryIdAttribute']}).then(
65 | function (r)
66 | {
67 | var list = new Array();
68 | r.List.forEach(function(entity)
69 | {
70 | var edm = new Object();
71 | edm.MetadataId = entity.MetadataId;
72 | edm.EntitySetName = entity.EntitySetName;
73 | edm.LogicalName = entity.LogicalName;
74 | edm.LogicalCollectionName = entity.LogicalCollectionName;
75 | edm.PrimaryIdAttribute = entity.PrimaryIdAttribute;
76 | if ((entity.DisplayName.LocalizedLabels != null) && (entity.DisplayName.LocalizedLabels.length > 0))
77 | {
78 | edm.DisplayName = entity.DisplayName.LocalizedLabels[0].Label;
79 | if (LCID != null)
80 | entity.DisplayName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayName = label.Label});
81 | }
82 | else
83 | edm.DisplayName = edm.LogicalName;
84 | if ((entity.DisplayCollectionName.LocalizedLabels != null) && (entity.DisplayCollectionName.LocalizedLabels.length > 0))
85 | {
86 | edm.DisplayCollectionName = entity.DisplayCollectionName.LocalizedLabels[0].Label;
87 | if (LCID != null)
88 | entity.DisplayCollectionName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayCollectionName = label.Label});
89 | }
90 | else
91 | edm.DisplayCollectionName = entity.LogicalCollectionName;
92 | edm.LogicalDisplayName = edm.DisplayName +'(' + edm.LogicalName + ')'
93 | edm.LogicalDisplayCollectionName = edm.DisplayCollectionName +'(' + edm.LogicalCollectionName + ')'
94 | list.push(edm);
95 | }
96 | )
97 | resolve(list);
98 | },
99 | function(e){
100 | console.log(e)
101 | reject(e)
102 | })
103 | });
104 | };
--------------------------------------------------------------------------------
/JS/lib/Releases/CRMWebAPIMetadata-1.2.0.js:
--------------------------------------------------------------------------------
1 | CRMWebAPI.prototype.GetOptionSetByName = function (optionSetName) {
2 | var self = this;
3 | return new Promise(function (resolve, reject) {
4 |
5 | self.GetList('GlobalOptionSetDefinitions',
6 | {Select:['Name']}).then(
7 | function (r)
8 | {
9 | r.List.forEach(function(set)
10 | {
11 | if (set.Name == optionSetName)
12 | {
13 | self.Get('GlobalOptionSetDefinitions',set.MetadataId).then(
14 | function(res){
15 | resolve(res);
16 | },function(err){console.log(err)}
17 | )
18 | }
19 | }
20 | )
21 | },
22 | function(e){
23 | console.log(e)
24 | reject(e)
25 | })
26 | });
27 | };
28 |
29 | CRMWebAPI.prototype.GetOptionSetUserLabels = function (optionSetName) {
30 | var self = this;
31 | return new Promise(function (resolve, reject) {
32 |
33 | self.GetOptionSetByName(optionSetName).then(
34 | function (result)
35 | {
36 | var displayList = new Array();
37 | result.Options.forEach(function (option)
38 | {
39 | var displayOption = new Object;
40 | displayOption.Value = option.Value;
41 | displayOption.Label = option.Label.UserLocalizedLabel.Label;
42 | displayList.push(displayOption);
43 | });
44 | resolve(displayList);
45 | }
46 | ,
47 | function (err)
48 | {
49 | console.log(err)
50 | reject(err);
51 | }
52 | );
53 | });
54 |
55 | }
56 |
57 | CRMWebAPI.prototype.GetEntityDisplayNameList = function (LCID) {
58 | var self = this;
59 | return new Promise(function (resolve, reject) {
60 |
61 |
62 | self.GetList('EntityDefinitions',
63 | {Filter:'IsPrivate eq false',Select:['MetadataId','EntitySetName','DisplayName',
64 | 'DisplayCollectionName','LogicalName','LogicalCollectionName','PrimaryIdAttribute']}).then(
65 | function (r)
66 | {
67 | var list = new Array();
68 | r.List.forEach(function(entity)
69 | {
70 | var edm = new Object();
71 | edm.MetadataId = entity.MetadataId;
72 | edm.EntitySetName = entity.EntitySetName;
73 | edm.LogicalName = entity.LogicalName;
74 | edm.LogicalCollectionName = entity.LogicalCollectionName;
75 | edm.PrimaryIdAttribute = entity.PrimaryIdAttribute;
76 | if ((entity.DisplayName.LocalizedLabels != null) && (entity.DisplayName.LocalizedLabels.length > 0))
77 | {
78 | edm.DisplayName = entity.DisplayName.LocalizedLabels[0].Label;
79 | if (LCID != null)
80 | entity.DisplayName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayName = label.Label});
81 | }
82 | else
83 | edm.DisplayName = edm.LogicalName;
84 | if ((entity.DisplayCollectionName.LocalizedLabels != null) && (entity.DisplayCollectionName.LocalizedLabels.length > 0))
85 | {
86 | edm.DisplayCollectionName = entity.DisplayCollectionName.LocalizedLabels[0].Label;
87 | if (LCID != null)
88 | entity.DisplayCollectionName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayCollectionName = label.Label});
89 | }
90 | else
91 | edm.DisplayCollectionName = entity.LogicalCollectionName;
92 | edm.LogicalDisplayName = edm.DisplayName +'(' + edm.LogicalName + ')'
93 | edm.LogicalDisplayCollectionName = edm.DisplayCollectionName +'(' + edm.LogicalCollectionName + ')'
94 | list.push(edm);
95 | }
96 | )
97 | resolve(list);
98 | },
99 | function(e){
100 | console.log(e)
101 | reject(e)
102 | })
103 | });
104 | };
105 |
106 |
107 | CRMWebAPI.prototype.GetAttributeDisplayNameList = function (entityID,LCID) {
108 | var self = this;
109 | return new Promise(function (resolve, reject) {
110 |
111 |
112 | self.GetList('EntityDefinitions('+ entityID.toString() + ')/Attributes',
113 | {Select:['MetadataId','DisplayName','LogicalName','AttributeType','IsPrimaryId']}).then(
114 | function (r)
115 | {
116 | var list = new Array();
117 | r.List.forEach(function(attrib)
118 | {
119 | var edm = new Object();
120 | edm.MetadataId = attrib.MetadataId;
121 | edm.LogicalName = attrib.LogicalName;
122 | edm.IsPrimaryId = attrib.IsPrimaryId;
123 | if ((attrib.DisplayName.LocalizedLabels != null) && (attrib.DisplayName.LocalizedLabels.length > 0))
124 | {
125 | edm.DisplayName = attrib.DisplayName.LocalizedLabels[0].Label;
126 | if (LCID != null)
127 | attrib.DisplayName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayName = label.Label});
128 | }
129 | else
130 | edm.DisplayName = edm.LogicalName;
131 | edm.LogicalDisplayName = edm.DisplayName +'(' + edm.LogicalName + ')'
132 | list.push(edm);
133 | }
134 | )
135 | resolve(list);
136 | },
137 | function(e){
138 | console.log(e)
139 | reject(e)
140 | })
141 | });
142 | };
--------------------------------------------------------------------------------
/JS/lib/Releases/CRMWebAPIMetadata-1.2.1.js:
--------------------------------------------------------------------------------
1 | CRMWebAPI.prototype.GetOptionSetByName = function (optionSetName) {
2 | var self = this;
3 | return new Promise(function (resolve, reject) {
4 |
5 | self.GetList('GlobalOptionSetDefinitions',
6 | {Select:['Name']}).then(
7 | function (r)
8 | {
9 | r.List.forEach(function(set)
10 | {
11 | if (set.Name == optionSetName)
12 | {
13 | self.Get('GlobalOptionSetDefinitions',set.MetadataId).then(
14 | function(res){
15 | resolve(res);
16 | },function(err){console.log(err)}
17 | )
18 | }
19 | }
20 | )
21 | },
22 | function(e){
23 | console.log(e)
24 | reject(e)
25 | })
26 | });
27 | };
28 |
29 | CRMWebAPI.prototype.GetOptionSetUserLabels = function (optionSetName) {
30 | var self = this;
31 | return new Promise(function (resolve, reject) {
32 |
33 | self.GetOptionSetByName(optionSetName).then(
34 | function (result)
35 | {
36 | var displayList = new Array();
37 | result.Options.forEach(function (option)
38 | {
39 | var displayOption = new Object;
40 | displayOption.Value = option.Value;
41 | displayOption.Label = option.Label.UserLocalizedLabel.Label;
42 | displayList.push(displayOption);
43 | });
44 | resolve(displayList);
45 | }
46 | ,
47 | function (err)
48 | {
49 | console.log(err)
50 | reject(err);
51 | }
52 | );
53 | });
54 |
55 | }
56 |
57 | CRMWebAPI.prototype.GetEntityDisplayNameList = function (LCID) {
58 | var self = this;
59 | return new Promise(function (resolve, reject) {
60 |
61 |
62 | self.GetList('EntityDefinitions',
63 | {Filter:'IsPrivate eq false',Select:['MetadataId','EntitySetName','DisplayName',
64 | 'DisplayCollectionName','LogicalName','LogicalCollectionName','PrimaryIdAttribute']}).then(
65 | function (r)
66 | {
67 | var list = new Array();
68 | r.List.forEach(function(entity)
69 | {
70 | var edm = new Object();
71 | edm.MetadataId = entity.MetadataId;
72 | edm.EntitySetName = entity.EntitySetName;
73 | edm.LogicalName = entity.LogicalName;
74 | edm.LogicalCollectionName = entity.LogicalCollectionName;
75 | edm.PrimaryIdAttribute = entity.PrimaryIdAttribute;
76 | if ((entity.DisplayName.LocalizedLabels != null) && (entity.DisplayName.LocalizedLabels.length > 0))
77 | {
78 | edm.DisplayName = entity.DisplayName.LocalizedLabels[0].Label;
79 | if (LCID != null)
80 | entity.DisplayName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayName = label.Label});
81 | }
82 | else
83 | edm.DisplayName = edm.LogicalName;
84 | if ((entity.DisplayCollectionName.LocalizedLabels != null) && (entity.DisplayCollectionName.LocalizedLabels.length > 0))
85 | {
86 | edm.DisplayCollectionName = entity.DisplayCollectionName.LocalizedLabels[0].Label;
87 | if (LCID != null)
88 | entity.DisplayCollectionName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayCollectionName = label.Label});
89 | }
90 | else
91 | edm.DisplayCollectionName = entity.LogicalCollectionName;
92 | edm.LogicalDisplayName = edm.DisplayName +'(' + edm.LogicalName + ')'
93 | edm.LogicalDisplayCollectionName = edm.DisplayCollectionName +'(' + edm.LogicalCollectionName + ')'
94 | list.push(edm);
95 | }
96 | )
97 | resolve(list);
98 | },
99 | function(e){
100 | console.log(e)
101 | reject(e)
102 | })
103 | });
104 | };
105 |
106 |
107 | CRMWebAPI.prototype.GetAttributeDisplayNameList = function (entityID,LCID) {
108 | var self = this;
109 | return new Promise(function (resolve, reject) {
110 |
111 |
112 | self.GetList('EntityDefinitions('+ entityID.toString() + ')/Attributes',
113 | {Filter:'((IsValidForRead eq true) and (AttributeOf eq null))',Select:['MetadataId','DisplayName','LogicalName','AttributeType','IsPrimaryId']}).then(
114 | function (r)
115 | {
116 | var list = new Array();
117 | r.List.forEach(function(attrib)
118 | {
119 | var edm = new Object();
120 | edm.MetadataId = attrib.MetadataId;
121 | edm.LogicalName = attrib.LogicalName;
122 | edm.IsPrimaryId = attrib.IsPrimaryId;
123 | edm.AttributeType = attrib.AttributeType;
124 | if (attrib.AttributeType === "Lookup" || attrib.AttributeType === "Customer" || attrib.AttributeType === "Owner")
125 | edm.ODataLogicalName = "_" + attrib.LogicalName + "_value";
126 | else
127 | edm.ODataLogicalName = attrib.LogicalName;
128 |
129 | if ((attrib.DisplayName.LocalizedLabels != null) && (attrib.DisplayName.LocalizedLabels.length > 0))
130 | {
131 | edm.DisplayName = attrib.DisplayName.LocalizedLabels[0].Label;
132 | if (LCID != null)
133 | attrib.DisplayName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayName = label.Label});
134 | }
135 | else
136 | edm.DisplayName = edm.LogicalName;
137 | edm.LogicalDisplayName = edm.DisplayName +'(' + edm.LogicalName + ')'
138 | list.push(edm);
139 | }
140 | )
141 | resolve(list);
142 | },
143 | function(e){
144 | console.log(e)
145 | reject(e)
146 | })
147 | });
148 | };
--------------------------------------------------------------------------------
/JS/lib/Releases/CRMWebAPIMetadata-1.3.0.js:
--------------------------------------------------------------------------------
1 | CRMWebAPI.prototype.GetOptionSetByName = function (optionSetName) {
2 | var self = this;
3 | return new Promise(function (resolve, reject) {
4 |
5 | self.GetList('GlobalOptionSetDefinitions',
6 | {Select:['Name']}).then(
7 | function (r)
8 | {
9 | r.List.forEach(function(set)
10 | {
11 | if (set.Name == optionSetName)
12 | {
13 | self.Get('GlobalOptionSetDefinitions',set.MetadataId).then(
14 | function(res){
15 | resolve(res);
16 | },function(err){console.log(err)}
17 | )
18 | }
19 | }
20 | )
21 | },
22 | function(e){
23 | console.log(e)
24 | reject(e)
25 | })
26 | });
27 | };
28 |
29 | CRMWebAPI.prototype.GetOptionSetUserLabels = function (optionSetName) {
30 | var self = this;
31 | return new Promise(function (resolve, reject) {
32 |
33 | self.GetOptionSetByName(optionSetName).then(
34 | function (result)
35 | {
36 | var displayList = new Array();
37 | result.Options.forEach(function (option)
38 | {
39 | var displayOption = new Object;
40 | displayOption.Value = option.Value;
41 | displayOption.Label = option.Label.UserLocalizedLabel.Label;
42 | displayList.push(displayOption);
43 | });
44 | resolve(displayList);
45 | }
46 | ,
47 | function (err)
48 | {
49 | console.log(err)
50 | reject(err);
51 | }
52 | );
53 | });
54 |
55 | }
56 |
57 | CRMWebAPI.prototype.GetEntityDisplayNameList = function (LCID) {
58 | var self = this;
59 | return new Promise(function (resolve, reject) {
60 |
61 |
62 | self.GetList('EntityDefinitions',
63 | {Filter:'IsPrivate eq false',Select:['MetadataId','EntitySetName','DisplayName',
64 | 'DisplayCollectionName','LogicalName','LogicalCollectionName','PrimaryIdAttribute']}).then(
65 | function (r)
66 | {
67 | var list = new Array();
68 | r.List.forEach(function(entity)
69 | {
70 | var edm = new Object();
71 | edm.MetadataId = entity.MetadataId;
72 | edm.EntitySetName = entity.EntitySetName;
73 | edm.LogicalName = entity.LogicalName;
74 | edm.LogicalCollectionName = entity.LogicalCollectionName;
75 | edm.PrimaryIdAttribute = entity.PrimaryIdAttribute;
76 | if ((entity.DisplayName.LocalizedLabels != null) && (entity.DisplayName.LocalizedLabels.length > 0))
77 | {
78 | edm.DisplayName = entity.DisplayName.LocalizedLabels[0].Label;
79 | if (LCID != null)
80 | entity.DisplayName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayName = label.Label});
81 | }
82 | else
83 | edm.DisplayName = edm.LogicalName;
84 | if ((entity.DisplayCollectionName.LocalizedLabels != null) && (entity.DisplayCollectionName.LocalizedLabels.length > 0))
85 | {
86 | edm.DisplayCollectionName = entity.DisplayCollectionName.LocalizedLabels[0].Label;
87 | if (LCID != null)
88 | entity.DisplayCollectionName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayCollectionName = label.Label});
89 | }
90 | else
91 | edm.DisplayCollectionName = entity.LogicalCollectionName;
92 | edm.LogicalDisplayName = edm.DisplayName +'(' + edm.LogicalName + ')'
93 | edm.LogicalDisplayCollectionName = edm.DisplayCollectionName +'(' + edm.LogicalCollectionName + ')'
94 | list.push(edm);
95 | }
96 | )
97 | resolve(list);
98 | },
99 | function(e){
100 | console.log(e)
101 | reject(e)
102 | })
103 | });
104 | };
105 |
106 |
107 | CRMWebAPI.prototype.GetAttributeDisplayNameList = function (entityID,LCID) {
108 | var self = this;
109 | return new Promise(function (resolve, reject) {
110 |
111 |
112 | self.GetList('EntityDefinitions('+ entityID.toString() + ')/Attributes',
113 | {Filter:'((IsValidForRead eq true) and (AttributeOf eq null))',Select:['MetadataId','DisplayName','LogicalName','SchemaName','AttributeType','IsPrimaryId']}).then(
114 | function (r)
115 | {
116 | var list = new Array();
117 | r.List.forEach(function(attrib)
118 | {
119 | var edm = new Object();
120 | edm.MetadataId = attrib.MetadataId;
121 | edm.LogicalName = attrib.LogicalName;
122 | edm.SchemaName = attrib.SchemaName;
123 | edm.IsPrimaryId = attrib.IsPrimaryId;
124 | edm.AttributeType = attrib.AttributeType;
125 | if (attrib.AttributeType === "Lookup" || attrib.AttributeType === "Customer" || attrib.AttributeType === "Owner")
126 | edm.ODataLogicalName = "_" + attrib.LogicalName + "_value";
127 | else
128 | edm.ODataLogicalName = attrib.LogicalName;
129 |
130 | if ((attrib.DisplayName.LocalizedLabels != null) && (attrib.DisplayName.LocalizedLabels.length > 0))
131 | {
132 | edm.DisplayName = attrib.DisplayName.LocalizedLabels[0].Label;
133 | if (LCID != null)
134 | attrib.DisplayName.LocalizedLabels.forEach(function (label) { if (label.LanguageCode == LCID) edm.DisplayName = label.Label});
135 | }
136 | else
137 | edm.DisplayName = edm.LogicalName;
138 | edm.LogicalDisplayName = edm.DisplayName +'(' + edm.LogicalName + ')'
139 | list.push(edm);
140 | }
141 | )
142 | resolve(list);
143 | },
144 | function(e){
145 | console.log(e)
146 | reject(e)
147 | })
148 | });
149 | };
150 |
151 | CRMWebAPI.prototype.CopyEntityAttribute = function (fromEntityID,toEntityID,fromAttributeID,attributeType,toNames) {
152 | var self = this;
153 | return new Promise(function (resolve, reject) {
154 |
155 | var ec ='EntityDefinitions('+ fromEntityID.toString() + ')/Attributes('+fromAttributeID+')';
156 | if (attributeType == "Boolean")
157 | ec += '/Microsoft.Dynamics.CRM.BooleanAttributeMetadata';
158 | if (attributeType == "Picklist")
159 | ec += '/Microsoft.Dynamics.CRM.PicklistAttributeMetadata';
160 |
161 | self.Get(ec,null,{}).then(
162 | function (r)
163 | {
164 | delete r.MetadataId;
165 | if (attributeType == "Boolean" || attributeType == "Picklist")
166 | {
167 | delete r.DefaultValue;
168 | delete r.FormulaDefinition;
169 | delete r.SourceTypeMask;
170 | delete r.DefaultFormValue;
171 | }
172 | r.LogicalName = toNames.LogicalName;
173 | r.SchemaName = toNames.SchemaName;
174 | console.log(JSON.stringify(r));
175 |
176 | self.Create('EntityDefinitions('+ fromEntityID.toString() + ')/Attributes',r).then(
177 | function (createR)
178 | {
179 | resolve(createR);
180 | },
181 | function(errorR)
182 | {
183 | console.log(errorR)
184 | reject(errorR)
185 | }
186 | );
187 | },
188 | function(e){
189 | console.log(e)
190 | reject(e)
191 | })
192 | });
193 | };
--------------------------------------------------------------------------------
/JS/lib/Releases/README.md:
--------------------------------------------------------------------------------
1 | # CRMWebAPI.js Releases
2 | #### 1.0.0
3 | - intial version
4 | #### 1.1.0
5 | - Added PageAction and RecordAction options to query options
6 | #### 1.2.0
7 | - all functions that take entityID remove {} that is added by Xrm.Page getEntityID so you don't have to pre-process it before passing to API
8 | #### 1.2.1
9 | - allow entity ID to be null when passed to .Get and just use collection name as passed
10 | #### 1.3.0
11 | - Added support for Expand query option
12 |
13 | # CRMWebAPIMetadata.js Releases
14 | #### 1.0.0
15 | - initial version
16 | #### 1.1.3
17 | - added support for GetEntityDisplayNameList
18 | #### 1.2.0
19 | - added support for GetAttributeDisplayNameList
20 | #### 1.2.1
21 | - added filter to GetAttributeDisplayNamelist for attributeof and no read, added ODataLogicalName to handle Owner,Customer and Lookup
22 | #### 1.3.0
23 | - Added CopyEntityAttribute function (note Boolean and Picklist types have a CRM bug)
24 | #### 1.3.1
25 | - Got CopyEntityAttribute to create Boolean and Picklists - as long as picklist isn't global - that is still outstanding
26 | #### 1.3.2
27 | - Got CopyEntityAttribute to create OptionSets pointing to global optionset values
--------------------------------------------------------------------------------
/JS/tests/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mocha Tests
5 |
6 |
7 |
8 |
9 |
10 | AccessToken:
11 |
12 | Run
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/JS/tests/test.node.js:
--------------------------------------------------------------------------------
1 | var expect = require('chai').expect;
2 | var should = require('chai').should();
3 | var CRMWebAPI = require('../lib/CRMWebAPI.js');
4 |
5 | describe('CRMWebAPI', function() {
6 | if(process.env.CRM_ACCESS_TOKEN == undefined) {
7 | console.log('Please provide CRM_ACCESS_TOKEN environment variable. I.e.');
8 | console.log('set CRM_ACCESS_TOKEN=213214213213');
9 | process.exit();
10 | }
11 | var api = new CRMWebAPI({
12 | 'APIUrl': 'https://tr22a.crm.dynamics.com/api/data/v8.0/',
13 | 'AccessToken': process.env.CRM_ACCESS_TOKEN
14 | });
15 |
16 | var uid1 = '7d7e3791-d5bf-e511-80df-c4346bac0574';
17 | var uid2 = '2d60a58f-d5bf-e511-80e2-c4346bacf5c0';
18 | var temp_user_id = '';
19 | var op;
20 |
21 | describe('Create', function(){
22 | it('should return GUID', function () {
23 | return api.Create('accounts', {'name': 'test'})
24 | .then(function(r){
25 | expect(r).to.have.length(36);
26 | expect(r).to.be.a('string');
27 | temp_user_id = r;
28 | }, function(e){
29 | should.not.exist(e);
30 | })
31 | });
32 | it('should return error', function () {
33 | return api.Create('accounts', {'sdadsad': 'sadsad'})
34 | .then(function(r){
35 | should.not.exist(r);
36 | }, function(e){
37 | should.exist(e);
38 | expect(e).to.be.a('object');
39 | })
40 | });
41 | })
42 | describe('Update', function(){
43 | it('should return same GUID', function(){
44 | return api.Update('accounts', temp_user_id, {'name': 'testup'}, false).then(function(r){
45 | expect(r.EntityID).to.have.length(36);
46 | expect(r.EntityID).to.be.a('string');
47 | expect(r.EntityID).to.equal(temp_user_id);
48 | }, function(e){
49 | should.not.exist(e);
50 | });
51 | });
52 | it('should return another GUID', function(){
53 | return api.Update('accounts', temp_user_id.replace('1', '3'), {'name': 'testup'}, true).then(function(r){
54 | expect(r.EntityID).to.have.length(36);
55 | expect(r.EntityID).to.be.a('string');
56 | expect(r.EntityID).not.equal(temp_user_id);
57 | }, function(e){
58 | should.not.exist(e);
59 | });
60 | });
61 | it('should return error', function(){
62 | return api.Update('accounts', temp_user_id + 'adsad', {'name': 'testup'}).then(function(r){
63 | should.not.exist(r);
64 | }, function(e){
65 | should.exist(e);
66 | expect(e).to.be.a('object');
67 | });
68 | });
69 | });
70 | describe('Get', function(){
71 | it('should return object', function(){
72 | return api.Get('accounts', temp_user_id).then(function(r){
73 | expect(r).to.be.a('object');
74 | }, function(e){
75 | should.not.exist(e);
76 | });
77 | });
78 | it('should return error', function(){
79 | return api.Get('accounts', temp_user_id.replace('1', '0')).then(function(r){
80 | should.not.exist(r);
81 | }, function(e){
82 | should.exist(e);
83 | expect(e).to.be.a('object');
84 | });
85 | });
86 | });
87 | describe('Delete', function(){
88 | it('should not return error', function(){
89 | return api.Delete('accounts', temp_user_id).then(function(r){
90 | expect(r).to.equal(true);
91 | }, function(e){
92 | should.not.exist(e);
93 | });
94 | });
95 | it('should return error', function(){
96 | return api.Delete('accounts', temp_user_id.replace('1', '0')).then(function(r){
97 | should.not.exist(r);
98 | }, function(e){
99 | should.exist(e);
100 | expect(e).to.be.a('object');
101 | });
102 | });
103 | });
104 | describe('GetCount', function(){
105 | it('should return object', function(){
106 | return api.GetCount('accounts').then(function(r){
107 | expect(r).to.be.a('number');
108 | }, function(e){
109 | should.not.exist(e);
110 | });
111 | });
112 | it('should return error', function(){
113 | return api.GetCount('accountsadwad').then(function(r){
114 | should.not.exist(r);
115 | }, function(e){
116 | should.exist(e);
117 | expect(e).to.be.a('object');
118 | });
119 | });
120 | });
121 | describe('GetList', function(){
122 | it('should return more than 5001 entries', function(){
123 | return api.GetList('accounts').then(function(r){
124 | expect(r).to.be.a('object');
125 | expect(r.List.length).to.be.at.least(5001);
126 | }, function(e){
127 | should.not.exist(e);
128 | });
129 | });
130 | it('should return error', function(){
131 | return api.GetList('accountsadwad').then(function(r){
132 | should.not.exist(r);
133 | }, function(e){
134 | should.exist(e);
135 | expect(e).to.be.a('object');
136 | });
137 | });
138 | it('get opportunity for action', function(){
139 | return api.GetList("opportunities", {"Top": "1"}).then(function(r){
140 | expect(r).to.be.a('object');
141 | op = r.List[0];
142 | });
143 | });
144 | });
145 | describe('Associate', function(){
146 | it('should return success', function(){
147 | return api.Associate('accounts', uid1, 'account_parent_account', 'accounts', uid2).then(function(r){
148 | expect(r).to.equal(true);
149 | }, function(e){
150 | should.not.exist(e);
151 | });
152 | });
153 | it('should return error', function(){
154 | return api.Associate('accounts', uid1, 'account_parent_account_asd', 'accounts', uid2).then(function(r){
155 | should.not.exist(r);
156 | }, function(e){
157 | should.exist(e);
158 | expect(e).to.be.a('object');
159 | });
160 | });
161 | });
162 | describe('DeleteAssociation', function(){
163 | it('should return success', function(){
164 | return api.DeleteAssociation('accounts', uid1, 'account_parent_account', 'accounts', uid2).then(function(r){
165 | expect(r).to.equal(true);
166 | }, function(e){
167 | should.not.exist(e);
168 | });
169 | });
170 | it('should return error', function(){
171 | return api.DeleteAssociation('accounts', uid1, 'account_parent_account_asd', 'accounts', uid2).then(function(r){
172 | should.not.exist(r);
173 | }, function(e){
174 | should.exist(e);
175 | expect(e).to.be.a('object');
176 | });
177 | });
178 | });
179 | describe('ExecuteFunction', function(){
180 | it('should return object', function(){
181 | return api.ExecuteFunction('WhoAmI').then(function(r){
182 | expect(r).to.be.a('object');
183 | }, function(e){
184 | should.not.exist(e);
185 | });
186 | });
187 | it('should return error', function(){
188 | return api.ExecuteFunction('AmIWho').then(function(r){
189 | should.not.exist(r);
190 | }, function(e){
191 | should.exist(e);
192 | expect(e).to.be.a('object');
193 | });
194 | });
195 | });
196 | describe('ExecuteAction', function(){
197 | // TODO: This returns error but all about the params. Fix params to get object;
198 | it('should return object (returns error in fact)', function(){
199 | var params = {
200 | "Target": {
201 | "opportunityid": op.opportunityid,
202 | "@odata.type": "Microsoft.Dynamics.CRM.opportunity"
203 | },
204 | "NewProcess": null
205 | };
206 | return api.ExecuteAction("SetProcess", params).then(function(r){
207 | expect(r).to.be.a('object');
208 | }, function(e){
209 | //should.not.exist(e); // TODO: Uncomment after params fix and remove all below
210 | expect(JSON.parse(e.response).error.message).to.equal('processstage With Id = 00000000-0000-0000-0000-000000000000 Does Not Exist');
211 | });
212 | });
213 | });
214 | });
215 | /*
216 |
217 |
218 |
219 |
220 |
221 | QUnit.test('Account', 1, function(assert){
222 | QUnit.stop();
223 | api.Create('accounts', {'name': 'testname'}).then(function(r){
224 | assert.equal(r.length, 36);
225 | var id = r;
226 |
227 | api.Get('accounts', id).then(function(r){
228 | assert.equal()
229 | }, function(e){
230 | QUnit.start();
231 | });
232 | }, function(e){
233 | QUnit.start();
234 | });
235 | });
236 | */
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 David Yack
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is an API helper for working with the Common Data Service (CDS) and Dynamics 365 Web API
2 |
3 | Design goals include
4 | - Lightweight
5 | - Simple API signatures as similar as possible across languages
6 | - Integrate well with Azure Active Directory / Authentication libraries but don't bake them in
7 | - JavaScript library to work from web resource or external application
8 |
9 |
10 | There are versions of the API for .NET, JavaScript, Node, Python and PHP with Java coming soon
11 |
12 | Feedback and contributions welcome...if you are going to propose major changes open an issue first to discuss the change.
13 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "xrm.tools.crmwebapi",
3 | "homepage": "https://github.com/davidyack/Xrm.Tools.CRMWebAPI",
4 | "authors": [
5 | "XRM.Tools"
6 | ],
7 | "description": "Helper wrapper to interact with Dynamics 365 API",
8 | "main": [
9 | "js/lib/CRMWebAPI.js"
10 | ],
11 | "moduleType": [
12 | "es6"
13 | ],
14 | "license": "MIT",
15 | "ignore": [
16 | "**/.*",
17 | "dotnet",
18 | "python",
19 | "php",
20 | "nodejs",
21 | "JS/lib/Releases",
22 | "node_modules",
23 | "bower_components",
24 | "test",
25 | "tests",
26 | "archive"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/dotnet/ReadMe.md:
--------------------------------------------------------------------------------
1 |
2 | Install via NuGet (https://www.nuget.org/packages/Xrm.Tools.CRMWebAPI/)
3 |
4 | Support for full .NET, .NET Core and .NET Standard projects
5 |
6 | Install-Package Xrm.Tools.CRMWebAPI
7 | Here is how to get an instance of CRMWebAPI passing an AccessToken
8 | ````
9 | public static CRMWebAPI GetAPI()
10 | {
11 |
12 | CRMWebAPI api = new CRMWebAPI("https://orgname.api.crm.dynamics.com/api/data/v8.0/",
13 | "");
14 | return api;
15 |
16 | }
17 | ````
18 | Here is how to get an instance of CRMWebAPI passing an ADAL with a user and password - to understand how to get a client ID visit the walk through here https://msdn.microsoft.com/en-us/library/mt622431.aspx This requires a native application and is not supported by .NET Core
19 |
20 | ````
21 | public static CRMWebAPI GetAPI()
22 | {
23 | string authority = "https://login.microsoftonline.com/common";
24 | string clientId = "";
25 | string crmBaseUrl = "https://xx.crm.dynamics.com";
26 |
27 | var authContext = new AuthenticationContext(authority);
28 | UserCredential userCreds = new UserPasswordCredential("", "");
29 | var result = authContext.AcquireTokenAsync(crmBaseUrl, clientId, userCreds).Result;
30 | CRMWebAPI api = new CRMWebAPI(crmBaseUrl + "/api/data/v9.0/", result.AccessToken);
31 |
32 | return api;
33 | }
34 | ````
35 |
36 | Here is how to get an instance of CRMWebAPI passing an ADAL with a Server-to-server authentication - to understand Server-to-server authentication visit
37 | https://msdn.microsoft.com/en-us/library/mt790168.aspx
38 | ````
39 | public async static Task GetAPI()
40 | {
41 | string authority = "https://login.microsoftonline.com/";
42 | string clientId = "";
43 | string crmBaseUrl = "https://xx.crm.dynamics.com";
44 | string clientSecret = "";
45 | string tenantID = "";
46 |
47 | var clientcred = new ClientCredential(clientId, clientSecret);
48 | var authContext = new AuthenticationContext(authority + tenantID);
49 | var authenticationResult = await authContext.AcquireTokenAsync(crmBaseUrl, clientcred);
50 |
51 | return new CRMWebAPI(crmBaseUrl + "/api/data/v8.0/", authenticationResult.AccessToken);
52 | }
53 | ````
54 |
55 | Here are a few simple examples
56 | ````
57 | Task.Run(async () =>
58 | {
59 | var api = GetAPI();
60 |
61 | dynamic data = new ExpandoObject();
62 | data.name = "test " + DateTime.Now.ToString();
63 |
64 | Guid createdID = await api.Create("accounts", data);
65 |
66 | var retrievedObject = await api.Get("accounts", createdID, new CRMGetListOptions() { FormattedValues = true });
67 |
68 | var retrievedObjectEx = await api.Get("accounts", createdID);
69 |
70 | dynamic updateObject = new ExpandoObject();
71 | updateObject.name = "updated name " + DateTime.Now.ToString();
72 |
73 | var updateResult = await api.Update("accounts", createdID, updateObject);
74 | //update with an upsert
75 | var upsertResult = await api.Update("accounts", Guid.NewGuid(), updateObject, Upsert: true);
76 |
77 | await api.Delete("accounts", upsertResult.EntityID);
78 |
79 | var results = await api.GetList("accounts", new CRMGetListOptions() { Top = 5, FormattedValues=true });
80 |
81 | string fetchXml = " ";
82 |
83 | var fetchResults = await api.GetList("accounts", QueryOptions: new CRMGetListOptions() { FetchXml = fetchXml });
84 |
85 | var count = await api.GetCount("accounts");
86 | }).Wait();
87 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Core/Xrm.Tools.WebAPI.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp1.0
5 | true
6 | xt.snk
7 | Xrm.Tools.WebAPI
8 | Xrm.Tools.WebAPI
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Core/Xrm.Tools.WebAPI.Core.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26228.9
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xrm.Tools.WebAPI.Core", "Xrm.Tools.WebAPI.Core.csproj", "{34DA42DF-002F-46FE-A087-26C8B516ECB1}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xrm.Tools.WebAPI.Standard", "..\Xrm.Tools.WebAPI.Standard\Xrm.Tools.WebAPI.Standard.csproj", "{F5BACF79-BBCA-407F-A46F-00CBC9227800}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|x64 = Debug|x64
14 | Debug|x86 = Debug|x86
15 | Release|Any CPU = Release|Any CPU
16 | Release|x64 = Release|x64
17 | Release|x86 = Release|x86
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Debug|x64.ActiveCfg = Debug|Any CPU
23 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Debug|x64.Build.0 = Debug|Any CPU
24 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Debug|x86.ActiveCfg = Debug|Any CPU
25 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Debug|x86.Build.0 = Debug|Any CPU
26 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Release|Any CPU.Build.0 = Release|Any CPU
28 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Release|x64.ActiveCfg = Release|Any CPU
29 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Release|x64.Build.0 = Release|Any CPU
30 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Release|x86.ActiveCfg = Release|Any CPU
31 | {34DA42DF-002F-46FE-A087-26C8B516ECB1}.Release|x86.Build.0 = Release|Any CPU
32 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Debug|x64.ActiveCfg = Debug|Any CPU
35 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Debug|x64.Build.0 = Debug|Any CPU
36 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Debug|x86.ActiveCfg = Debug|Any CPU
37 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Debug|x86.Build.0 = Debug|Any CPU
38 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Release|Any CPU.ActiveCfg = Release|Any CPU
39 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Release|Any CPU.Build.0 = Release|Any CPU
40 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Release|x64.ActiveCfg = Release|Any CPU
41 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Release|x64.Build.0 = Release|Any CPU
42 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Release|x86.ActiveCfg = Release|Any CPU
43 | {F5BACF79-BBCA-407F-A46F-00CBC9227800}.Release|x86.Build.0 = Release|Any CPU
44 | EndGlobalSection
45 | GlobalSection(SolutionProperties) = preSolution
46 | HideSolutionNode = FALSE
47 | EndGlobalSection
48 | EndGlobal
49 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Core/bin/Debug/netcoreapp1.0/Xrm.Tools.WebAPI.deps.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimeTarget": {
3 | "name": ".NETCoreApp,Version=v1.0",
4 | "signature": ""
5 | },
6 | "compilationOptions": {},
7 | "targets": {
8 | ".NETCoreApp,Version=v1.0": {
9 | "Xrm.Tools.WebAPI/1.0.0": {
10 | "dependencies": {
11 | "Newtonsoft.Json": "9.0.1"
12 | },
13 | "runtime": {
14 | "Xrm.Tools.WebAPI.dll": {}
15 | }
16 | },
17 | "Newtonsoft.Json/9.0.1": {
18 | "dependencies": {
19 | "System.Runtime.Serialization.Primitives": "4.1.1"
20 | },
21 | "runtime": {
22 | "lib/netstandard1.0/Newtonsoft.Json.dll": {
23 | "assemblyVersion": "9.0.0.0",
24 | "fileVersion": "9.0.1.19813"
25 | }
26 | }
27 | },
28 | "System.Runtime.Serialization.Primitives/4.1.1": {
29 | "runtime": {
30 | "lib/netstandard1.3/System.Runtime.Serialization.Primitives.dll": {
31 | "assemblyVersion": "4.1.1.0",
32 | "fileVersion": "1.0.24212.1"
33 | }
34 | }
35 | }
36 | }
37 | },
38 | "libraries": {
39 | "Xrm.Tools.WebAPI/1.0.0": {
40 | "type": "project",
41 | "serviceable": false,
42 | "sha512": ""
43 | },
44 | "Newtonsoft.Json/9.0.1": {
45 | "type": "package",
46 | "serviceable": true,
47 | "sha512": "sha512-U82mHQSKaIk+lpSVCbWYKNavmNH1i5xrExDEquU1i6I5pV6UMOqRnJRSlKO3cMPfcpp0RgDY+8jUXHdQ4IfXvw==",
48 | "path": "newtonsoft.json/9.0.1",
49 | "hashPath": "newtonsoft.json.9.0.1.nupkg.sha512"
50 | },
51 | "System.Runtime.Serialization.Primitives/4.1.1": {
52 | "type": "package",
53 | "serviceable": true,
54 | "sha512": "sha512-HZ6Du5QrTG8MNJbf4e4qMO3JRAkIboGT5Fk804uZtg3Gq516S7hAqTm2UZKUHa7/6HUGdVy3AqMQKbns06G/cg==",
55 | "path": "system.runtime.serialization.primitives/4.1.1",
56 | "hashPath": "system.runtime.serialization.primitives.4.1.1.nupkg.sha512"
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Core/xt.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI.Core/xt.snk
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI.NuGet/NuGet.exe
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/NuGet.log:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI.NuGet/NuGet.log
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/NuGetPackage.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [switch]$Publish
3 | )
4 |
5 | $ErrorActionPreference = "Stop"
6 | $global:ExitCode = 1
7 |
8 | function Write-Log {
9 |
10 | #region Parameters
11 |
12 | [cmdletbinding()]
13 | Param(
14 | [Parameter(ValueFromPipeline=$true)]
15 | [array] $Messages,
16 |
17 | [Parameter()] [ValidateSet("Error", "Warn", "Info")]
18 | [string] $Level = "Info",
19 |
20 | [Parameter()]
21 | [Switch] $NoConsoleOut = $false,
22 |
23 | [Parameter()]
24 | [String] $ForegroundColor = 'White',
25 |
26 | [Parameter()] [ValidateRange(1,30)]
27 | [Int16] $Indent = 0,
28 |
29 | [Parameter()]
30 | [IO.FileInfo] $Path = ".\NuGet.log",
31 |
32 | [Parameter()]
33 | [Switch] $Clobber,
34 |
35 | [Parameter()]
36 | [String] $EventLogName,
37 |
38 | [Parameter()]
39 | [String] $EventSource,
40 |
41 | [Parameter()]
42 | [Int32] $EventID = 1
43 |
44 | )
45 |
46 | #endregion
47 |
48 | Begin {}
49 |
50 | Process {
51 |
52 | $ErrorActionPreference = "Continue"
53 |
54 | if ($Messages.Length -gt 0) {
55 | try {
56 | foreach($m in $Messages) {
57 | if ($NoConsoleOut -eq $false) {
58 | switch ($Level) {
59 | 'Error' {
60 | Write-Error $m -ErrorAction SilentlyContinue
61 | Write-Host ('{0}{1}' -f (" " * $Indent), $m) -ForegroundColor Red
62 | }
63 | 'Warn' {
64 | Write-Warning $m
65 | }
66 | 'Info' {
67 | Write-Host ('{0}{1}' -f (" " * $Indent), $m) -ForegroundColor $ForegroundColor
68 | }
69 | }
70 | }
71 |
72 | if ($m.Trim().Length -gt 0) {
73 | $msg = '{0}{1} [{2}] : {3}' -f (" " * $Indent), (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $Level.ToUpper(), $m
74 |
75 | if ($Clobber) {
76 | $msg | Out-File -FilePath $Path -Force
77 | } else {
78 | $msg | Out-File -FilePath $Path -Append
79 | }
80 | }
81 |
82 | if ($EventLogName) {
83 |
84 | if (-not $EventSource) {
85 | $EventSource = ([IO.FileInfo] $MyInvocation.ScriptName).Name
86 | }
87 |
88 | if(-not [Diagnostics.EventLog]::SourceExists($EventSource)) {
89 | [Diagnostics.EventLog]::CreateEventSource($EventSource, $EventLogName)
90 | }
91 |
92 | $log = New-Object System.Diagnostics.EventLog
93 | $log.set_log($EventLogName)
94 | $log.set_source($EventSource)
95 |
96 | switch ($Level) {
97 | "Error" { $log.WriteEntry($Message, 'Error', $EventID) }
98 | "Warn" { $log.WriteEntry($Message, 'Warning', $EventID) }
99 | "Info" { $log.WriteEntry($Message, 'Information', $EventID) }
100 | }
101 | }
102 | }
103 | }
104 | catch {
105 | throw "Failed to create log entry in: '$Path'. The error was: '$_'."
106 | }
107 | }
108 | }
109 |
110 | End {}
111 |
112 | <#
113 | .SYNOPSIS
114 | Writes logging information to screen and log file simultaneously.
115 |
116 | .DESCRIPTION
117 | Writes logging information to screen and log file simultaneously. Supports multiple log levels.
118 |
119 | .PARAMETER Messages
120 | The messages to be logged.
121 |
122 | .PARAMETER Level
123 | The type of message to be logged.
124 |
125 | .PARAMETER NoConsoleOut
126 | Specifies to not display the message to the console.
127 |
128 | .PARAMETER ConsoleForeground
129 | Specifies what color the text should be be displayed on the console. Ignored when switch 'NoConsoleOut' is specified.
130 |
131 | .PARAMETER Indent
132 | The number of spaces to indent the line in the log file.
133 |
134 | .PARAMETER Path
135 | The log file path.
136 |
137 | .PARAMETER Clobber
138 | Existing log file is deleted when this is specified.
139 |
140 | .PARAMETER EventLogName
141 | The name of the system event log, e.g. 'Application'.
142 |
143 | .PARAMETER EventSource
144 | The name to appear as the source attribute for the system event log entry. This is ignored unless 'EventLogName' is specified.
145 |
146 | .PARAMETER EventID
147 | The ID to appear as the event ID attribute for the system event log entry. This is ignored unless 'EventLogName' is specified.
148 |
149 | .EXAMPLE
150 | PS C:\> Write-Log -Message "It's all good!" -Path C:\MyLog.log -Clobber -EventLogName 'Application'
151 |
152 | .EXAMPLE
153 | PS C:\> Write-Log -Message "Oops, not so good!" -Level Error -EventID 3 -Indent 2 -EventLogName 'Application' -EventSource "My Script"
154 |
155 | .INPUTS
156 | System.String
157 |
158 | .OUTPUTS
159 | No output.
160 |
161 | .NOTES
162 | Revision History:
163 | 2011-03-10 : Andy Arismendi - Created.
164 | #>
165 | }
166 |
167 | function Create-Process() {
168 | param([string] $fileName, [string] $arguments)
169 |
170 | $pinfo = New-Object System.Diagnostics.ProcessStartInfo
171 | $pinfo.RedirectStandardError = $true
172 | $pinfo.RedirectStandardOutput = $true
173 | $pinfo.UseShellExecute = $false
174 | $pinfo.FileName = $fileName
175 | $pinfo.Arguments = $arguments
176 |
177 | $p = New-Object System.Diagnostics.Process
178 | $p.StartInfo = $pinfo
179 |
180 | return $p
181 | }
182 |
183 | function HandlePublishError {
184 | param([string] $ErrorMessage)
185 |
186 | # Run NuGet Setup
187 | $encodedMessage = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($ErrorMessage))
188 | $setupTask = Start-Process PowerShell.exe "-ExecutionPolicy Unrestricted -File .\NuGetSetup.ps1 -Url $url -Base64EncodedMessage $encodedMessage" -Wait -PassThru
189 |
190 | #Write-Log ("NuGet Setup Task Exit Code: " + $setupTask.ExitCode)
191 |
192 | if ($setupTask.ExitCode -eq 0) {
193 | # Try to push package again
194 | $publishTask = Create-Process .\NuGet.exe ("push " + $_.Name + " -Source " + $url)
195 | $publishTask.Start() | Out-Null
196 | $publishTask.WaitForExit()
197 |
198 | $output = ($publishTask.StandardOutput.ReadToEnd() -Split '[\r\n]') |? {$_}
199 | $error = (($publishTask.StandardError.ReadToEnd() -Split '[\r\n]') |? {$_})
200 | Write-Log $output
201 | Write-Log $error Error
202 |
203 | if ($publishTask.ExitCode -eq 0) {
204 | $global:ExitCode = 0
205 | }
206 | }
207 | elseif ($setupTask.ExitCode -eq 2) {
208 | $global:ExitCode = 2
209 | }
210 | else {
211 | $global:ExitCode = 0
212 | }
213 | }
214 |
215 | function Publish {
216 |
217 | Write-Log " "
218 | Write-Log "Publishing package..." -ForegroundColor Green
219 |
220 | # Get nuget config
221 | [xml]$nugetConfig = Get-Content .\NuGet.Config
222 |
223 | $nugetConfig.configuration.packageSources.add | ForEach-Object {
224 | $url = $_.value
225 |
226 | Write-Log "Repository Url: $url"
227 | Write-Log " "
228 |
229 | Get-ChildItem *.nupkg | Where-Object { $_.Name.EndsWith(".symbols.nupkg") -eq $false } | ForEach-Object {
230 |
231 | # Try to push package
232 | $task = Create-Process .\NuGet.exe ("push " + $_.Name + " -Source " + $url)
233 | $task.Start() | Out-Null
234 | $task.WaitForExit()
235 |
236 | $output = ($task.StandardOutput.ReadToEnd() -Split '[\r\n]') |? { $_ }
237 | $error = ($task.StandardError.ReadToEnd() -Split '[\r\n]') |? { $_ }
238 | Write-Log $output
239 | Write-Log $error Error
240 |
241 | if ($task.ExitCode -gt 0) {
242 | HandlePublishError -ErrorMessage $error
243 | #Write-Log ("HandlePublishError() Exit Code: " + $global:ExitCode)
244 | }
245 | else {
246 | $global:ExitCode = 0
247 | }
248 | }
249 | }
250 | }
251 |
252 | Write-Log " "
253 | Write-Log "NuGet Packager 2.0.3" -ForegroundColor Yellow
254 |
255 | # Make sure the nuget executable is writable
256 | Set-ItemProperty NuGet.exe -Name IsReadOnly -Value $false
257 |
258 | # Make sure the nupkg files are writeable and create backup
259 | if (Test-Path *.nupkg) {
260 | Set-ItemProperty *.nupkg -Name IsReadOnly -Value $false
261 |
262 | Write-Log " "
263 | Write-Log "Creating backup..." -ForegroundColor Green
264 |
265 | Get-ChildItem *.nupkg | ForEach-Object {
266 | Move-Item $_.Name ($_.Name + ".bak") -Force
267 | Write-Log ("Renamed " + $_.Name + " to " + $_.Name + ".bak")
268 | }
269 | }
270 |
271 | Write-Log " "
272 | Write-Log "Updating NuGet..." -ForegroundColor Green
273 | Write-Log (Invoke-Command {.\NuGet.exe update -Self} -ErrorAction Stop)
274 |
275 | Write-Log " "
276 | Write-Log "Creating package..." -ForegroundColor Green
277 |
278 | # Create symbols package if any .pdb files are located in the lib folder
279 | If ((Get-ChildItem *.pdb -Path .\lib -Recurse).Count -gt 0) {
280 | $packageTask = Create-Process .\NuGet.exe ("pack Package.nuspec -Symbol -Verbosity Detailed")
281 | $packageTask.Start() | Out-Null
282 | $packageTask.WaitForExit()
283 |
284 | $output = ($packageTask.StandardOutput.ReadToEnd() -Split '[\r\n]') |? {$_}
285 | $error = (($packageTask.StandardError.ReadToEnd() -Split '[\r\n]') |? {$_})
286 | Write-Log $output
287 | Write-Log $error Error
288 |
289 | $global:ExitCode = $packageTask.ExitCode
290 | }
291 | Else {
292 | $packageTask = Create-Process .\NuGet.exe ("pack Package.nuspec -Verbosity Detailed")
293 | $packageTask.Start() | Out-Null
294 | $packageTask.WaitForExit()
295 |
296 | $output = ($packageTask.StandardOutput.ReadToEnd() -Split '[\r\n]') |? {$_}
297 | $error = (($packageTask.StandardError.ReadToEnd() -Split '[\r\n]') |? {$_})
298 | Write-Log $output
299 | Write-Log $error Error
300 |
301 | $global:ExitCode = $packageTask.ExitCode
302 | }
303 |
304 | # Check if package should be published
305 | if ($Publish -and $global:ExitCode -eq 0) {
306 | Publish
307 | }
308 |
309 | Write-Log " "
310 | Write-Log "Exit Code: $global:ExitCode" -ForegroundColor Gray
311 |
312 | $host.SetShouldExit($global:ExitCode)
313 | Exit $global:ExitCode
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/NuGetSetup.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$Url,
3 | [string]$Base64EncodedMessage
4 | )
5 |
6 | $ErrorActionPreference = "Stop"
7 | $ExitCode = 1
8 |
9 | function Write-Log {
10 |
11 | #region Parameters
12 |
13 | [cmdletbinding()]
14 | Param(
15 | [Parameter(ValueFromPipeline=$true)]
16 | [array] $Messages,
17 |
18 | [Parameter()] [ValidateSet("Error", "Warn", "Info")]
19 | [string] $Level = "Info",
20 |
21 | [Parameter()]
22 | [Switch] $NoConsoleOut = $false,
23 |
24 | [Parameter()]
25 | [String] $ForegroundColor = 'White',
26 |
27 | [Parameter()] [ValidateRange(1,30)]
28 | [Int16] $Indent = 0,
29 |
30 | [Parameter()]
31 | [IO.FileInfo] $Path = ".\NuGet.log",
32 |
33 | [Parameter()]
34 | [Switch] $Clobber,
35 |
36 | [Parameter()]
37 | [String] $EventLogName,
38 |
39 | [Parameter()]
40 | [String] $EventSource,
41 |
42 | [Parameter()]
43 | [Int32] $EventID = 1
44 |
45 | )
46 |
47 | #endregion
48 |
49 | Begin {}
50 |
51 | Process {
52 |
53 | $ErrorActionPreference = "Continue"
54 |
55 | if ($Messages.Length -gt 0) {
56 | try {
57 | foreach($m in $Messages) {
58 | if ($NoConsoleOut -eq $false) {
59 | switch ($Level) {
60 | 'Error' {
61 | Write-Error $m -ErrorAction SilentlyContinue
62 | Write-Host ('{0}{1}' -f (" " * $Indent), $m) -ForegroundColor Red
63 | }
64 | 'Warn' {
65 | Write-Warning $m
66 | }
67 | 'Info' {
68 | Write-Host ('{0}{1}' -f (" " * $Indent), $m) -ForegroundColor $ForegroundColor
69 | }
70 | }
71 | }
72 |
73 | if ($m.Trim().Length -gt 0) {
74 | $msg = '{0}{1} [{2}] : {3}' -f (" " * $Indent), (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $Level.ToUpper(), $m
75 |
76 | if ($Clobber) {
77 | $msg | Out-File -FilePath $Path -Force
78 | } else {
79 | $msg | Out-File -FilePath $Path -Append
80 | }
81 | }
82 |
83 | if ($EventLogName) {
84 |
85 | if (-not $EventSource) {
86 | $EventSource = ([IO.FileInfo] $MyInvocation.ScriptName).Name
87 | }
88 |
89 | if(-not [Diagnostics.EventLog]::SourceExists($EventSource)) {
90 | [Diagnostics.EventLog]::CreateEventSource($EventSource, $EventLogName)
91 | }
92 |
93 | $log = New-Object System.Diagnostics.EventLog
94 | $log.set_log($EventLogName)
95 | $log.set_source($EventSource)
96 |
97 | switch ($Level) {
98 | "Error" { $log.WriteEntry($Message, 'Error', $EventID) }
99 | "Warn" { $log.WriteEntry($Message, 'Warning', $EventID) }
100 | "Info" { $log.WriteEntry($Message, 'Information', $EventID) }
101 | }
102 | }
103 | }
104 | }
105 | catch {
106 | throw "Failed to create log entry in: '$Path'. The error was: '$_'."
107 | }
108 | }
109 | }
110 |
111 | End {}
112 |
113 | <#
114 | .SYNOPSIS
115 | Writes logging information to screen and log file simultaneously.
116 |
117 | .DESCRIPTION
118 | Writes logging information to screen and log file simultaneously. Supports multiple log levels.
119 |
120 | .PARAMETER Messages
121 | The messages to be logged.
122 |
123 | .PARAMETER Level
124 | The type of message to be logged.
125 |
126 | .PARAMETER NoConsoleOut
127 | Specifies to not display the message to the console.
128 |
129 | .PARAMETER ConsoleForeground
130 | Specifies what color the text should be be displayed on the console. Ignored when switch 'NoConsoleOut' is specified.
131 |
132 | .PARAMETER Indent
133 | The number of spaces to indent the line in the log file.
134 |
135 | .PARAMETER Path
136 | The log file path.
137 |
138 | .PARAMETER Clobber
139 | Existing log file is deleted when this is specified.
140 |
141 | .PARAMETER EventLogName
142 | The name of the system event log, e.g. 'Application'.
143 |
144 | .PARAMETER EventSource
145 | The name to appear as the source attribute for the system event log entry. This is ignored unless 'EventLogName' is specified.
146 |
147 | .PARAMETER EventID
148 | The ID to appear as the event ID attribute for the system event log entry. This is ignored unless 'EventLogName' is specified.
149 |
150 | .EXAMPLE
151 | PS C:\> Write-Log -Message "It's all good!" -Path C:\MyLog.log -Clobber -EventLogName 'Application'
152 |
153 | .EXAMPLE
154 | PS C:\> Write-Log -Message "Oops, not so good!" -Level Error -EventID 3 -Indent 2 -EventLogName 'Application' -EventSource "My Script"
155 |
156 | .INPUTS
157 | System.String
158 |
159 | .OUTPUTS
160 | No output.
161 |
162 | .NOTES
163 | Revision History:
164 | 2011-03-10 : Andy Arismendi - Created.
165 | #>
166 | }
167 |
168 | $choices = [System.Management.Automation.Host.ChoiceDescription[]](
169 | (New-Object System.Management.Automation.Host.ChoiceDescription "&Add API Key","Add an API Key for this URL"),
170 | (New-Object System.Management.Automation.Host.ChoiceDescription "&Skip","Skip pushing to this URL"))
171 |
172 | Write-Output ""
173 | Write-Log "Invalid API key for this repository URL, or there is a version conflict" Warn
174 |
175 | If ($Base64EncodedMessage) {
176 | Write-Warning ([System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($Base64EncodedMessage)))
177 | }
178 |
179 | $firstAnswer = $Host.UI.PromptForChoice(("Would you like to try adding an API key for " + $Url + "?"), "", $choices, (1))
180 |
181 | if ($firstAnswer -eq 0) {
182 | $fields = new-object "System.Collections.ObjectModel.Collection``1[[System.Management.Automation.Host.FieldDescription]]"
183 |
184 | $f = New-Object System.Management.Automation.Host.FieldDescription "API Key for $Url"
185 | $f.SetParameterType( [System.Security.SecureString] )
186 | $f.HelpMessage = "Please enter API Key for $Url"
187 | $f.Label = "&API Key for $Url"
188 |
189 | $fields.Add($f)
190 |
191 | $results = $Host.UI.Prompt( "Add API Key", "", $fields )
192 |
193 | $pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($results["API Key for $Url"]))
194 |
195 | # Add API Key to config file
196 | Write-Log (.\NuGet.exe setApiKey $pass -Source $Url)
197 |
198 | if ($LASTEXITCODE -le 0) {
199 | $ExitCode = 0
200 | }
201 | }
202 | else {
203 | Write-Log "Skipping..."
204 | $ExitCode = 2
205 | }
206 |
207 | $host.SetShouldExit($ExitCode)
208 | Exit $ExitCode
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/Package.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Xrm.Tools.CRMWebAPI
5 | 1.0.24
6 | Xrm.Tools.CRMWebAPI
7 | DavidYack
8 |
9 |
10 | This is an API helper for working with the Common Data Service (CDS) and Dynamics 365 Web API
11 |
12 |
13 |
14 | 1.0.0 Initial release
15 | 1.0.1 Cleanup of the API, more comments
16 | 1.0.2 removed JToken from public APIs
17 | 1.0.3 added uwp binary
18 | 1.0.4 fixed bug in ExecuteFunction, added support for Formatted Values
19 | 1.0.5 allow network credentials to be optional for on-prem
20 | 1.0.6 added Metadata Extension methods
21 | 1.0.7 added Expand support to Query Options
22 | 1.0.8 fixed references to System.Net.Http
23 | 1.0.9 added dependency for System.Net.Http.Formatting
24 | 1.0.10 Fixed issue if Select and Orderby were both used
25 | 1.0.11 Improved contents of exception messages
26 | 1.0.12 Fixed issue with Upsert with alternate key
27 | 1.0.13 Added .net core assembly support
28 | 1.0.14 fixed target file for netcore in nuget spec
29 | 1.0.15 fixed target file for netcore in nuget spec
30 | 1.0.16 added .net standard support, fixed return of ID with non lower service url
31 | 1.0.17 fixed ExecuteFunction serialization of object parameters,
32 | GetList by type honor formatted values option
33 | 1.0.18 added support for Entity Change Tracking
34 | 1.0.19 Fixed FetchXML when other params, fix for mixed case org url, Config as a param
35 | 1.0.20 Fixed parsing of entityid on create, added aggregate support
36 | 1.0.21 Removed full framework version of nuget in favor of .net standard
37 | 1.0.22 Changed assembly name of standard version to just Xrm.Tools.WebAPI
38 | 1.0.23 Changed assembly name of core version to just Xrm.Tools.WebAPI
39 | 1.0.24 Added Associate and DeleteAssocation methods
40 |
41 |
42 | This is an API helper for working with the Common Data Service/Dynamics 365 Web API
43 |
44 | en-US
45 | https://github.com/davidyack/Xrm.Tools.CRMWebAPI
46 | https://nuget.org/Content/Images/packageDefaultIcon-50x50.png
47 | false
48 | https://github.com/davidyack/Xrm.Tools.CRMWebAPI/blob/master/LICENSE
49 | Copyright 2018
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Xrm.Tools.WebAPI.NuGet")]
9 | [assembly: AssemblyDescription("Project template made by EyeCatch (http://www.eyecatch.no/)")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Xrm.Tools.WebAPI.NuGet")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("5b586874-8d3e-4137-9ba8-e982413416d5")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.0.nupkg.bak:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.0.nupkg.bak
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.1.nupkg.bak:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.1.nupkg.bak
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.2.nupkg.bak:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.2.nupkg.bak
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.24.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.24.nupkg
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.3.nupkg.bak:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.3.nupkg.bak
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.4.nupkg.bak:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.4.nupkg.bak
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.5.nupkg.bak:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.CRMWebAPI.1.0.5.nupkg.bak
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/Xrm.Tools.WebAPI.NuGet.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {0451BAEF-DF2E-4B98-8644-94EE9415E389}
9 | Library
10 | Properties
11 | Xrm.Tools.WebAPI.NuGet
12 | Xrm.Tools.WebAPI.NuGet
13 | v4.5.2
14 |
15 |
16 | 512
17 |
18 |
19 | AnyCPU
20 | true
21 | full
22 | false
23 | bin\Debug\
24 | DEBUG;TRACE
25 | prompt
26 | 4
27 |
28 |
29 | AnyCPU
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 | AnyCPU
39 | bin\Debug\
40 | false
41 |
42 |
43 | AnyCPU
44 | bin\Release\
45 | false
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | ..\packages\Newtonsoft.Json.8.0.2\lib\net35\Newtonsoft.Json.dll
72 | True
73 |
74 |
75 |
76 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/tools/init.ps1:
--------------------------------------------------------------------------------
1 | # Runs the first time a package is installed in a solution, and every time the solution is opened.
2 |
3 | param($installPath, $toolsPath, $package, $project)
4 |
5 | # $installPath is the path to the folder where the package is installed.
6 | # $toolsPath is the path to the tools directory in the folder where the package is installed.
7 | # $package is a reference to the package object.
8 | # $project is null in init.ps1
9 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/tools/install.ps1:
--------------------------------------------------------------------------------
1 | # Runs every time a package is installed in a project
2 |
3 | param($installPath, $toolsPath, $package, $project)
4 |
5 | # $installPath is the path to the folder where the package is installed.
6 | # $toolsPath is the path to the tools directory in the folder where the package is installed.
7 | # $package is a reference to the package object.
8 | # $project is a reference to the project the package was installed to.
9 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.NuGet/tools/uninstall.ps1:
--------------------------------------------------------------------------------
1 | # Runs every time a package is uninstalled
2 |
3 | param($installPath, $toolsPath, $package, $project)
4 |
5 | # $installPath is the path to the folder where the package is installed.
6 | # $toolsPath is the path to the tools directory in the folder where the package is installed.
7 | # $package is a reference to the package object.
8 | # $project is a reference to the project the package was installed to.
9 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Portable/CRMOptionDisplayValue.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Xrm.Tools.WebAPI.Results
8 | {
9 | public class CRMOptionDisplayValue
10 | {
11 | public long Value { get; set; }
12 | public string Label { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Portable/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Resources;
2 | using System.Reflection;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("Xrm.Tools.WebAPI.Portable")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("Xrm.Tools.WebAPI.Portable")]
14 | [assembly: AssemblyCopyright("Copyright © 2016")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 | [assembly: NeutralResourcesLanguage("en")]
18 |
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Build and Revision Numbers
27 | // by using the '*' as shown below:
28 | // [assembly: AssemblyVersion("1.0.*")]
29 | [assembly: AssemblyVersion("1.0.0.0")]
30 | [assembly: AssemblyFileVersion("1.0.0.0")]
31 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Portable/Xrm.Tools.WebAPI.Portable.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 14.0
6 | Debug
7 | AnyCPU
8 | {2E161345-1A64-45A9-A31B-FDC7054BBEFB}
9 | Library
10 | Properties
11 | Xrm.Tools.WebAPI.Portable
12 | Xrm.Tools.WebAPI.Portable
13 | en-US
14 | 512
15 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
16 |
17 |
18 | v5.0
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | TRACE;DEBUG;WINDOWS_APP
26 | prompt
27 | 4
28 | false
29 |
30 |
31 | pdbonly
32 | true
33 | bin\Release\
34 | TRACE
35 | prompt
36 | 4
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | CRMWebAPI.cs
45 |
46 |
47 | CRMExpandOptions.cs
48 |
49 |
50 | CRMGetListOptions.cs
51 |
52 |
53 | CRMBatchResult.cs
54 |
55 |
56 | CRMGetListResult.cs
57 |
58 |
59 | CRMMultipleOperationResultItem.cs
60 |
61 |
62 | CRMUpdateResult.cs
63 |
64 |
65 | CRMWebAPIException.cs
66 |
67 |
68 |
69 |
70 |
71 |
78 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Portable/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "supports": {
3 | "net46.app": {},
4 | "uwp.10.0.app": {}
5 | },
6 | "dependencies": {
7 | "Microsoft.NETCore": "5.0.0",
8 | "Microsoft.NETCore.Portable.Compatibility": "1.0.0",
9 | "Newtonsoft.Json": "8.0.2"
10 | },
11 | "frameworks": {
12 | "dotnet": {
13 | "imports": "portable-net452+win81"
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Standard/Xrm.Tools.WebAPI.Standard.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard1.4;netstandard2.0
5 | true
6 | xt.snk
7 | Xrm.Tools.WebAPI
8 | Xrm.Tools.WebAPI
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Standard/xt.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI.Standard/xt.snk
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Test/ActionTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using System.Threading.Tasks;
4 | using System.Dynamic;
5 | using System.Collections.Generic;
6 |
7 | namespace Xrm.Tools.WebAPI.Test
8 | {
9 | [TestClass]
10 | public class ActionTests : UnitTestBaseClass
11 | {
12 | [TestMethod]
13 | public void TestWinOpportunity()
14 | {
15 |
16 | Task.Run(async () =>
17 | {
18 | var api = GetAPI();
19 |
20 | dynamic account = new ExpandoObject();
21 | account.name = "test " + DateTime.Now.ToString();
22 | Guid accountID = await api.Create("accounts", account);
23 |
24 | dynamic contact = new ExpandoObject();
25 | contact.firstname = "test " + DateTime.Now.ToString();
26 | contact.lastname = "test " + DateTime.Now.ToString();
27 | Guid contactID = await api.Create("contacts", contact);
28 |
29 | dynamic opportunity = new ExpandoObject();
30 | var oppIndexer = opportunity as IDictionary;
31 | opportunity.name = "Test opportunity " + DateTime.Now.ToString();
32 | oppIndexer["customerid_account@odata.bind"] = "/accounts(" + accountID.ToString() + ")";
33 | oppIndexer["parentcontactid@odata.bind"] = "/contacts(" + contactID.ToString() + ")";
34 | Guid oppID = await api.Create("opportunities", opportunity);
35 |
36 | dynamic opportClose = new ExpandoObject();
37 | var opportCloseIndexer = opportClose as IDictionary;
38 | opportClose.subject = "Won Opportunity";
39 | opportCloseIndexer["opportunityid@odata.bind"] = "/opportunities(" + oppID.ToString() + ")";
40 | dynamic lostOpportParams = new ExpandoObject();
41 | lostOpportParams.Status = 3;
42 | lostOpportParams.OpportunityClose = opportClose;
43 | await api.ExecuteAction("WinOpportunity", lostOpportParams);
44 |
45 | System.Diagnostics.Trace.WriteLine("finished");
46 |
47 |
48 | }).Wait();
49 | }
50 | [TestMethod]
51 | public void TestLostOpportunity()
52 | {
53 |
54 | Task.Run(async () =>
55 | {
56 | var api = GetAPI();
57 |
58 | dynamic account = new ExpandoObject();
59 | account.name = "test " + DateTime.Now.ToString();
60 | Guid accountID = await api.Create("accounts", account);
61 |
62 | dynamic contact = new ExpandoObject();
63 | contact.firstname = "test " + DateTime.Now.ToString();
64 | contact.lastname = "test " + DateTime.Now.ToString();
65 | Guid contactID = await api.Create("contacts", contact);
66 |
67 | dynamic opportunity = new ExpandoObject();
68 | var oppIndexer = opportunity as IDictionary;
69 | opportunity.name = "Test opportunity " + DateTime.Now.ToString();
70 | oppIndexer["customerid_account@odata.bind"] = "/accounts(" + accountID.ToString() + ")";
71 | oppIndexer["parentcontactid@odata.bind"] = "/contacts(" + contactID.ToString() + ")";
72 | Guid oppID = await api.Create("opportunities", opportunity);
73 |
74 | dynamic opportClose = new ExpandoObject();
75 | var opportCloseIndexer = opportClose as IDictionary;
76 | opportClose.subject = "Lost Opportunity";
77 | opportCloseIndexer["opportunityid@odata.bind"] = "/opportunities(" + oppID.ToString() +")";
78 | dynamic lostOpportParams = new ExpandoObject();
79 | lostOpportParams.Status = 4;
80 | lostOpportParams.OpportunityClose = opportClose;
81 | await api.ExecuteAction("LoseOpportunity", lostOpportParams);
82 |
83 | System.Diagnostics.Trace.WriteLine("finished");
84 |
85 |
86 | }).Wait();
87 | }
88 |
89 | [TestMethod]
90 | public void TestCalculateRollup()
91 | {
92 |
93 | Task.Run(async () =>
94 | {
95 | var api = GetAPI();
96 |
97 | dynamic voteCountUpdate = new ExpandoObject();
98 | voteCountUpdate.Target = new ExpandoObject();
99 | var ivote = voteCountUpdate.Target as IDictionary;
100 |
101 | ivote["@odata.id"] = "ctccrm_ideas(19dc848b-1c5e-e711-8112-e0071b66aea1)";
102 | voteCountUpdate.FieldName = "ctccrm_votes";
103 | await api.ExecuteFunction("CalculateRollupField", voteCountUpdate);
104 |
105 |
106 | System.Diagnostics.Trace.WriteLine("finished");
107 |
108 |
109 | }).Wait();
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Test/BasicChangeTrackingTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using System.Threading.Tasks;
4 | using System.Dynamic;
5 |
6 | namespace Xrm.Tools.WebAPI.Test
7 | {
8 | [TestClass]
9 | public class BasicChangeTrackingTests : UnitTestBaseClass
10 | {
11 | [TestMethod]
12 | public void TestMethod1()
13 | {
14 |
15 | Task.Run(async () =>
16 | {
17 | var api = GetAPI();
18 |
19 | var results = await api.GetList("accounts", new Requests.CRMGetListOptions() { TrackChanges=true, FormattedValues = true });
20 |
21 | results = await api.GetList("accounts", new Requests.CRMGetListOptions() { TrackChanges = true, TrackChangesLink=results.TrackChangesLink, FormattedValues = true });
22 |
23 | dynamic data = new ExpandoObject();
24 | data.name = "test " + DateTime.Now.ToString();
25 |
26 | Guid createdID = await api.Create("accounts", data);
27 |
28 | results = await api.GetList("accounts", new Requests.CRMGetListOptions() { TrackChanges = true, TrackChangesLink = results.TrackChangesLink, FormattedValues = true });
29 |
30 | }).Wait();
31 |
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Test/BasicMetadataTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using Xrm.Tools.WebAPI;
4 | using Xrm.Tools.WebAPI.Metadata;
5 | using System.Threading.Tasks;
6 | using System.Linq;
7 | using System.Dynamic;
8 |
9 | namespace Xrm.Tools.WebAPI.Test
10 | {
11 | [TestClass]
12 | public class BasicMetadataTests : UnitTestBaseClass
13 | {
14 | [TestMethod]
15 | public void TestOptionSetNames()
16 | {
17 | Task.Run(async () =>
18 | {
19 | var api = GetAPI();
20 |
21 | var optionSet = await api.GetOptionSetByName("need");
22 |
23 | var optionSetLabels = await api.GetOptionSetUserLabels("need");
24 |
25 | }).Wait();
26 |
27 | }
28 |
29 | [TestMethod]
30 | public void TestEntitySetNames()
31 | {
32 | Task.Run(async () =>
33 | {
34 | var api = GetAPI();
35 |
36 | var entityNameList = await api.GetEntityDisplayNameList();
37 |
38 | var entityNameListWithLCID = await api.GetEntityDisplayNameList(1033);
39 |
40 | }).Wait();
41 |
42 | }
43 |
44 | [TestMethod]
45 | public void TestAttributeNames()
46 | {
47 | Task.Run(async () =>
48 | {
49 | var api = GetAPI();
50 |
51 | var entityNameList = await api.GetEntityDisplayNameList();
52 |
53 | var firstEntity = entityNameList.Where(e => e.LogicalName == "account").FirstOrDefault();
54 |
55 | var attrNameList = await api.GetAttributeDisplayNameList(firstEntity.MetadataId);
56 |
57 | var attrNameListWithLCID = await api.GetAttributeDisplayNameList(firstEntity.MetadataId,1033);
58 |
59 | }).Wait();
60 |
61 | }
62 |
63 | [TestMethod]
64 | public void TestCopyAttribute()
65 | {
66 | Task.Run(async () =>
67 | {
68 | var api = GetAPI();
69 |
70 | var entityNameList = await api.GetEntityDisplayNameList();
71 |
72 | var accountEntity = entityNameList.Where(e => e.LogicalName == "account").FirstOrDefault();
73 |
74 | var attrNameList = await api.GetAttributeDisplayNameList(accountEntity.MetadataId);
75 |
76 | var nameAttr = attrNameList.Where(a => a.LogicalName == "name").FirstOrDefault();
77 |
78 | var newAttrib = await api.CopyEntityAttribute(accountEntity.MetadataId, accountEntity.MetadataId, nameAttr.MetadataId, nameAttr.AttributeType, "dy_name123");
79 |
80 | }).Wait();
81 |
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Test/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Xrm.Tools.WebAPI.Test")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Xrm.Tools.WebAPI.Test")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("2492b98c-952b-41f5-99d3-1168d192e322")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Test/UnitTestBaseClass.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Xrm.Tools.WebAPI.Test
8 | {
9 | public class UnitTestBaseClass
10 | {
11 | public CRMWebAPI GetAPI()
12 | {
13 |
14 | CRMWebAPI api = new CRMWebAPI("https://orgname.api.crm.dynamics.com/api/data/v9.0/", "");
15 | return api;
16 |
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Test/Xrm.Tools.WebAPI.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {2492B98C-952B-41F5-99D3-1168D192E322}
7 | Library
8 | Properties
9 | Xrm.Tools.WebAPI.Test
10 | Xrm.Tools.WebAPI.Test
11 | v4.6
12 | 512
13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 10.0
15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
17 | False
18 | UnitTest
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 4
28 |
29 |
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 |
40 | ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll
41 | True
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | False
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | {8d1c4066-5def-4cc9-b84f-58944bbe86f0}
71 | Xrm.Tools.WebAPI
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | False
83 |
84 |
85 | False
86 |
87 |
88 | False
89 |
90 |
91 | False
92 |
93 |
94 |
95 |
96 |
97 |
98 |
105 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Test/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.Test/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26730.3
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xrm.Tools.WebAPI", "Xrm.Tools.WebAPI\Xrm.Tools.WebAPI.csproj", "{8D1C4066-5DEF-4CC9-B84F-58944BBE86F0}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xrm.Tools.WebAPI.Test", "Xrm.Tools.WebAPI.Test\Xrm.Tools.WebAPI.Test.csproj", "{2492B98C-952B-41F5-99D3-1168D192E322}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xrm.Tools.WebAPI.NuGet", "Xrm.Tools.WebAPI.NuGet\Xrm.Tools.WebAPI.NuGet.csproj", "{0451BAEF-DF2E-4B98-8644-94EE9415E389}"
11 | EndProject
12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xrm.Tools.WebAPI.Core", "Xrm.Tools.WebAPI.Core\Xrm.Tools.WebAPI.Core.csproj", "{96734240-AB11-44F0-B47D-9169F4334403}"
13 | EndProject
14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xrm.Tools.WebAPI.Standard", "Xrm.Tools.WebAPI.Standard\Xrm.Tools.WebAPI.Standard.csproj", "{94F41AEC-9406-44E1-BE56-2E786C51CCA7}"
15 | EndProject
16 | Global
17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
18 | Debug|Any CPU = Debug|Any CPU
19 | Release|Any CPU = Release|Any CPU
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {8D1C4066-5DEF-4CC9-B84F-58944BBE86F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {8D1C4066-5DEF-4CC9-B84F-58944BBE86F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {8D1C4066-5DEF-4CC9-B84F-58944BBE86F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {8D1C4066-5DEF-4CC9-B84F-58944BBE86F0}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {2492B98C-952B-41F5-99D3-1168D192E322}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {2492B98C-952B-41F5-99D3-1168D192E322}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {2492B98C-952B-41F5-99D3-1168D192E322}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {2492B98C-952B-41F5-99D3-1168D192E322}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {0451BAEF-DF2E-4B98-8644-94EE9415E389}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 | {0451BAEF-DF2E-4B98-8644-94EE9415E389}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 | {0451BAEF-DF2E-4B98-8644-94EE9415E389}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {0451BAEF-DF2E-4B98-8644-94EE9415E389}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {96734240-AB11-44F0-B47D-9169F4334403}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35 | {96734240-AB11-44F0-B47D-9169F4334403}.Debug|Any CPU.Build.0 = Debug|Any CPU
36 | {96734240-AB11-44F0-B47D-9169F4334403}.Release|Any CPU.ActiveCfg = Release|Any CPU
37 | {96734240-AB11-44F0-B47D-9169F4334403}.Release|Any CPU.Build.0 = Release|Any CPU
38 | {94F41AEC-9406-44E1-BE56-2E786C51CCA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {94F41AEC-9406-44E1-BE56-2E786C51CCA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {94F41AEC-9406-44E1-BE56-2E786C51CCA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
41 | {94F41AEC-9406-44E1-BE56-2E786C51CCA7}.Release|Any CPU.Build.0 = Release|Any CPU
42 | EndGlobalSection
43 | GlobalSection(SolutionProperties) = preSolution
44 | HideSolutionNode = FALSE
45 | EndGlobalSection
46 | GlobalSection(ExtensibilityGlobals) = postSolution
47 | SolutionGuid = {9BE9241F-12DA-4E8E-9656-FD2A4AD05809}
48 | EndGlobalSection
49 | EndGlobal
50 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Metadata/CRMWebAPIMetadata.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Dynamic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using Xrm.Tools.WebAPI.Requests;
8 | using Xrm.Tools.WebAPI.Results;
9 |
10 | namespace Xrm.Tools.WebAPI.Metadata
11 | {
12 | public static class CRMWebAPIMetadataExtensions
13 | {
14 | public static async Task GetOptionSetByName(this CRMWebAPI api, string optionSetName)
15 | {
16 | CRMGetListOptions options = new CRMGetListOptions() { Select = new[] { "Name" } };
17 |
18 | var queryResult = await api.GetList("GlobalOptionSetDefinitions", options);
19 |
20 | foreach(dynamic optionSet in queryResult.List)
21 | {
22 |
23 | if ((optionSet != null) && (optionSet.Name == optionSetName))
24 | {
25 | var matchingOptionSet = await api.Get("GlobalOptionSetDefinitions", Guid.Parse( optionSet.MetadataId));
26 |
27 | return matchingOptionSet;
28 | }
29 | }
30 |
31 | return null;
32 |
33 | }
34 |
35 | public static async Task> GetOptionSetUserLabels(this CRMWebAPI api,string optionSetName)
36 | {
37 | var response = new List();
38 |
39 | dynamic optionSet = await api.GetOptionSetByName(optionSetName);
40 |
41 | foreach(dynamic option in optionSet.Options)
42 | {
43 | CRMOptionDisplayValue odv = new CRMOptionDisplayValue();
44 | odv.Value = option.Value;
45 | odv.Label = option.Label.UserLocalizedLabel.Label;
46 | response.Add(odv);
47 | }
48 |
49 | return response;
50 | }
51 |
52 | public static async Task> GetEntityDisplayNameList(this CRMWebAPI api, int LCID=0)
53 | {
54 | var result = new List();
55 |
56 | CRMGetListOptions options = new CRMGetListOptions()
57 | {
58 | Filter = "IsPrivate eq false",
59 |
60 | Select = new[] { "MetadataId","EntitySetName","DisplayName",
61 | "DisplayCollectionName","LogicalName","LogicalCollectionName","PrimaryIdAttribute" }
62 | };
63 |
64 | var queryResults = await api.GetList("EntityDefinitions", options);
65 |
66 | foreach(dynamic entity in queryResults.List)
67 | {
68 | CRMEntityDisplayName edm = new CRMEntityDisplayName();
69 | edm.MetadataId = Guid.Parse(entity.MetadataId);
70 | edm.EntitySetName = entity.EntitySetName;
71 | edm.LogicalName = entity.LogicalName;
72 | edm.LogicalCollectionName = entity.LogicalCollectionName;
73 | edm.PrimaryIdAttribute = entity.PrimaryIdAttribute;
74 | if ((entity.DisplayName.LocalizedLabels != null) && (entity.DisplayName.LocalizedLabels.Count > 0))
75 | {
76 | edm.DisplayName = entity.DisplayName.LocalizedLabels[0].Label;
77 | if (LCID != 0)
78 | foreach (dynamic label in entity.DisplayName.LocalizedLabels)
79 | { if (label.LanguageCode == LCID) edm.DisplayName = label.Label; }
80 |
81 | }
82 | else
83 | edm.DisplayName = edm.LogicalName;
84 | if ((entity.DisplayCollectionName.LocalizedLabels != null) && (entity.DisplayCollectionName.LocalizedLabels.Count > 0))
85 | {
86 | edm.DisplayCollectionName = entity.DisplayCollectionName.LocalizedLabels[0].Label;
87 | if (LCID != 0)
88 | foreach (dynamic label in entity.DisplayCollectionName.LocalizedLabels)
89 | { if (label.LanguageCode == LCID) edm.DisplayCollectionName = label.Label; }
90 | }
91 | else
92 | edm.DisplayCollectionName = entity.LogicalCollectionName;
93 | edm.LogicalDisplayName = edm.DisplayName + "(" + edm.LogicalName + ")";
94 | edm.LogicalDisplayCollectionName = edm.DisplayCollectionName + "(" + edm.LogicalCollectionName + ")";
95 |
96 | result.Add(edm);
97 |
98 | }
99 |
100 | return result;
101 |
102 | }
103 |
104 | public static async Task> GetAttributeDisplayNameList(this CRMWebAPI api, Guid entityID,int LCID = 0)
105 | {
106 | var result = new List();
107 |
108 | CRMGetListOptions options = new CRMGetListOptions()
109 | {
110 | Filter = "((IsValidForRead eq true) and (AttributeOf eq null))",
111 |
112 | Select = new[] { "MetadataId", "DisplayName", "LogicalName", "SchemaName", "AttributeType", "IsPrimaryId" }
113 | };
114 |
115 | var queryResults = await api.GetList("EntityDefinitions(" + entityID.ToString() + ")/Attributes", options);
116 |
117 | foreach (dynamic attrib in queryResults.List)
118 | {
119 | CRMAttributeDisplayName edm = new CRMAttributeDisplayName();
120 | edm.MetadataId = Guid.Parse(attrib.MetadataId);
121 | edm.LogicalName = attrib.LogicalName;
122 | edm.SchemaName = attrib.SchemaName;
123 | edm.IsPrimaryId = attrib.IsPrimaryId;
124 | edm.AttributeType = attrib.AttributeType;
125 | if (attrib.AttributeType == "Lookup" || attrib.AttributeType == "Customer" || attrib.AttributeType == "Owner")
126 | edm.ODataLogicalName = "_" + attrib.LogicalName + "_value";
127 | else
128 | edm.ODataLogicalName = attrib.LogicalName;
129 |
130 | if ((attrib.DisplayName.LocalizedLabels != null) && (attrib.DisplayName.LocalizedLabels.Count > 0))
131 | {
132 | edm.DisplayName = attrib.DisplayName.LocalizedLabels[0].Label;
133 | if (LCID != 0)
134 | foreach (dynamic label in attrib.DisplayName.LocalizedLabels)
135 | { if (label.LanguageCode == LCID) edm.DisplayName = label.Label; }
136 | }
137 | else
138 | edm.DisplayName = edm.LogicalName;
139 | edm.LogicalDisplayName = edm.DisplayName + "(" + edm.LogicalName + ")";
140 | result.Add(edm);
141 | }
142 |
143 |
144 |
145 | return result;
146 |
147 | }
148 |
149 | public static async Task CopyEntityAttribute(this CRMWebAPI api, Guid fromEntityID, Guid toEntityID, Guid fromAttributeID, string attributeType, string logicalName)
150 | {
151 | var ec = "EntityDefinitions(" + fromEntityID.ToString() + ")/Attributes(" + fromAttributeID + ")";
152 | if (attributeType == "Boolean")
153 | ec += "/Microsoft.Dynamics.CRM.BooleanAttributeMetadata?$expand=OptionSet";
154 | if (attributeType == "Picklist")
155 | ec += "/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$expand=OptionSet,GlobalOptionSet";
156 |
157 | dynamic fromAttrib = await api.Get(ec, Guid.Empty);
158 | IDictionary fromAttribValues = (IDictionary)fromAttrib;
159 | fromAttribValues.Remove("MetadataId");
160 | fromAttribValues.Remove("EntityLogicalName");
161 | if (attributeType == "Boolean")
162 | {
163 | fromAttribValues["@odata.type"] = "Microsoft.Dynamics.CRM.BooleanAttributeMetadata";
164 | fromAttribValues.Remove("OptionSet@odata.context");
165 | if (fromAttrib.OptionSet != null)
166 | {
167 | IDictionary fromOptionSetValues = (IDictionary)fromAttrib.OptionSet;
168 | fromOptionSetValues.Remove("Name");
169 | fromOptionSetValues.Remove("MetadataId");
170 | fromOptionSetValues.Remove("MetadataId");
171 | fromOptionSetValues["IsCustomOptionSet"] = true;
172 |
173 | }
174 | }
175 | if (attributeType == "Picklist")
176 | {
177 |
178 | fromAttribValues["@odata.type"] = "Microsoft.Dynamics.CRM.PicklistAttributeMetadata";
179 |
180 |
181 | if (fromAttrib.OptionSet != null)
182 | {
183 | IDictionary fromOptionSetValues = (IDictionary)fromAttrib.OptionSet;
184 | fromOptionSetValues.Remove("Name");
185 | fromOptionSetValues.Remove("MetadataId");
186 | fromOptionSetValues.Remove("MetadataId");
187 | fromOptionSetValues["IsCustomOptionSet"] = true;
188 |
189 | }
190 | else
191 | {
192 | fromAttribValues.Remove("OptionSet");
193 | fromAttribValues["GlobalOptionSet@odata.bind"] = "/GlobalOptionSetDefinitions(" + fromAttrib.GlobalOptionSet.MetadataId + ")";
194 | fromAttribValues.Remove("OptionSet@odata.context");
195 | fromAttribValues.Remove("GlobalOptionSet");
196 |
197 | }
198 | }
199 | fromAttrib.LogicalName = logicalName;
200 | fromAttrib.SchemaName = logicalName;
201 |
202 |
203 | return await api.Create("EntityDefinitions(" + toEntityID.ToString() + ")/Attributes", fromAttrib);
204 | }
205 |
206 | }
207 | }
208 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Xrm.Tools.WebAPI")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Xrm.Tools.WebAPI")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("8d1c4066-5def-4cc9-b84f-58944bbe86f0")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.12.0")]
36 | [assembly: AssemblyFileVersion("1.0.12.0")]
37 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Requests/CRMExpandOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Xrm.Tools.WebAPI.Requests
8 | {
9 | public class CRMExpandOptions
10 | {
11 | public string Property { get; set; }
12 |
13 | public string[] Select { get; set; }
14 |
15 | public string[] OrderBy { get; set; }
16 |
17 | public string Filter { get; set; }
18 | public int Top { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Requests/CRMGetListOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Xrm.Tools.WebAPI.Requests
8 | {
9 | public class CRMGetListOptions
10 | {
11 | public string[] Select { get; set; }
12 |
13 | public string[] OrderBy { get; set; }
14 |
15 | public string Filter { get; set; }
16 |
17 | public string Apply { get; set; }
18 | public int Skip { get; set; }
19 | public int Top { get; set; }
20 | public bool IncludeCount { get; set; }
21 | public bool FormattedValues { get; set; }
22 | public bool IncludeAnnotations { get; set; }
23 |
24 | public Guid SystemQuery { get; set; }
25 |
26 | public Guid UserQuery { get; set; }
27 | public string FetchXml { get; set; }
28 |
29 | public CRMExpandOptions[] Expand { get; set; }
30 |
31 | public bool TrackChanges { get; set; }
32 |
33 | public string TrackChangesLink { get; set; }
34 |
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Requests/CRMWebAPIConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Threading.Tasks;
4 |
5 | namespace Xrm.Tools.WebAPI.Requests
6 | {
7 | public class CRMWebAPIConfig
8 | {
9 | public string APIUrl { get; set; }
10 | public string AccessToken { get; set; }
11 | public bool ResolveUnicodeNames { get; set; }
12 | public Guid CallerID { get; set; }
13 | public Func> GetAccessToken { get; set; }
14 | public NetworkCredential NetworkCredential { get; set; }
15 | public CRMWebAPILoggingOptions Logging { get; set; }
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Requests/CRMWebAPILoggingOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Xrm.Tools.WebAPI.Requests
8 | {
9 | public class CRMWebAPILoggingOptions
10 | {
11 | public Action Logger { get; set; }
12 | public bool ODataUrl { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Results/CRMAttributeDisplayName.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Xrm.Tools.WebAPI.Results
8 | {
9 | public class CRMAttributeDisplayName
10 | {
11 | public Guid MetadataId { get; set; }
12 | public string LogicalName { get; set; }
13 | public string SchemaName { get; set; }
14 | public bool IsPrimaryId { get; set; }
15 | public string AttributeType { get; set; }
16 | public string ODataLogicalName { get; set; }
17 | public string DisplayName { get; set; }
18 | public string LogicalDisplayName { get; set; }
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Results/CRMBatchResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Xrm.Tools.WebAPI.Results
8 | {
9 | public class CRMBatchResult
10 | {
11 | public List ResultItems { get; set; }
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Results/CRMEntityDisplayName.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Xrm.Tools.WebAPI.Results
8 | {
9 | public class CRMEntityDisplayName
10 | {
11 | public Guid MetadataId { get; set; }
12 | public string EntitySetName { get; set; }
13 | public string LogicalName { get; set; }
14 | public string LogicalCollectionName { get; set; }
15 | public string PrimaryIdAttribute { get; set; }
16 | public string DisplayName { get; set; }
17 | public string DisplayCollectionName { get; set; }
18 | public string LogicalDisplayName { get; set; }
19 | public string LogicalDisplayCollectionName { get; set; }
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Results/CRMGetListResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Xrm.Tools.WebAPI.Results
9 | {
10 | public class CRMGetListResult
11 | {
12 | public List List { get; set; }
13 |
14 | public int Count { get; set; }
15 |
16 | public string TrackChangesLink { get; set; }
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Results/CRMMultipleOperationResultItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Xrm.Tools.WebAPI.Results
8 | {
9 | public class CRMBatchResultItem
10 | {
11 | public Guid EntityID{ get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Results/CRMOptionDisplayValue.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Xrm.Tools.WebAPI.Results
8 | {
9 | public class CRMOptionDisplayValue
10 | {
11 | public long Value { get; set; }
12 | public string Label { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Results/CRMUpdateResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Xrm.Tools.WebAPI.Results
8 | {
9 | public class CRMUpdateResult
10 | {
11 |
12 | public Guid EntityID { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Results/CRMWebAPIException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net.Http;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Xrm.Tools.WebAPI.Results
9 | {
10 | public class CRMWebAPIException : HttpRequestException
11 | {
12 | public CRMWebAPIException(string message) : base(message)
13 | {
14 |
15 | }
16 | public string JSON { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/Xrm.Tools.WebAPI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {8D1C4066-5DEF-4CC9-B84F-58944BBE86F0}
8 | Library
9 | Properties
10 | Xrm.Tools.WebAPI
11 | Xrm.Tools.WebAPI
12 | v4.6
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 | true
34 |
35 |
36 | xt.snk
37 |
38 |
39 |
40 | ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll
41 | True
42 |
43 |
44 |
45 |
46 |
47 |
48 | ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
49 | True
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
87 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/dotnet/Xrm.Tools.WebAPI/xt.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidyack/Xrm.Tools.CRMWebAPI/1d89792291b435cf659932bdc8e54662c7ddf4b7/dotnet/Xrm.Tools.WebAPI/xt.snk
--------------------------------------------------------------------------------
/nodejs/README.md:
--------------------------------------------------------------------------------
1 | Currently the nodejs library only supports oAuth authentication use Adal.js for Node to get an access token for real applications or https://xrm.tools/AccessToken for testing
2 |
3 | #Getting Started
4 |
5 | ````
6 | npm install CRMWebAPI
7 | ````
8 |
9 | # Usage example
10 | You can find other query example information [here](https://github.com/davidyack/Xrm.Tools.CRMWebAPI/wiki/Query-Examples )
11 |
12 | ```javascript
13 | var CRMWebAPI = require('CRMWebAPI');
14 |
15 | var apiconfig = { APIUrl: 'https://orgname.crm.dynamics.com/api/data/v8.0/', AccessToken: "" };
16 |
17 | var crmAPI = new CRMWebAPI(apiconfig);
18 |
19 | crmAPI
20 | .Create("accounts", { "name": "test2" })
21 | .then(
22 | function(r){
23 | console.log('Created: ' + r);
24 | return crmAPI.Update('accounts', r, { "name": "test2updated"});
25 | },
26 | function(e){
27 | console.log(e);
28 | })
29 | .then(
30 | function(r){
31 | console.log('Updated: ' + r.EntityID);
32 | return crmAPI.Delete('accounts', r.EntityID);
33 | },
34 | function(e){
35 | console.log(e);
36 | })
37 | .then(
38 | function(r){
39 | console.log('Deleted');
40 | }, function(e){
41 | console.log(e);
42 | })
43 | ```
44 |
--------------------------------------------------------------------------------
/nodejs/examples/callactionclientcreds/index.js:
--------------------------------------------------------------------------------
1 |
2 | var CRMWebAPI = require('CRMWebAPI');
3 | var adal = require('adal-node');
4 |
5 | function _authenticate(server,user,password)
6 | {
7 | return new Promise(function (resolve, reject) {
8 |
9 | var authorityHostUrl = 'https://login.windows.net/common';
10 | var clientId = 'your client id here';
11 |
12 | var context = new adal.AuthenticationContext(authorityHostUrl);
13 |
14 | context.acquireTokenWithUsernamePassword(server, user, password, clientId, function(err, tokenResponse) {
15 | if (err) { reject(err);} else {
16 | resolve(tokenResponse.accessToken);
17 | }
18 | });
19 | });
20 | }
21 |
22 | var server = 'https://orgname.crm.dynamics.com';
23 | _authenticate(server,'admin@.onmicrosoft.com','your password').then(function(accessToken) {
24 |
25 | var apiconfig = { APIUrl: server+'/api/data/v8.1/', AccessToken: accessToken };
26 |
27 | var crmAPI = new CRMWebAPI(apiconfig);
28 |
29 | var params = {
30 | "Country":'US' ,
31 | "Amount": 500
32 | };
33 |
34 | crmAPI.ExecuteAction("xt_CalculateDiscount", params).then(function(r){
35 | console.log(r);
36 | }, function(e){
37 | console.log(e);
38 | });
39 | });
40 |
41 |
--------------------------------------------------------------------------------
/nodejs/examples/callactionclientcreds/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "callaction",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "CRMWebAPI": "^1.0.0",
13 | "adal-node": "^0.1.21"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/nodejs/examples/callactionclientcreds/readme.md:
--------------------------------------------------------------------------------
1 | This is a simple example using Node JS and CRMWebAPI to call a CRM Custom Action.
2 |
3 | This example uses client credentials hard coded and clearly isn't a pattern to follow for production applications and is intended to simply demonstrate how to call an action from Node.
4 |
5 | # Steps to uses
6 |
7 | 1. run npm install to restore node_modules folder
8 |
9 | 2. Register an application with Azure AD and make sure it has CRM permissions configured
10 |
11 | 3. Edit index.js and update the orgName and client ID you just registered as well as appropriate user/passwords hard coded
12 |
13 | 4. In that CRM, create a custom action named xt_CalculateDiscount that takes Country and Amount as input parameters and returns a money field named Discount
14 |
15 | 5. Run the sample e.g. node index.js
--------------------------------------------------------------------------------
/nodejs/lib/CRMWebAPI.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for CRMWebAPI
2 | // Project: CRMWebAPI
3 | // Definitions by: Daryl LaBar
4 |
5 | /*~ This is the module template file for class modules.
6 | *~ You should rename it to index.d.ts and place it in a folder with the same name as the module.
7 | *~ For example, if you were writing a file for "super-greeter", this
8 | *~ file should be 'super-greeter/index.d.ts'
9 | */
10 |
11 | /*~ Note that ES6 modules cannot directly export class objects.
12 | *~ This file should be imported using the CommonJS-style:
13 | *~ import x = require('someLibrary');
14 | *~
15 | *~ Refer to the documentation to understand common
16 | *~ workarounds for this limitation of ES6 modules.
17 | */
18 |
19 | /*~ If this module is a UMD module that exposes a global variable 'CRMWebAPI' when
20 | *~ loaded outside a module loader environment, declare that global here.
21 | *~ Otherwise, delete this declaration.
22 | */
23 | export as namespace CRMWebAPI;
24 |
25 | /*~ This declaration specifies that the class constructor function
26 | *~ is the exported object from the file
27 | */
28 | export = CRMWebAPI;
29 |
30 | /*~ Write your module's methods and properties in this class */
31 | declare class CRMWebAPI {
32 | constructor(config: CRMWebAPI.Config);
33 |
34 | GetList(uri: string, queryOptions: CRMWebAPI.QueryOptions): Promise>;
35 | Get(entityCollection: string, entityId: string, queryOptions: CRMWebAPI.QueryOptions): Promise;
36 | GetCount(uri: string, queryOptions: CRMWebAPI.QueryOptions): Promise;
37 | Create(entityCollection: string, data: any): Promise;
38 | Update(entityCollection: string, key: string, data: any, upsert?: boolean): Promise;
39 | Delete(entityCollection: string, entityID: string): Promise;
40 | Associate(fromEntitycollection: string, fromEntityId: string, navProperty: string, toEntityCollection: string, toEntityId: string): Promise;
41 | DeleteAssociation(fromEntitycollection: string, fromEntityId: string, navProperty: string, toEntityCollection?: string, toEntityId?: string): Promise;
42 | ExecuteFunction(functionName: string, parameters: TRequest): Promise;
43 | ExecuteFunction(functionName: string, parameters: TRequest, entityCollection: string, entityId: string): Promise;
44 | ExecuteAction(actionName: string, data: TRequest): Promise;
45 | ExecuteAction(actionName: string, data: TRequest, entityCollection: string, entityId: string): Promise;
46 | }
47 |
48 | /*~ If you want to expose types from your module as well, you can
49 | *~ place them in this block.
50 | */
51 | declare namespace CRMWebAPI {
52 | export interface Config{
53 | APIUrl: string;
54 | AccessToken?: string;
55 | callerId?: string;
56 | }
57 |
58 | export interface GetListResponse {
59 | List: T[];
60 | }
61 |
62 | export interface UpdateResponse {
63 | EntityID: string;
64 | }
65 |
66 | export interface QueryOptionBase{
67 | IncludeAnnotations?:boolean;
68 | FormattedValues?:boolean;
69 | Select?: string[];
70 | Filter?: string;
71 | OrderBy?: string[];
72 | Top?: number;
73 | }
74 |
75 | export interface ExpandQueryOptions extends QueryOptionBase {
76 | Property: string;
77 | }
78 |
79 | export interface QueryOptions extends QueryOptionBase{
80 | Expand?: ExpandQueryOptions[];
81 | FetchXml?: string;
82 | IncludeCount?: boolean;
83 | Skip?: number;
84 | SystemQuery?: string;
85 | UserQuery?: string;
86 |
87 | RecordAction?(record:any);
88 | PageAction?(list:any[]);
89 | }
90 | }
--------------------------------------------------------------------------------
/nodejs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "Xrm.Tools",
3 | "name": "CRMWebAPI",
4 | "description": "CRMWebAPI Node.js Wrapper",
5 | "version": "1.3.6",
6 | "repository": {
7 | "url": "http://github.com/DavidYack/Xrm.Tools.CRMWebAPI"
8 | },
9 | "main": "./lib/CRMWebAPI",
10 | "types": "./lib/CRMWebAPI.d.ts",
11 | "dependencies": {},
12 | "devDependencies": {},
13 | "optionalDependencies": {},
14 | "engines": {
15 | "node": ">=0.12"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/php/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | crmwebapi-php-demo.iml
3 | test.php
4 | vendor
5 |
--------------------------------------------------------------------------------
/php/README.md:
--------------------------------------------------------------------------------
1 | # Usage example
2 |
3 | ```php
4 | use CRMWebAPI\CRMWebAPI;
5 |
6 | $api = new CRMWebAPI([
7 | 'APIUrl' => 'https://test.crm.dynamics.com/api/data/v8.0/',
8 | 'AccessToken' => ''
9 | ]);
10 |
11 | $id = $api->Create('accounts', ['name' => 'test-php']);
12 | $uid = $api->Update('accounts', $id, ['name' => 'test-php-updated']);
13 | $api->Delete('accounts', $uid->EntityId);
14 | $whoami = $api->ExecuteFunction("WhoAmI");
15 | ```
16 |
17 | As for acquring the token, I would look at https://github.com/jamesmcq/oidc-aad-php-library or one of the Office 365 samples here https://github.com/jasonjoh/php-calendar - for CRM you would need to specify the org URL as the resource
18 |
--------------------------------------------------------------------------------
/php/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "davidyack/Xrm.Tools.CRMWebAPI",
3 | "description": "CRM Web API for PHP",
4 | "license": "MIT",
5 | "keywords": [
6 | "crmwebapi",
7 | "api"
8 | ],
9 | "authors": [
10 | {
11 | "name": "Xrm.Tools",
12 | "email": "info@coloradotc.com"
13 | }
14 | ],
15 | "require": {
16 | "guzzlehttp/guzzle": "~6"
17 | },
18 | "require-dev": {},
19 | "autoload": {
20 | "psr-4": {
21 | "CRMWebAPI\\": "lib"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/php/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "hash": "f10578f6d7d728aa34277c81961d3fc3",
8 | "content-hash": "949eca3f573e3f372ac10e9e79ed3c90",
9 | "packages": [
10 | {
11 | "name": "guzzlehttp/guzzle",
12 | "version": "6.1.1",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/guzzle/guzzle.git",
16 | "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c6851d6e48f63b69357cbfa55bca116448140e0c",
21 | "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "guzzlehttp/promises": "~1.0",
26 | "guzzlehttp/psr7": "~1.1",
27 | "php": ">=5.5.0"
28 | },
29 | "require-dev": {
30 | "ext-curl": "*",
31 | "phpunit/phpunit": "~4.0",
32 | "psr/log": "~1.0"
33 | },
34 | "type": "library",
35 | "extra": {
36 | "branch-alias": {
37 | "dev-master": "6.1-dev"
38 | }
39 | },
40 | "autoload": {
41 | "files": [
42 | "src/functions_include.php"
43 | ],
44 | "psr-4": {
45 | "GuzzleHttp\\": "src/"
46 | }
47 | },
48 | "notification-url": "https://packagist.org/downloads/",
49 | "license": [
50 | "MIT"
51 | ],
52 | "authors": [
53 | {
54 | "name": "Michael Dowling",
55 | "email": "mtdowling@gmail.com",
56 | "homepage": "https://github.com/mtdowling"
57 | }
58 | ],
59 | "description": "Guzzle is a PHP HTTP client library",
60 | "homepage": "http://guzzlephp.org/",
61 | "keywords": [
62 | "client",
63 | "curl",
64 | "framework",
65 | "http",
66 | "http client",
67 | "rest",
68 | "web service"
69 | ],
70 | "time": "2015-11-23 00:47:50"
71 | },
72 | {
73 | "name": "guzzlehttp/promises",
74 | "version": "1.0.3",
75 | "source": {
76 | "type": "git",
77 | "url": "https://github.com/guzzle/promises.git",
78 | "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea"
79 | },
80 | "dist": {
81 | "type": "zip",
82 | "url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea",
83 | "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea",
84 | "shasum": ""
85 | },
86 | "require": {
87 | "php": ">=5.5.0"
88 | },
89 | "require-dev": {
90 | "phpunit/phpunit": "~4.0"
91 | },
92 | "type": "library",
93 | "extra": {
94 | "branch-alias": {
95 | "dev-master": "1.0-dev"
96 | }
97 | },
98 | "autoload": {
99 | "psr-4": {
100 | "GuzzleHttp\\Promise\\": "src/"
101 | },
102 | "files": [
103 | "src/functions_include.php"
104 | ]
105 | },
106 | "notification-url": "https://packagist.org/downloads/",
107 | "license": [
108 | "MIT"
109 | ],
110 | "authors": [
111 | {
112 | "name": "Michael Dowling",
113 | "email": "mtdowling@gmail.com",
114 | "homepage": "https://github.com/mtdowling"
115 | }
116 | ],
117 | "description": "Guzzle promises library",
118 | "keywords": [
119 | "promise"
120 | ],
121 | "time": "2015-10-15 22:28:00"
122 | },
123 | {
124 | "name": "guzzlehttp/psr7",
125 | "version": "1.2.1",
126 | "source": {
127 | "type": "git",
128 | "url": "https://github.com/guzzle/psr7.git",
129 | "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982"
130 | },
131 | "dist": {
132 | "type": "zip",
133 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/4d0bdbe1206df7440219ce14c972aa57cc5e4982",
134 | "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982",
135 | "shasum": ""
136 | },
137 | "require": {
138 | "php": ">=5.4.0",
139 | "psr/http-message": "~1.0"
140 | },
141 | "provide": {
142 | "psr/http-message-implementation": "1.0"
143 | },
144 | "require-dev": {
145 | "phpunit/phpunit": "~4.0"
146 | },
147 | "type": "library",
148 | "extra": {
149 | "branch-alias": {
150 | "dev-master": "1.0-dev"
151 | }
152 | },
153 | "autoload": {
154 | "psr-4": {
155 | "GuzzleHttp\\Psr7\\": "src/"
156 | },
157 | "files": [
158 | "src/functions_include.php"
159 | ]
160 | },
161 | "notification-url": "https://packagist.org/downloads/",
162 | "license": [
163 | "MIT"
164 | ],
165 | "authors": [
166 | {
167 | "name": "Michael Dowling",
168 | "email": "mtdowling@gmail.com",
169 | "homepage": "https://github.com/mtdowling"
170 | }
171 | ],
172 | "description": "PSR-7 message implementation",
173 | "keywords": [
174 | "http",
175 | "message",
176 | "stream",
177 | "uri"
178 | ],
179 | "time": "2015-11-03 01:34:55"
180 | },
181 | {
182 | "name": "psr/http-message",
183 | "version": "1.0",
184 | "source": {
185 | "type": "git",
186 | "url": "https://github.com/php-fig/http-message.git",
187 | "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298"
188 | },
189 | "dist": {
190 | "type": "zip",
191 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
192 | "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
193 | "shasum": ""
194 | },
195 | "require": {
196 | "php": ">=5.3.0"
197 | },
198 | "type": "library",
199 | "extra": {
200 | "branch-alias": {
201 | "dev-master": "1.0.x-dev"
202 | }
203 | },
204 | "autoload": {
205 | "psr-4": {
206 | "Psr\\Http\\Message\\": "src/"
207 | }
208 | },
209 | "notification-url": "https://packagist.org/downloads/",
210 | "license": [
211 | "MIT"
212 | ],
213 | "authors": [
214 | {
215 | "name": "PHP-FIG",
216 | "homepage": "http://www.php-fig.org/"
217 | }
218 | ],
219 | "description": "Common interface for HTTP messages",
220 | "keywords": [
221 | "http",
222 | "http-message",
223 | "psr",
224 | "psr-7",
225 | "request",
226 | "response"
227 | ],
228 | "time": "2015-05-04 20:22:00"
229 | }
230 | ],
231 | "packages-dev": [],
232 | "aliases": [],
233 | "minimum-stability": "stable",
234 | "stability-flags": [],
235 | "prefer-stable": false,
236 | "prefer-lowest": false,
237 | "platform": [],
238 | "platform-dev": []
239 | }
240 |
--------------------------------------------------------------------------------
/python/.gitignore:
--------------------------------------------------------------------------------
1 | *.py[co]
2 | crm-python.iml
3 |
4 | #small test code that contains my keys
5 | t.py
6 |
7 | # Packages
8 | *.egg
9 | *.egg-info
10 | dist
11 | build
12 | eggs
13 | parts
14 | bin
15 | include
16 | lib
17 | local
18 | var
19 | sdist
20 | develop-eggs
21 | .installed.cfg
22 |
23 | # Installer logs
24 | pip-log.txt
25 |
26 | # Unit test / coverage reports
27 | .coverage
28 | .tox
29 |
30 | # PyCharm data
31 | .idea
32 |
33 | #Translations
34 | *.mo
35 |
36 | #Mr Developer
37 | .mr.developer.cfg
38 |
39 | #Environment
40 | env
41 |
42 |
--------------------------------------------------------------------------------
/python/Makefile:
--------------------------------------------------------------------------------
1 | help:
2 | @echo " env create a development environment using virtualenv"
3 | @echo " deps install dependencies"
4 | @echo " clean remove unwanted stuff"
5 | @echo " test run tests"
6 |
7 | env:
8 | sudo easy_install pip && \
9 | pip install virtualenv && \
10 | virtualenv env && \
11 | . env/bin/activate && \
12 | make deps
13 |
14 | deps:
15 | pip install -r requirements.txt --use-mirrors
16 |
17 | clean:
18 | rm -fr build
19 | rm -fr dist
20 | find . -name '*.pyc' -exec rm -f {} \;
21 | find . -name '*.pyo' -exec rm -f {} \;
22 | find . -name '*~' -exec rm -f {} \;
23 |
24 | test:
25 | nosetests
26 |
27 | build: clean
28 | python setup.py sdist
29 | python setup.py bdist_wheel
30 |
31 | upload: clean
32 | python setup.py sdist upload
33 | python setup.py bdist_wheel upload
34 |
35 |
--------------------------------------------------------------------------------
/python/README.md:
--------------------------------------------------------------------------------
1 | CRMWebAPI Python
2 | ================
3 |
4 | ## Installation
5 |
6 | ### From PyPI
7 |
8 | `pip install crmwebapi` (future)
9 |
10 | ### From sources
11 |
12 | `python setup.py install`
13 |
14 | ## Usage example
15 |
16 | from crmwebapi import CRMWebAPI
17 |
18 | api = CRMWebAPI({
19 | 'AccessToken': 'token',
20 | 'APIUrl': 'https://test.crm.dynamics.com/api/data/v8.0/'})
21 | id = api.create('accounts', {'name': 'testpy2'})
22 | ent = api.get('accounts', id)
23 | upid = api.update('accounts', id, {'name': 'testpy2up'})
24 |
25 | if id != upid['EntityId']:
26 | print('Something went wrong')
27 |
28 | api.delete('accounts', upid['EntityId'])
29 | print(api.execute_function('WhoAmI'))
30 |
--------------------------------------------------------------------------------
/python/README.rst:
--------------------------------------------------------------------------------
1 | CRMWebAPI Python
2 | ================
3 |
4 | Usage example
5 |
6 | from crmwebapi import CRMWebAPI
7 |
8 | api = CRMWebAPI({
9 | 'AccessToken': 'token',
10 | 'APIUrl': 'https://test.crm.dynamics.com/api/data/v8.0/'})
11 | id = api.create('accounts', {'name': 'testpy2'})
12 | ent = api.get('accounts', id)
13 | upid = api.update('accounts', id, {'name': 'testpy2up'})
14 |
15 | if id != upid['EntityId']:
16 | print('Something went wrong')
17 |
18 | api.delete('accounts', upid['EntityId'])
19 | print(api.execute_function('WhoAmI'))
20 |
--------------------------------------------------------------------------------
/python/crmwebapi/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | """A library that provides a Python interface to the CRM Web API"""
4 | from __future__ import absolute_import
5 |
6 | __author__ = ''
7 | __version__ = '1.0'
8 |
9 | import json # noqa
10 | from .crmwebapi import CRMWebAPI # noqa
--------------------------------------------------------------------------------
/python/setup.cfg:
--------------------------------------------------------------------------------
1 | [check-manifest]
2 | ignore =
3 | violations.flake8.txt
4 |
5 | [flake8]
6 | ignore = E111,E124,E126,E201,E202,E221,E241,E302,E501
7 |
--------------------------------------------------------------------------------
/python/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | '''The setup and build script for the python-crmwebapi library.'''
4 |
5 | import os
6 |
7 | from setuptools import setup, find_packages
8 |
9 | def read(*paths):
10 | """Build a file path from *paths* and return the contents."""
11 | with open(os.path.join(*paths), 'r') as f:
12 | return f.read()
13 |
14 | setup(
15 | name='xrm-tools-crmwebapi',
16 | version='1.0',
17 | author='Xrm.Tools',
18 | author_email='',
19 | license='MIT',
20 | url='https://github.com/davidyack/Xrm.Tools.CRMWebAPI',
21 | keywords='crmwebapi',
22 | description='A Python version of CRMWebAPI',
23 | long_description=(read('README.rst')),
24 | packages=find_packages(exclude=['tests*']),
25 | install_requires=['future', 'requests'],
26 | classifiers=[
27 | 'Development Status :: 5 - Production/Stable',
28 | 'Intended Audience :: Developers',
29 | 'License :: OSI Approved :: Apache Software License',
30 | 'Operating System :: OS Independent',
31 | 'Topic :: Software Development :: Libraries :: Python Modules',
32 | 'Topic :: Internet',
33 | 'Programming Language :: Python',
34 | 'Programming Language :: Python :: 2',
35 | 'Programming Language :: Python :: 2.7',
36 | 'Programming Language :: Python :: 3',
37 | 'Programming Language :: Python :: 3.5',
38 | ],
39 | )
40 |
41 |
--------------------------------------------------------------------------------