11using McTools . Xrm . Connection ;
22using Microsoft . Xrm . Sdk ;
3- using Microsoft . Xrm . Sdk . Query ;
4- using Newtonsoft . Json . Linq ;
53using System ;
6- using System . Collections . Generic ;
7- using System . IO ;
84using System . Linq ;
9- using System . Reflection ;
10- using System . Windows . Forms ;
11- using System . Xml ;
125using XrmToolBox . Extensibility ;
13- using XrmToolBox . Extensibility . Interfaces ;
146
157namespace Rappen . XTB . CAT
168{
17- public partial class CustomActionTester : PluginControlBase , IGitHubPlugin , IAboutPlugin
9+ public partial class CustomActionTester : PluginControlBase
1810 {
19- private const string aiEndpoint = "https://dc.services.visualstudio.com/v2/track" ;
20- private const string aiKey = "eed73022-2444-45fd-928b-5eebd8fa46a6" ; // [email protected] tenant, XrmToolBox 21- private AppInsights ai = new AppInsights ( aiEndpoint , aiKey , Assembly . GetExecutingAssembly ( ) , "Custom Action Tester" ) ;
22-
23- public string RepositoryName => "CustomActionTester" ;
24-
25- public string UserName => "rappen" ;
26-
27- public void ShowAboutDialog ( )
28- {
29- var about = new About ( this )
30- {
31- StartPosition = FormStartPosition . CenterParent
32- } ;
33- about . lblVersion . Text = Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version . ToString ( ) ;
34- about . ShowDialog ( ) ;
35- }
11+ #region Public Constructors
3612
3713 public CustomActionTester ( )
3814 {
3915 InitializeComponent ( ) ;
4016 }
4117
42- internal void LogUse ( string action , double ? count = null , double ? duration = null )
43- {
44- ai . WriteEvent ( action , count , duration , HandleAIResult ) ;
45- }
46-
47- private void HandleAIResult ( string result )
48- {
49- if ( ! string . IsNullOrEmpty ( result ) )
50- {
51- LogError ( "Failed to write to Application Insights:\n {0}" , result ) ;
52- }
53- }
18+ #endregion Public Constructors
5419
55- private void CustomActionTester_Load ( object sender , EventArgs e )
56- {
57- LogUse ( "Load" ) ;
58- }
59-
60- private void GetCustomActions ( )
61- {
62- var qx = new QueryExpression ( "workflow" ) ;
63- qx . ColumnSet . AddColumns ( "name" , "uniquename" , "createdby" , "primaryentity" , "scope" , "mode" , "ismanaged" , "iscustomizable" , "istransacted" , "iscustomprocessingstepallowedforotherpublishers" , "inputparameters" , "description" ) ;
64- qx . AddOrder ( "ismanaged" , OrderType . Descending ) ;
65- qx . AddOrder ( "name" , OrderType . Ascending ) ;
66- qx . Criteria . AddCondition ( "category" , ConditionOperator . Equal , 3 ) ;
67- qx . Criteria . AddCondition ( "type" , ConditionOperator . Equal , 1 ) ;
68- qx . Criteria . AddCondition ( "componentstate" , ConditionOperator . Equal , 0 ) ;
69- qx . Criteria . AddCondition ( "statuscode" , ConditionOperator . Equal , 2 ) ;
70- var qxsdk = qx . AddLink ( "sdkmessage" , "sdkmessageid" , "sdkmessageid" , JoinOperator . LeftOuter ) ;
71- qxsdk . EntityAlias = "M" ;
72- qxsdk . Columns . AddColumns ( "name" , "workflowsdkstepenabled" ) ;
73- WorkAsync ( new WorkAsyncInfo
74- {
75- Message = "Getting Custom Actions" ,
76- Work = ( worker , args ) =>
77- {
78- args . Result = Service . RetrieveMultiple ( qx ) ;
79- } ,
80- PostWorkCallBack = ( args ) =>
81- {
82- if ( args . Error != null )
83- {
84- MessageBox . Show ( args . Error . ToString ( ) , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
85- }
86- else if ( args . Result is EntityCollection actions )
87- {
88- cmbCustomActions . DataSource = actions ;
89- }
90- }
91- } ) ;
92- }
20+ #region Public Methods
9321
9422 public override void UpdateConnection ( IOrganizationService newService , ConnectionDetail detail , string actionName , object parameter )
9523 {
@@ -107,104 +35,13 @@ public override void UpdateConnection(IOrganizationService newService, Connectio
10735 }
10836 }
10937
110- private void cmbCustomActions_SelectedIndexChanged ( object sender , EventArgs e )
111- {
112- txtUniqueName . Entity = cmbCustomActions . SelectedEntity ;
113- txtMessageName . Entity = cmbCustomActions . SelectedEntity ;
114- txtCreatedBy . Entity = cmbCustomActions . SelectedEntity ;
115- GetInputParams ( ) ;
116- }
38+ #endregion Public Methods
11739
118- private void GetInputParams ( )
119- {
120- var qx = new QueryExpression ( "sdkmessagerequestfield" ) ;
121- qx . Distinct = true ;
122- qx . ColumnSet . AddColumns ( "name" , "position" , "optional" , "parser" , "fieldmask" ) ;
123- qx . AddOrder ( "position" , OrderType . Ascending ) ;
124- var req = qx . AddLink ( "sdkmessagerequest" , "sdkmessagerequestid" , "sdkmessagerequestid" ) ;
125- var pair = req . AddLink ( "sdkmessagepair" , "sdkmessagepairid" , "sdkmessagepairid" ) ;
126- var msg = pair . AddLink ( "sdkmessage" , "sdkmessageid" , "sdkmessageid" ) ;
127- var wf = msg . AddLink ( "workflow" , "sdkmessageid" , "sdkmessageid" ) ;
128- wf . LinkCriteria . AddCondition ( "workflowid" , ConditionOperator . Equal , cmbCustomActions . SelectedEntity . Id ) ;
129- WorkAsync ( new WorkAsyncInfo
130- {
131- Message = "Loading Input Parameters" ,
132- Work = ( worker , args ) =>
133- {
134- args . Result = Service . RetrieveMultiple ( qx ) ;
135- } ,
136- PostWorkCallBack = ( args ) =>
137- {
138- if ( args . Error != null )
139- {
140- MessageBox . Show ( args . Error . ToString ( ) , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
141- }
142- else if ( args . Result is EntityCollection inputs )
143- {
144- ExtractTypeInfo ( inputs , "parser" ) ;
145- gridInputParams . DataSource = inputs ;
146- gridInputParams . AutoResizeColumns ( ) ;
147- GetOutputParams ( ) ;
148- }
149- }
150- } ) ;
151- }
152-
153- private void GetOutputParams ( )
154- {
155- var qx = new QueryExpression ( "sdkmessageresponsefield" ) ;
156- qx . Distinct = true ;
157- qx . ColumnSet . AddColumns ( "name" , "position" , "parameterbindinginformation" , "formatter" , "publicname" ) ;
158- qx . AddOrder ( "position" , OrderType . Ascending ) ;
159- var resp = qx . AddLink ( "sdkmessageresponse" , "sdkmessageresponseid" , "sdkmessageresponseid" ) ;
160- var req = resp . AddLink ( "sdkmessagerequest" , "sdkmessagerequestid" , "sdkmessagerequestid" ) ;
161- var pair = req . AddLink ( "sdkmessagepair" , "sdkmessagepairid" , "sdkmessagepairid" ) ;
162- var msg = pair . AddLink ( "sdkmessage" , "sdkmessageid" , "sdkmessageid" ) ;
163- var wf = msg . AddLink ( "workflow" , "sdkmessageid" , "sdkmessageid" ) ;
164- wf . LinkCriteria . AddCondition ( "workflowid" , ConditionOperator . Equal , cmbCustomActions . SelectedEntity . Id ) ;
165- WorkAsync ( new WorkAsyncInfo
166- {
167- Message = "Loading Output Parameters" ,
168- Work = ( worker , args ) =>
169- {
170- args . Result = Service . RetrieveMultiple ( qx ) ;
171- } ,
172- PostWorkCallBack = ( args ) =>
173- {
174- if ( args . Error != null )
175- {
176- MessageBox . Show ( args . Error . ToString ( ) , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
177- }
178- else if ( args . Result is EntityCollection outputs )
179- {
180- ExtractTypeInfo ( outputs , "formatter" ) ;
181- gridOutputParams . DataSource = outputs ;
182- gridOutputParams . AutoResizeColumns ( ) ;
183- }
184- }
185- } ) ;
186- }
40+ #region Private Methods
18741
188- private void ExtractTypeInfo ( EntityCollection records , string attribute )
189- {
190- foreach ( var record in records . Entities )
191- {
192- if ( record . TryGetAttributeValue ( attribute , out string parser ) )
193- {
194- parser = parser . Split ( ',' ) [ 0 ] ;
195- while ( parser . Contains ( "." ) )
196- {
197- parser = parser . Substring ( parser . IndexOf ( '.' ) + 1 ) ;
198- }
199- record [ "type" ] = parser ;
200- }
201- }
202- }
203-
204- private void gridInputParams_RecordEnter ( object sender , xrmtb . XrmToolBox . Controls . CRMRecordEventArgs e )
42+ private void btnExecute_Click ( object sender , EventArgs e )
20543 {
206- e . Entity . TryGetAttributeValue ( "value" , out string value ) ;
207- txtInputParamValue . Text = value ;
44+ ExecuteCA ( ) ;
20845 }
20946
21047 private void btnSaveInputParamValue_Click ( object sender , EventArgs e )
@@ -217,116 +54,40 @@ private void btnSaveInputParamValue_Click(object sender, EventArgs e)
21754 }
21855 }
21956
220- private void btnExecute_Click ( object sender , EventArgs e )
57+ private void cmbCustomActions_SelectedIndexChanged ( object sender , EventArgs e )
22158 {
222- ExecuteCA ( ) ;
59+ txtUniqueName . Entity = cmbCustomActions . SelectedEntity ;
60+ txtMessageName . Entity = cmbCustomActions . SelectedEntity ;
61+ txtCreatedBy . Entity = cmbCustomActions . SelectedEntity ;
62+ GetInputParams ( ) ;
22363 }
22464
225- private void ExecuteCA ( )
65+ private void CustomActionTester_Load ( object sender , EventArgs e )
22666 {
227- var request = new OrganizationRequest ( txtMessageName . Text ) ;
228- foreach ( var input in gridInputParams . DataSource as IEnumerable < Entity > )
229- {
230- if ( input . TryGetAttributeValue ( "name" , out string name ) &&
231- input . TryGetAttributeValue ( "value" , out string value ) )
232- {
233- request [ name ] = value ;
234- }
235- }
236- WorkAsync ( new WorkAsyncInfo
237- {
238- Message = "Executing Custom Action" ,
239- Work = ( worker , args ) =>
240- {
241- args . Result = Service . Execute ( request ) ;
242- } ,
243- PostWorkCallBack = ( args ) =>
244- {
245- if ( args . Error != null )
246- {
247- MessageBox . Show ( args . Error . ToString ( ) , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
248- }
249- else if ( args . Result is OrganizationResponse response )
250- {
251- foreach ( var result in response . Results )
252- {
253- var outputs = gridOutputParams . DataSource as IEnumerable < Entity > ;
254- var output = outputs . FirstOrDefault ( o => o [ "name" ] . ToString ( ) . Equals ( result . Key ) ) ;
255- if ( output != null )
256- {
257- output [ "value" ] = result . Value ;
258- }
259- }
260- gridOutputParams . Refresh ( ) ;
261- gridOutputParams . AutoResizeColumns ( ) ;
262- FormatResultDetailDefault ( ) ;
263- }
264- }
265- } ) ;
67+ LogUse ( "Load" ) ;
26668 }
26769
268- private void FormatResultDetailDefault ( )
70+ private void gridInputParams_RecordEnter ( object sender , xrmtb . XrmToolBox . Controls . CRMRecordEventArgs e )
26971 {
270- var value = GetResultDetailValue ( ) ;
271- if ( string . IsNullOrEmpty ( value ) )
272- {
273- return ;
274- }
275- if ( value . StartsWith ( "{" ) )
276- {
277- rbFormatJSON . Checked = true ;
278- }
279- else if ( value . StartsWith ( "<" ) )
280- {
281- rbFormatXML . Checked = true ;
282- }
72+ e . Entity . TryGetAttributeValue ( "value" , out string value ) ;
73+ txtInputParamValue . Text = value ;
28374 }
28475
28576 private void gridOutputParams_RecordClick ( object sender , xrmtb . XrmToolBox . Controls . CRMRecordEventArgs e )
28677 {
287- FormatResultDetail ( ) ;
288- }
289-
290- private void FormatResultDetail ( )
291- {
292- var value = GetResultDetailValue ( ) ;
293- if ( ! string . IsNullOrEmpty ( value ) )
294- {
295- if ( rbFormatJSON . Checked )
296- {
297- var parsedJson = JToken . Parse ( value ) ;
298- value = parsedJson . ToString ( Newtonsoft . Json . Formatting . Indented ) ;
299- }
300- else if ( rbFormatXML . Checked )
301- {
302- var string_writer = new StringWriter ( ) ;
303- var xml_text_writer = new XmlTextWriter ( string_writer ) ;
304- xml_text_writer . Formatting = System . Xml . Formatting . Indented ;
305- value = string_writer . ToString ( ) ;
306- }
307- }
308- txtResultDetail . Text = value ;
309- }
310-
311- private string GetResultDetailValue ( )
312- {
313- var record = gridOutputParams . SelectedCellRecords . FirstOrDefault ( ) ;
314- if ( record ? . Contains ( "value" ) != true )
315- {
316- txtResultDetail . Text = string . Empty ;
317- return null ;
318- }
319- return record [ "value" ] . ToString ( ) ;
78+ txtResultDetail . Text = FormatResultDetail ( ) ;
32079 }
32180
32281 private void rbFormatResult_CheckedChanged ( object sender , EventArgs e )
32382 {
324- FormatResultDetail ( ) ;
83+ txtResultDetail . Text = FormatResultDetail ( ) ;
32584 }
32685
32786 private void tslAbout_Click ( object sender , EventArgs e )
32887 {
32988 ShowAboutDialog ( ) ;
33089 }
90+
91+ #endregion Private Methods
33192 }
33293}
0 commit comments