public static void Run(CDSWebApiService svc)
        {
            Console.WriteLine("\t--Starting Conditional Operations--");

            /// <summary> Creates the CRM entity instance used by this sample. </summary>
            #region Create sample Account record
            // Create a CRM account record.
            Console.WriteLine("\nCreate sample data");
            var account = new JObject
            {
                { "name", "Contoso Ltd" },
                { "telephone1", "555-0000" }, //Phone number value will increment with each update attempt
                { "revenue", 5000000 },
                { "description", "Parent company of Contoso Pharmaceuticals, etc." }
            };

            var accountUri = svc.PostCreate("accounts", account);
            Console.WriteLine("Account entity created:");

            //Retrieve the account record you created to access the ETag value
            account = svc.Get($"{accountUri}?$select=name,revenue,telephone1,description") as JObject;
            var initialAcctETagVal = account["@odata.etag"].ToString();
            var updatedAcctETagVal = string.Empty;
            Console.WriteLine($"ETag value: {initialAcctETagVal}");
            #endregion Create sample Account record

            #region Conditional GET
            Console.WriteLine("\n--Conditional GET section started--");
            var IfNoneMatchHeader = new Dictionary <string, List <string> >
            {
                { "If-None-Match", new List <string> {
                      initialAcctETagVal
                  } }
            };
            // Retrieve only if it doesn't match previously retrieved version.
            var result = svc.Get($"{accountUri}?$select=name,revenue,telephone1,description", IfNoneMatchHeader);
            if (result == null)
            {
                Console.WriteLine("Expected outcome: Entity was not modified so nothing was returned.");
            }
            else
            {
                Console.WriteLine("Unexpected outcome: Entity was not modified so nothing should be returned.");
            }

            // Modify the account instance by updating telephone1
            svc.Put(accountUri, "telephone1", "555-0001");
            Console.WriteLine("\nAccount telephone number updated.");

            // Re-Attempt conditional GET with original initialAcctETagVal ETag value
            result = svc.Get($"{accountUri}?$select=name", IfNoneMatchHeader);
            if (result == null)
            {
                Console.WriteLine("Unexpected outcome: Entity was modified so something should be returned.");
            }
            else
            {
                Console.WriteLine("Expected outcome: Entity was modified so something was returned.");
            }

            #endregion Conditional GET

            #region Optimistic concurrency on delete and update
            Console.WriteLine("\n--Optimistic concurrency section started--");
            // Attempt to delete original account (if matches original initialAcctETagVal ETag value).

            var IfMatchHeader = new Dictionary <string, List <string> >
            {
                { "If-Match", new List <string> {
                      initialAcctETagVal
                  } }
            };
            try
            {
                svc.Delete(accountUri, IfMatchHeader);
            }
            catch (CDSWebApiException ex)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine($"Expected Error: {ex.Message}\n" +
                                  $"\tAccount not deleted using the initial ETag value: {initialAcctETagVal}\n" +
                                  $"\tStatusCode: {ex.StatusCode}\n" +
                                  $"\tReasonPhrase: {ex.ReasonPhrase}");
                Console.ResetColor();
            }

            //Attempt to update account (if matches original ETag value).


            JObject accountUpdate = new JObject
            {
                { "telephone1", "555-0002" },
                { "revenue", 6000000 }
            };
            try
            {
                svc.Patch(accountUri, accountUpdate, IfMatchHeader);
            }
            catch (CDSWebApiException ex)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine($"Expected Error: {ex.Message}\n" +
                                  $"\tAccount not updated using the initial ETag value: {initialAcctETagVal}\n" +
                                  $"\tStatusCode: {ex.StatusCode}\n" +
                                  $"\tReasonPhrase: {ex.ReasonPhrase}");
                Console.ResetColor();
            }

            //Get current ETag value:
            updatedAcctETagVal = svc.Get($"{accountUri}?$select=accountid")["@odata.etag"].ToString();

            // Reattempt update if matches current ETag value.
            var NewIfMatchHeader = new Dictionary <string, List <string> >
            {
                { "If-Match", new List <string> {
                      updatedAcctETagVal
                  } }
            };

            svc.Patch(accountUri, accountUpdate, NewIfMatchHeader);
            Console.WriteLine($"\nAccount successfully updated using ETag: {updatedAcctETagVal}");

            // Retrieve and output current account state.
            account = svc.Get($"{accountUri}?$select=name,revenue,telephone1,description") as JObject;
            Console.WriteLine(account.ToString(Formatting.Indented));

            // Delete the account record
            svc.Delete(accountUri);
            Console.WriteLine("Account Deleted.");

            //Verify that it now longer exists
            try
            {
                svc.Get($"{accountUri}?$select=name,revenue,telephone1,description");
            }
            catch (CDSWebApiException ex)
            {
                if (ex.StatusCode.Equals(404))
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine($"Expected Error: {ex.Message}\n" +
                                      $"\tVerified that Account does not exist.\n" +
                                      $"\tStatusCode: {ex.StatusCode}\n" +
                                      $"\tReasonPhrase: {ex.ReasonPhrase}");
                    Console.ResetColor();
                }
                else
                {
                    throw ex;
                }
            }


            #endregion Optimistic concurrency on delete and update

            #region Controlling upsert operations
            Console.WriteLine("\n--Controlling upsert operations section started--");
            // Attempt to update it only if it exists
            accountUpdate["telephone1"] = "555-0006";
            var IfMatchAnyHeader = new Dictionary <string, List <string> >
            {
                { "If-Match", new List <string> {
                      "*"
                  } }
            };

            try
            {
                svc.Patch(accountUri, accountUpdate, IfMatchAnyHeader);
            }
            catch (CDSWebApiException ex)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine($"Expected Error: {ex.Message}\n" +
                                  $"\tAccount not updated because it does not exist.\n" +
                                  $"\tStatusCode: {ex.StatusCode}\n" +
                                  $"\tReasonPhrase: {ex.ReasonPhrase}");
                Console.ResetColor();
            }
            //Attempt to upsert to re-create the record that was deleted
            // as long as there are no existing account records with the same id.
            var IfNoneMatchAnyHeader = new Dictionary <string, List <string> >
            {
                { "If-None-Match", new List <string> {
                      "*"
                  } }
            };

            //Remove any lookup properties since they cannot be set.
            account.Remove("_transactioncurrencyid_value");

            svc.Patch(accountUri, account, IfNoneMatchAnyHeader);
            Console.WriteLine("Account upserted.");

            //Verify that it now exists again with same id
            try
            {
                svc.Get($"{accountUri}?$select=name");
                Console.WriteLine($"Verified that account with accountid '{account["accountid"]}' exists.");
            }
            catch (CDSWebApiException ex)
            {
                if (ex.StatusCode.Equals(404))
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine($"Unexpected Error: {ex.Message}\n" +
                                      $"\tThe account does not exist.\n" +
                                      $"\tStatusCode: {ex.StatusCode}\n" +
                                      $"\tReasonPhrase: {ex.ReasonPhrase}");
                    Console.ResetColor();
                }
                else
                {
                    throw ex;
                }
            }

            #endregion Controlling upsert operations

            #region Clean-up
            //Delete the account record for good
            svc.Delete(accountUri);
            #endregion Clean-up

            Console.WriteLine("\t--Conditional Operations Completed--");
        }
Exemplo n.º 2
0
        private static void CreateRequiredRecords(CDSWebApiService svc)
        {
            //Create a parent account, an associated incident with three associated tasks
            //(required for CalculateTotalTimeIncident).
            Console.WriteLine("----Creating Required Records---- -");

            JObject account1    = new JObject(new JProperty("name", "Fourth Coffee"));
            var     account1Uri = svc.PostCreate("accounts", account1);

            entityUris.Add(account1Uri);
            JObject incident1 = new JObject
                                (
                new JProperty("title", "Sample Case"),
                new JProperty("*****@*****.**", account1Uri),
                new JProperty("Incident_Tasks",
                              new JArray(
                                  new JObject(
                                      new JProperty("subject", "Task 1"),
                                      new JProperty("actualdurationminutes", 30)
                                      ),
                                  new JObject(
                                      new JProperty("subject", "Task 2"),
                                      new JProperty("actualdurationminutes", 30)
                                      ),
                                  new JObject(
                                      new JProperty("subject", "Task 3"),
                                      new JProperty("actualdurationminutes", 30)
                                      ))));

            incident1Uri = svc.PostCreate("incidents", incident1);

            Console.WriteLine("Incident and related tasks are Created");

            //Close the associated tasks (so that they represent completed work).
            JObject completeCode = new JObject(
                new JProperty("statecode", 1),
                new JProperty("statuscode", 5));

            var incidentTaskRefs = svc.Get($"{incident1Uri}/Incident_Tasks/$ref");

            foreach (JObject obj in incidentTaskRefs["value"])
            {
                svc.Patch(new Uri(obj["@odata.id"].ToString()), completeCode);
            }
            Console.WriteLine("Tasks are closed.");

            //Create another account and associated opportunity (required for CloseOpportunityAsWon).
            JObject account2 = new JObject(
                new JProperty("name", "Coho Winery"),
                new JProperty("opportunity_customer_accounts",
                              new JArray(
                                  new JObject(
                                      new JProperty("name", "Opportunity to win")
                                      ))));
            var account2Uri = svc.PostCreate("accounts", account2);

            entityUris.Add(account2Uri);
            Console.WriteLine("Another Account is created with associated Opportunity");
            //Retrieve the URI to the opportunity.
            var custOpporRefs = svc.Get($"{account2Uri}/opportunity_customer_accounts/$ref");

            opportunity1Uri = new Uri(custOpporRefs["value"][0]["@odata.id"].ToString());

            //Create a contact to use with custom action sample_AddNoteToContact
            var contact1 = new JObject(
                new JProperty("firstname", "Jon"),
                new JProperty("lastname", "Fogg"));

            contact1Uri = svc.PostCreate("contacts", contact1);
            Console.WriteLine("Contact record is created");
            entityUris.Add(contact1Uri);
        }
        public static void Run(CDSWebApiService svc, bool deleteCreatedRecords)
        {
            Console.WriteLine("--Starting Basic Operations--");

            #region Section 1: Basic Create and Update operations
            Console.WriteLine("--Section 1 started--");
            //Create a contact
            var contact1 = new JObject
            {
                { "firstname", "Rafel" },
                { "lastname", "Shillo" }
            };
            Uri contact1Uri = svc.PostCreate("contacts", contact1);
            Console.WriteLine($"Contact '{contact1["firstname"]} " +
                              $"{contact1["lastname"]}' created.");
            entityUris.Add(contact1Uri); //To delete later
            Console.WriteLine($"Contact URI: {contact1Uri}");

            //Update a contact
            JObject contact1Add = new JObject
            {
                { "annualincome", 80000 },
                { "jobtitle", "Junior Developer" }
            };
            svc.Patch(contact1Uri, contact1Add);
            Console.WriteLine(
                $"Contact '{contact1["firstname"]} {contact1["lastname"]}' " +
                $"updated with jobtitle and annual income");

            //Retrieve a contact
            var retrievedcontact1 = svc.Get(contact1Uri.ToString() +
                                            "?$select=fullname,annualincome,jobtitle,description");
            Console.WriteLine($"Contact '{retrievedcontact1["fullname"]}' retrieved: \n" +
                              $"\tAnnual income: {retrievedcontact1["annualincome"]}\n" +
                              $"\tJob title: {retrievedcontact1["jobtitle"]} \n" +
                              //description is initialized empty.
                              $"\tDescription: {retrievedcontact1["description"]}.");

            //Modify specific properties and then update entity instance.
            JObject contact1Update = new JObject
            {
                { "jobtitle", "Senior Developer" },
                { "annualincome", 95000 },
                { "description", "Assignment to-be-determined" }
            };
            svc.Patch(contact1Uri, contact1Update);

            Console.WriteLine($"Contact '{retrievedcontact1["fullname"]}' updated:\n" +
                              $"\tJob title: {contact1Update["jobtitle"]}\n" +
                              $"\tAnnual income: {contact1Update["annualincome"]}\n" +
                              $"\tDescription: {contact1Update["description"]}\n");

            // Change just one property
            string telephone1 = "555-0105";
            svc.Put(contact1Uri, "telephone1", telephone1);
            Console.WriteLine($"Contact '{retrievedcontact1["fullname"]}' " +
                              $"phone number updated.");

            //Now retrieve just the single property.
            var telephone1Value = svc.Get($"{contact1Uri}/telephone1");
            Console.WriteLine($"Contact's telephone # is: {telephone1Value["value"]}.");

            #endregion Section 1: Basic Create and Update operations

            #region Section 2: Create record associated to another
            /// <summary>
            /// Demonstrates creation of entity instance and simultaneous association to another,
            ///  existing entity.
            /// </summary>
            ///

            Console.WriteLine("\n--Section 2 started--");


            //Create a new account and associate with existing contact in one operation.
            var account1 = new JObject
            {
                { "name", "Contoso Ltd" },
                { "telephone1", "555-5555" },
                { "*****@*****.**", contact1Uri }
            };
            var account1Uri = svc.PostCreate("accounts", account1);
            entityUris.Add(account1Uri); //To delete later
            Console.WriteLine($"Account '{account1["name"]}' created.");
            Console.WriteLine($"Account URI: {account1Uri}");
            //Retrieve account name and primary contact info
            JObject retrievedAccount1 = svc.Get($"{account1Uri}?$select=name," +
                                                $"&$expand=primarycontactid($select=fullname,jobtitle,annualincome)") as JObject;

            Console.WriteLine($"Account '{retrievedAccount1["name"]}' has primary contact " +
                              $"'{retrievedAccount1["primarycontactid"]["fullname"]}':");
            Console.WriteLine($"\tJob title: {retrievedAccount1["primarycontactid"]["jobtitle"]} \n" +
                              $"\tAnnual income: {retrievedAccount1["primarycontactid"]["annualincome"]}");

            #endregion Section 2: Create record associated to another

            #region Section 3: Create related entities
            /// <summary>
            /// Demonstrates creation of entity instance and related entities in a single operation.
            /// </summary>
            ///
            Console.WriteLine("\n--Section 3 started--");
            //Create the following entries in one operation: an account, its
            // associated primary contact, and open tasks for that contact.  These
            // entity types have the following relationships:
            //    Accounts
            //       |---[Primary] Contact (N-to-1)
            //              |---Tasks (1-to-N)

            //Build the Account object inside-out, starting with most nested type(s)
            JArray  tasks = new JArray();
            JObject task1 = new JObject
            {
                { "subject", "Sign invoice" },
                { "description", "Invoice #12321" },
                { "scheduledend", DateTimeOffset.Parse("4/19/2019") }
            };
            tasks.Add(task1);
            JObject task2 = new JObject
            {
                { "subject", "Setup new display" },
                { "description", "Theme is - Spring is in the air" },
                { "scheduledstart", DateTimeOffset.Parse("4/20/2019") }
            };
            tasks.Add(task2);
            JObject task3 = new JObject
            {
                { "subject", "Conduct training" },
                { "description", "Train team on making our new blended coffee" },
                { "scheduledstart", DateTimeOffset.Parse("6/1/2019") }
            };
            tasks.Add(task3);

            JObject contact2 = new JObject
            {
                { "firstname", "Susie" },
                { "lastname", "Curtis" },
                { "jobtitle", "Coffee Master" },
                { "annualincome", 48000 },
                //Add related tasks using corresponding navigation property
                { "Contact_Tasks", tasks }
            };

            JObject account2 = new JObject
            {
                { "name", "Fourth Coffee" },
                //Add related contacts using corresponding navigation property
                { "primarycontactid", contact2 }
            };

            //Create the account and related records
            Uri account2Uri = svc.PostCreate("accounts", account2);
            Console.WriteLine($"Account '{account2["name"]}  created.");
            entityUris.Add(account2Uri); //To delete later
            Console.WriteLine($"Contact URI: {account2Uri}");

            //Retrieve account, primary contact info, and assigned tasks for contact.
            //CDS only supports querying-by-expansion one level deep, so first query
            // account-primary contact.
            var retrievedAccount2 = svc.Get($"{account2Uri}?$select=name," +
                                            $"&$expand=primarycontactid($select=fullname,jobtitle,annualincome)");

            Console.WriteLine($"Account '{retrievedAccount2["name"]}' " +
                              $"has primary contact '{retrievedAccount2["primarycontactid"]["fullname"]}':");

            Console.WriteLine($"\tJob title: {retrievedAccount2["primarycontactid"]["jobtitle"]} \n" +
                              $"\tAnnual income: {retrievedAccount2["primarycontactid"]["annualincome"]}");

            //Next retrieve same contact and its assigned tasks.
            //Don't have a saved URI for contact 'Susie Curtis', so create one
            // from base address and entity ID.
            Uri contact2Uri = new Uri($"{svc.BaseAddress}contacts({retrievedAccount2["primarycontactid"]["contactid"]})");
            //Retrieve the contact
            var retrievedcontact2 = svc.Get($"{contact2Uri}?$select=fullname," +
                                            $"&$expand=Contact_Tasks($select=subject,description,scheduledstart,scheduledend)");

            Console.WriteLine($"Contact '{retrievedcontact2["fullname"]}' has the following assigned tasks:");
            foreach (JToken tk in retrievedcontact2["Contact_Tasks"])
            {
                Console.WriteLine(
                    $"Subject: {tk["subject"]}, \n" +
                    $"\tDescription: {tk["description"]}\n" +
                    $"\tStart: {tk["scheduledstart"].Value<DateTime>().ToString("d")}\n" +
                    $"\tEnd: {tk["scheduledend"].Value<DateTime>().ToString("d")}\n");
            }
            #endregion Section 3: Create related entities

            #region Section 4: Associate and Disassociate entities
            /// <summary>
            /// Demonstrates associating and disassociating of existing entity instances.
            /// </summary>
            Console.WriteLine("\n--Section 4 started--");
            //Add 'Rafel Shillo' to the contact list of 'Fourth Coffee',
            // a 1-to-N relationship.
            JObject rel1 = new JObject
            {
                { "@odata.id", contact1Uri }
            }; //relationship object for msg content
            Uri navUri1 = new Uri($"{account2Uri}/contact_customer_accounts/$ref");
            //Create relationship
            svc.Post(navUri1.ToString(), rel1);
            Console.WriteLine($"Contact '{retrievedcontact1["fullname"]}' " +
                              $"associated to account '{account2["name"]}'.");

            //Retrieve and output all contacts for account 'Fourth Coffee'.
            var retrievedContactList1 = svc.Get($"{account2Uri}/contact_customer_accounts?" +
                                                $"$select=fullname,jobtitle");

            Console.WriteLine($"Contact list for account '{retrievedAccount2["name"]}':");

            foreach (JToken ct in retrievedContactList1["value"])
            {
                Console.WriteLine($"\tName: {ct["fullname"]}, Job title: {ct["jobtitle"]}");
            }

            //Dissociate the contact from the account.  For a collection-valued
            // navigation property, must append URI of referenced entity.
            Uri dis1Uri = new Uri($"{navUri1}?$id={contact1Uri}");
            //Equivalently, could have dissociated from the other end of the
            // relationship, using the single-valued navigation ref, located in
            // the contact 'Peter Cambel'.  This dissociation URI has a simpler form:
            // [Org URI]/api/data/v9.1/contacts([contactid#])/parentcustomerid_account/$ref

            svc.Delete(dis1Uri);
            //'Rafel Shillo' was removed from the the contact list of 'Fourth Coffee'

            //Associate an opportunity to a competitor, an N-to-N relationship.
            //First, create the required entity instances.
            JObject comp1 = new JObject
            {
                { "name", "Adventure Works" },
                {
                    "strengths",
                    "Strong promoter of private tours for multi-day outdoor adventures"
                }
            };
            Uri comp1Uri = svc.PostCreate("competitors", comp1);
            entityUris.Add(comp1Uri); //To delete later

            JObject oppor1 = new JObject
            {
                ["name"]        = "River rafting adventure",
                ["description"] = "Sales team on a river-rafting offsite and team building"
            };
            Uri oppor1Uri = svc.PostCreate("opportunities", oppor1);
            entityUris.Add(oppor1Uri); //To delete later

            //Associate opportunity to competitor via opportunitycompetitors_association.
            // navigation property.
            JObject rel2 = new JObject
            {
                { "@odata.id", comp1Uri }
            };
            Uri navUri2 = new Uri($"{oppor1Uri}/opportunitycompetitors_association/$ref");

            svc.Post(navUri2.ToString(), rel2);
            Console.WriteLine($"Opportunity '{oppor1["name"]}' associated with competitor '{comp1["name"]}'.");

            //Retrieve all opportunities for competitor 'Adventure Works'.
            var retrievedOpporList1 = svc.Get($"{comp1Uri}?$select=name,&$expand=opportunitycompetitors_association($select=name,description)");

            Console.WriteLine($"Competitor '{retrievedOpporList1["name"]}' has the following opportunities:");
            foreach (JToken op in
                     retrievedOpporList1["opportunitycompetitors_association"])
            {
                Console.WriteLine($"\tName: {op["name"]}, \n" +
                                  $"\tDescription: {op["description"]}");
            }

            //Dissociate opportunity from competitor.
            svc.Delete(new Uri($"{navUri2}?$id={comp1Uri}"));
            // 'River rafting adventure' opportunity disassociated with 'Adventure Works' competitor

            #endregion Section 4: Associate and Disassociate entities

            #region Section 5: Delete sample entities
            Console.WriteLine("\n--Section 5 started--");
            //Delete all the created sample entities.  Note that explicit deletion is not required
            // for contact tasks because these are automatically cascade-deleted with owner.

            if (!deleteCreatedRecords)
            {
                Console.Write("\nDo you want these entity records deleted? (y/n) [y]: ");
                String answer = Console.ReadLine();
                answer = answer.Trim();
                if (!(answer.StartsWith("y") || answer.StartsWith("Y") || answer == string.Empty))
                {
                    entityUris.Clear();
                }
                else
                {
                    Console.WriteLine("\nDeleting created records.");
                }
            }
            else
            {
                Console.WriteLine("\nDeleting created records.");
            }

            foreach (Uri entityUrl in entityUris)
            {
                svc.Delete(entityUrl);
            }
            #endregion Section 5: Delete sample entities

            Console.WriteLine("--Basic Operations Completed--");
        }