sendwithus C# Client
none
Target framework is .NET Standard 2.0
With one exception, this client covers all of the sendwithus API calls documented at: https://www.sendwithus.com/docs/api#overview
The exception is the Multi-Langauge API calls; those API calls are not supported in this client. If you require support for the Multi-Language API, please contact sendwithus: https://www.sendwithus.com/contact
If you are using Visual Studio 2015:
- In the Solution Explorer window, right click on your solution and select "Manage NuGet Packages for Solution..."
- Search for "SendwithusClient"
- Be sure to use the one that's by sendwithus. There's another one called SendWithUs.Client by Mimeo, but that is not supported by sendwithus
- Select the "SendwithusClient" package and choose "Install" for your solution/project.
usingsendwithus;// Set the API KeySendwithusClient.ApiKey=<your_api_key>// Test or Production// Configure API settings (optional)SendwithusClient.SetTimeoutInMilliseconds(your_preferred_timeout);// Default is 30000 (30s). This is the timeout for an individual API call attemptSendwithusClient.RetryCount=your_preferred_retryCount;// Default is 3. This is the number of times that each API call will be retried if it fails due to a potentially transient eventSendwithusClient.RetryIntervalMilliseconds=your_preferred_retryInterval;// Default is 100ms. This is the amount of time to wait between retry attempts.The API will perform a retry in the following cases:
| Retry Causes | Exception Thrown |
|---|---|
| API Call Timeout | TaskCanceledException |
| Received HTTP Status 502: BadGateway | SendwithusException |
| Received HTTP Status 503: ServiceUnavailable | SendwithusException |
| Received HTTP Status 505: GatewayTimeout | SendwithusException |
A SendwithusException is a regular Exception with a StatusCode property added
All exceptions will be part of an AggregateException, regardless of whether a retry was attempted or not.
Some examples:
- An API call that fails with a status code 403: Forbidden (not a retriable status code) will throw an AggregateException with one InnerException of type SendwithusException
- An API call that repeatedly times out will throw an AggregateException with InnerExceptions of type TaskCanceledException
- An API call that times out once, then fails with a status code of 503: Service Unavailable, and then fails again with a status code 400: Bad Request will throw an AggregateException with InnerExceptions, in order, of: { TaskCanceledException, SendwithusException, SendwithusException}
The API Client will also throw the following other exceptions:
- An InvalidOperationException will be thrown when adding a new API call to a queue of Batched API calls when the limit of maximum API calls per batch has already been met
try{vartemplates=awaitTemplate.GetTemplatesAsync();}catch(AggregateExceptionexception){// Exception handling}vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";try{varresponse=awaitTemplate.GetTemplateAsync(templateId);}catch(AggregateExceptionexception){// Exception handling}vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";try{vartemplate=awaitTemplate.GetTemplateVersionsAsync(templateId);}catch(AggregateExceptionexception){// Exception handling}vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";varlocale="en-US";try{vartemplate=awaitTemplate.GetTemplateAsync(templateId,locale);}catch(AggregateExceptionexception){// Exception handling}vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";varlocale="en-US";try{vartemplateVersions=awaitTemplate.GetTemplateVersionsAsync(templateId,locale);}catch(AggregateExceptionexception){// Exception handling}vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";varversionId="ver_ET3j2snkKhqsjRjtK6bXJE";try{vartemplateVersion=awaitTemplate.GetTemplateVersionAsync(templateId,versionId);}catch(AggregateExceptionexception){// Exception handling}vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";varlocale="en-US";varversionId="ver_ET3j2snkKhqsjRjtK6bXJE";try{vartemplateVersion=awaitTemplate.GetTemplateVersionAsync(templateId,locale,versionId);}catch(AggregateExceptionexception){// Exception handling}Note: at least one of "html" or "text" must be specified in the updated template version object
vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";varversionId="ver_ET3j2snkKhqsjRjtK6bXJE";varupdatedTemplateVersion=newTemplateVersion();vartemplateVersionName="New Version";vartemplateSubject="edited!";// Create the template datavartemplate_data=newDictionary<string,object>();template_data.Add("amount","$12.00");varupdatedTemplateVersion=newTemplateVersion(templateVersionName,templateSubject);updatedTemplateVersion.html="<html><head></head><body><h1>UPDATE</h1></body></html>";// optionalupdatedTemplateVersion.text="sometext";// optionalupdatedTemplateVersion.preheader="some preheader";// optionalupdatedTemplateVersion.template_data=template_data;// optionaltry{vartemplateVersion=awaitTemplate.UpdateTemplateVersionAsync(templateId,versionId,updatedTemplateVersion);}catch(AggregateExceptionexception){// Exception handling}vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";varlocale="en-US"varversionId="ver_ET3j2snkKhqsjRjtK6bXJE";varupdatedTemplateVersion=newTemplateVersion();vartemplateVersionName="New Version";vartemplateSubject="edited!";varupdatedTemplateVersion=newTemplateVersion(templateVersionName,templateSubject);updatedTemplateVersion.html="<html><head></head><body><h1>UPDATE</h1></body></html>";// optionalupdatedTemplateVersion.text="sometext";// optionalupdatedTemplateVersion.preheader="some preheader";// optionaltry{vartemplateVersion=awaitTemplate.UpdateTemplateVersionAsync(templateId,versionId,updatedTemplateVersion);}catch(AggregateExceptionexception){// Exception handling}vartemplateVersionName="New Template Version";vartemplateSubject="New Version!";vartemplate_data=newDictionary<string,object>();template_data.Add("amount","$12.00");varupdatedTemplateVersion=newTemplateVersion(templateVersionName,templateSubject);updatedTemplateVersion.html="<html><head></head><body><h1>NEW TEMPLATE VERSION</h1></body></html>";// optionalupdatedTemplateVersion.text="some text";// optionalupdatedTemplateVersion.preheader="some preheader";// optionalupdatedTemplateVersion.locale="en-US";// optionalupdatedTemplateVersion.template_data=template_data;// optionaltry{vartemplate=awaitTemplate.CreateTemplateAsync(updatedTemplateVersion);}catch(AggregateExceptionexception){// Exception handling}vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";varlocale="fr-FR";vartemplateVersionName="Published French Version";vartemplateSubject="Ce est un nouveau modèle!";varupdatedTemplateVersion=newTemplateVersion(templateVersionName,templateSubject);updatedTemplateVersion.html="<html><head></head><body><h1>Nouveau modèle!</h1></body></html>";// optionalupdatedTemplateVersion.text="un texte";// optionalupdatedTemplateVersion.preheader="some preheader";// optionaltry{vartemplate=awaitTemplate.AddLocaleToTemplate(templateId,locale,updatedTemplateVersion);}catch(AggregateExceptionexception){// Exception handling}NOTE – At least one of html or text must be specified
vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";vartemplateVersionName="New Template Version";vartemplateSubject="New Version!";vartemplate_data=newDictionary<string,object>();template_data.Add("amount","$12.00");varupdatedTemplateVersion=newTemplateVersion(templateVersionName,templateSubject);updatedTemplateVersion.html="<html><head></head><body><h1>NEW TEMPLATE VERSION</h1></body></html>";// optionalupdatedTemplateVersion.text="some text";// optionalupdatedTemplateVersion.preheader="some preheader";// optionalupdatedTemplateVersion.template_data=template_data;// optionaltry{vartemplateVersion=awaitTemplate.CreateTemplateVersion(templateId,updatedTemplateVersion);}catch(AggregateExceptionexception){// Exception handling}NOTE – At least one of html or text must be specified
vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";varlocale="en-US";vartemplateVersionName="New Template Version";vartemplateSubject="New Version!";varupdatedTemplateVersion=newTemplateVersion(templateVersionName,templateSubject);updatedTemplateVersion.html="<html><head></head><body><h1>NEW TEMPLATE VERSION</h1></body></html>";// optionalupdatedTemplateVersion.text="some text";// optionalupdatedTemplateVersion.preheader="some preheader";// optionaltry{vartemplateVersion=awaitTemplate.CreateTemplateVersion(templateId,locale,updatedTemplateVersion);}catch(AggregateExceptionexception){// Exception handling}vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";try{vargenericApiCallStatus=awaitTemplate.DeleteTemplate(templateId);}catch(AggregateExceptionexception){// Exception handling}vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";varlocale="en-US";try{vargenericApiCallStatus=awaitTemplate.DeleteTemplate(templateId,locale);}catch(AggregateExceptionexception){// Exception handling}We validate all HTML content
Example with only the required parameters:
vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";// Construct the template data// The content of the template data is all optional and is based on the template being usedvartemplateData=newDictionary<string,object>();templateData.Add("first_name","Chuck");templateData.Add("last_name","Norris");templateData.Add("img","http://placekitten.com/50/60");varlink=newDictionary<string,string>();link.Add("url","https://www.sendwithus.com");link.Add("text","sendwithus!");templateData.Add("link",link);// Construct the recipientvarrecipient=newEmailRecipient(DEFAULT_RECIPIENT_EMAIL_ADDRESS);// Construct the email objectvaremail=newEmail(templateId,templateData,recipient);// Send the emailtry{varemailResponse=awaitemail.Send();}catch(AggregateExceptionexception){// Exception handling}Example with all parameters:
vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";// Construct the template data// The content of the template data is all optional and is based on the template being usedvartemplateData=newDictionary<string,object>();templateData.Add("first_name","Chuck");templateData.Add("last_name","Norris");templateData.Add("img","http://placekitten.com/50/60");varlink=newDictionary<string,string>();link.Add("url","https://www.sendwithus.com");link.Add("text","sendwithus!");templateData.Add("link",link);// Construct the recipientvarrecipient=newEmailRecipient(DEFAULT_RECIPIENT_EMAIL_ADDRESS);// Construct the email objectvaremail=newEmail(templateId,templateData,recipient);email.cc.Add(newEmailRecipient("cc_one@email.com","CC One"));email.cc.Add(newEmailRecipient("cc_two@email.com","CC Two"));email.bcc.Add(newEmailRecipient("bcc_one@email.com","BCC One"));email.bcc.Add(newEmailRecipient("bcc_two@email.com","BCC Two"));email.sender.address="company@company.com";email.sender.reply_to="info@company.com";email.sender.name="Company";email.tags.Add("tag1");email.tags.Add("tag2");email.tags.Add("tag3");email.headers.Add("X-HEADER-ONE","header-value");email.inline.id="cat.png";email.inline.data="{BASE_64_ENCODED_FILE_DATA}";email.files.Add(newEmailFileData("doc.txt","{BASE_64_ENCODED_FILE_DATA}"));email.files.Add(newEmailFileData("stuff.zip","{BASE_64_ENCODED_FILE_DATA}"));email.version_name="this version";email.locale="en-US";email.esp_account="esp_EsgkbqQdDg7F3ncbz9EHW7";// Send the emailtry{varemailResponse=awaitemail.Send();}catch(AggregateExceptionexception){// Exception handling}varlogId="log_88be2c0f8b5c6d3933dd578b6a0f13e5";try{varlog=awaitLog.GetLogAsync(logId);}catch(AggregateExceptionexception){// Exception handling}varlogId="log_88be2c0f8b5c6d3933dd578b6a0f13e5";try{varlogEvents=awaitLog.GetLogEventsAsync(logId);}catch(AggregateExceptionexception){// Exception handling}varlogId="log_88be2c0f8b5c6d3933dd578b6a0f13e5";try{varlogResendResponse=awaitLog.ResendLogAsync(logId);}catch(AggregateExceptionexception){// Exception handling}try{varsnippets=awaitSnippet.GetSnippetsAsync();}catch(AggregateExceptionexception){// Exception handling}varsnippetId="snp_bn8c87iXuFWdtYLGJrBAWW";try{varsnippets=awaitSnippet.GetSnippetAsync(snippetId);}catch(AggregateExceptionexception){// Exception handling}varsnippetName="My First Snippet";varsnippetBody="<h1>Welcome!</h1>";try{varsnippetResponse=awaitSnippet.CreateSnippetAsync(snippetName,snippetBody);}catch(AggregateExceptionexception){// Exception handling}varsnippetId="snp_bn8c87iXuFWdtYLGJrBAWW";varsnippetName="Updated Snippet";varsnippetBody="<h1>Welcome Again!</h1>";try{varresponse=awaitSnippet.UpdateSnippetAsync(snippetId,snippetName,snippetBody);}catch(AggregateExceptionexception){// Exception handling}varsnippetId="snp_bn8c87iXuFWdtYLGJrBAWW";try{vargenericApiCallStatus=awaitSnippet.DeleteSnippetAsync(snippetId);}catch(AggregateExceptionexception){// Exception handling}vartemplateId="tem_SxZKpxJSHPbYDWRSQnAQUR";// Create the template datavartemplateData=newDictionary<string,object>();templateData.Add("amount","$12.00");// Create the render objectvarrenderTemplate=newRender(templateId,templateData);renderTemplate.version_id="ver_ET3j2snkKhqsjRjtK6bXJE";// optional. Can use either version_id or version_name to specify a version, but not bothrenderTemplate.locale="en-US";// optionalrenderTemplate.strict=true;// optional. Strict defaults to false if not settry{varrenderTemplateResponse=awaitrenderTemplate.RenderTemplateAsync();}catch(AggregateExceptionexception){// Exception handling}GET /customers/customer@example.com
varcustomerEmailAddress="customer@example.com";try{varcustomerResponse=awaitCustomer.GetCustomerAsync(customerEmailAddress);}catch(AggregateExceptionexception){// Exception handling}If a Customer already exists with the specified email address, then a data merge is performed. Merge operations will:
- replace existing attributes with new values
- add any new attributes to the Customer Merge operations will never remove attributes from a Customer. Note that customer data can only be simple data types like strings and integers.
// Build the customervarcustomer=newCustomer("customer@example.com");customer.data.Add("first_name","Matt");// optionalcustomer.data.Add("city","San Francisco");// optionalcustomer.locale="en-US";// optional// Make the API calltry{vargenericApiCallStatus=awaitCustomer.CreateOrUpdateCustomerAsync(customer);}catch(AggregateExceptionexception){// Exception handling}varcustomerEmailAddress="customer@example.com";try{vargenericApiCallStatus=awaitCustomer.DeleteCustomerAsync(customerEmailAddress);}catch(AggregateExceptionexception){// Exception handling}GET /customers/matt@sendwithus.com/logs?count={count}&created_lt={timestamp}&created_gt={timestamp}
With no query parameters to filter the logs:
varcustomerEmailAddress="customer@example.com";try{varcustomerEmailLogsResponse=awaitCustomer.GetCustomerEmailLogsAsync(customerEmailAddress);}catch(AggregateExceptionexception){// Exception handling}With all query parameters to filter the logs:
varcustomerEmailAddress="customer@example.com";varqueryStartTime=123456789;varqueryEndTime=987654321;// Build the query parameters. All of these are optionalvarqueryParameters=newDictionary<string,object>();queryParameters.Add("count",2);queryParameters.Add("created_gt",queryStartTime);queryParameters.Add("created_lt",queryEndTime);// Make the API calltry{varcustomerEmailLogsResponse=awaitCustomer.GetCustomerEmailLogsAsync(customerEmailAddress,queryParameters);}catch(AggregateExceptionexception){// Exception handling}This will add the specified customer to the first step of the specified drip campaign. If the first step has a delay on it, then it will send the first email once that delay has elapsed.
vardripCampaignId="dc_VXKGx85NmwHnRv9FZv88TW";// Build the drip campaign objectvarrecipient=newEmailRecipient("user@email.com","John");// The email name is optionalvardripCampaign=newDripCampaign(recipient);dripCampaign.cc.Add(newEmailRecipient("cc_one@email.com","Suzy Smith"));// OptionaldripCampaign.cc.Add(newEmailRecipient("cc_two@email.com","Joe"));// OptionaldripCampaign.bcc.Add(newEmailRecipient("bcc_one@email.com","Fake Name"));// OptionaldripCampaign.bcc.Add(newEmailRecipient("bcc_one@email.com","Matt Damon"));// OptionaldripCampaign.sender.address="company@company.com";// OptionaldripCampaign.sender.name="Company";// OptionaldripCampaign.sender.reply_to="info@company.com";// OptionaldripCampaign.tags.Add("tag1");// OptionaldripCampaign.tags.Add("tag2");// OptionaldripCampaign.tags.Add("tag3");// OptionaldripCampaign.locale="en-US";// OptionaldripCampaign.esp_account="esp_1a2b3c4d5e";// OptionaldripCampaign.email_data.Add("amount","$12.00");// Optional// Make the API calltry{varresponse=awaitdripCampaign.ActivateAsync(dripCampaignId);}catch(AggregateExceptionexception){// Exception handling}vardripCampaignId="dc_VXKGx85NmwHnRv9FZv88TW";varcustomerEmailAddress="user@email.com";try{vardripCampaignResponse=awaitDripCampaign.DeactivateAsync(dripCampaignId,customerEmailAddress);}catch(AggregateExceptionexception){// Exception handling}If a user unsubscribes, changes email addresses, or cancels, call this endpoint to remove the specified email address from all active drip campaigns.
varcustomerEmailAddress="user@email.com";try{vardripCampaignDeactivateAllResponse=awaitDripCampaign.DeactivateFromAllCampaignsAsync(customerEmailAddress);}catch(AggregateExceptionexception){// Exception handling}try{vardripCampaignDetails=awaitDripCampaign.GetDripCampaignsAsync();}catch(AggregateExceptionexception){// Exception handling}vardripCampaignId="dc_VXKGx85NmwHnRv9FZv88TW";try{vardripCampaignDetails=awaitDripCampaign.GetDripCampaignAsync(dripCampaignId);}catch(AggregateExceptionexception){// Exception handling}The sendwithus batch endpoint enables multiple API calls to be made in a single HTTP request. NOTE – Batch sizes over 10 requests are not recommended.
- By default, batch API calls are limited to 10 per batch.
- Any additional calls beyond 10 will throw an InvalidOperationException.
- This limit can be increased by calling BatchApiRequest.OverrideMaximumBatchRequests(int newMaximum)
The process to making a batch API call is:
- Call BatchApiRequest.StartNewBatchRequest()
- After making this call, all subsequent API calls will queued up in a new batch request.
- Make all the API calls as you normally would. Instead of being sent, these calls will be queued.
- Call BatchApiRequest.SendBatchApiRequest(). This will send the batch request with all of the queued requests, clear the queue, return the response (which will contain the response for each API call in the queue), and exit batch mode.
- After this call, all subsequent API calls will be sent out as soon as they are called, instead of being queued.
- Access the response to each batch command by calling
Additional Features:
- PauseBatchRequest() and ResumeBatchRequest(): Respectively exist and then re-enter batch mode without clearing the list of batched calls. Allows other API calls to be sent immediately (not batched) while building a list of batched API calls.
- AbortBatchRequest(): Allows a batch API calls can be aborted without sending any of the batched calls. This will exit batch mode and clear the list of batched API calls.
Example using 5 commands:
// Start the batch requestBatchApiRequest.StartNewBatchRequest();// Make the API calls to be batchedvarcustomerEmailAddress="customer@example.com";varsnippetId="snp_bn8c87iXuFWdtYLGJrBAWW";varsnippetName="Updated Snippet";varsnippetBody="<h1>Welcome Again!</h1>";try{// Discard the response to the API calls as it will just be an empty object (since the requests aren't actually sent yet)awaitSnippet.GetSnippetsAsync();awaitLog.GetLogsAsync();awaitSnippet.UpdateSnippetAsync(snippetId,snippetName,snippetBody);awaitDripCampaign.GetDripCampaignsAsync();awaitCustomer.DeleteCustomerAsync(customerEmailAddress);// Make the batch API RequestvarbatchResponses=awaitBatchApiRequest.SendBatchApiRequest();// Get the response to the individual API callsvarsnippets=response[0].GetBody<List<Snippet>>();varlogs=response[1].GetBody<List<Log>>();varsnippetResponse=response[2].GetBody<SnippetResponse>();vardripCampaignDetails=response[3].GetBody<List<DripCampaignDetails>>();vargenericApiCallStatus=response[4].GetBody<GenericApiCallStatus>();}catch(AggregateExceptionexception){// Exception handling}catch(InvalidOperationExceptionexception){// Exception handling}Example sending 11 commands without overriding the limit (to show when the exception is thrown):
varcustomerEmailAddress="customer@example.com";varsnippetId="snp_bn8c87iXuFWdtYLGJrBAWW";varsnippetName="Updated Snippet";varsnippetBody="<h1>Welcome Again!</h1>";// Start the batch requestBatchApiRequest.StartNewBatchRequest();// Make the API calls to be batchedtry{// Make the first 10 API calls// Discard the response to the API calls as it will just be an empty object (since the requests aren't actually sent yet)awaitSnippet.GetSnippetsAsync();awaitLog.GetLogsAsync();awaitSnippet.UpdateSnippetAsync(snippetId,snippetName,snippetBody);awaitDripCampaign.GetDripCampaignsAsync();awaitCustomer.DeleteCustomerAsync(customerEmailAddress);awaitSnippet.GetSnippetsAsync();awaitLog.GetLogsAsync();awaitSnippet.UpdateSnippetAsync(snippetId,snippetName,snippetBody);awaitDripCampaign.GetDripCampaignsAsync();awaitCustomer.DeleteCustomerAsync(customerEmailAddress);// Make the 11th API call. This is when the InvalidOperationException will be thrownawaitSnippet.GetSnippetsAsync();// Make the batch API Request. This won't be reached.varbatchResponses=awaitBatchApiRequest.SendBatchApiRequest();// Handle the responses}catch(AggregateExceptionexception){// Exception handling}catch(InvalidOperationExceptionexception){// Exception handling}Example sending 12 commands after overriding the limit:
varcustomerEmailAddress="customer@example.com";varsnippetId="snp_bn8c87iXuFWdtYLGJrBAWW";varsnippetName="Updated Snippet";varsnippetBody="<h1>Welcome Again!</h1>";// Start the batch requestBatchApiRequest.StartNewBatchRequest();// Override the maximum number of API calls that can be included in this batchBatchApiRequest.OverrideMaximumBatchRequests(12);// Make the API calls to be batchedtry{// Make the first 10 API calls// Discard the response to the API calls as it will just be an empty object (since the requests aren't actually sent yet)awaitSnippet.GetSnippetsAsync();awaitLog.GetLogsAsync();awaitSnippet.UpdateSnippetAsync(snippetId,snippetName,snippetBody);awaitDripCampaign.GetDripCampaignsAsync();awaitCustomer.DeleteCustomerAsync(customerEmailAddress);awaitSnippet.GetSnippetsAsync();awaitLog.GetLogsAsync();awaitSnippet.UpdateSnippetAsync(snippetId,snippetName,snippetBody);awaitDripCampaign.GetDripCampaignsAsync();awaitCustomer.DeleteCustomerAsync(customerEmailAddress);// Make the 11th and 12th API calls. This is when the InvalidOperationException will be thrownawaitSnippet.GetSnippetsAsync();awaitLog.GetLogsAsync();// Make the batch API Request.varbatchResponses=awaitBatchApiRequest.SendBatchApiRequest();// Handle the responses}catch(AggregateExceptionexception){// Exception handling}catch(InvalidOperationExceptionexception){// Exception handling}finally{// Return the max batch request limit to its default value (optional)BatchApiRequest.SetMaximumBatchRequestsToDefault();}Example pausing and resuming a batch request
// Start the batch requestBatchApiRequest.StartNewBatchRequest();try{// Make the API call to be batchedawaitTemplate.GetTemplatesAsync();// Pause the batch requestBatchApiRequest.PauseBatchRequest();// Make another API call which will be sent immediatelyvarsnippets=awaitSnippet.GetSnippetsAsync();// Resume the batch request and add another API call to itBatchApiRequest.ResumeBatchRequest();awaitCustomer.GetCustomerAsync('foo@bar.com');// Make the final batch request, containing the Get Templates and Get Customer API callsvarbatchResponses=awaitBatchApiRequest.SendBatchApiRequest();}catch(AggregateExceptionexception){Assert.Fail(exception.ToString());}catch(InvalidOperationExceptionexception){// Exception handling}Example aborting a batch request
// Start the batch requestBatchApiRequest.StartNewBatchRequest();try{// Make the API call to be batchedawaitTemplate.GetTemplatesAsync();// Abort the batch requestBatchApiRequest.AbortBatchRequest();// Make another API call which will be sent immediatelyvarsnippets=awaitSnippet.GetSnippetsAsync();// For demonstration, make the aborted batch API Reqeust anyways// This will be an empty request as the list of batched API calls was cleared by the Abort callvarbatchResponses=awaitBatchApiRequest.SendBatchApiRequest();}catch(AggregateExceptionexception){Assert.Fail(exception.ToString());}catch(InvalidOperationExceptionexception){// Exception handling}The build version is set by the Sendwithus_csharp/appveyor.yml file. It is set so that the 3rd digit in the build number is automatically incremented whenever a new build is made. To change the major or minor build revision, simply edit the line at the top of the file accordingly:
# version format
version: 1.0.{build}
The way the version settings for the final package are set is:
- "version" variable set in appveyor.yml file, as shown above
- appveyor.yml sets the C# project's "assembly_version", "assembly_file_version", and "assembly_informational_version" to this "version"
- the sendwithus_csharp/Sendwithus/SendwithusClient.nuspec sets the NuGet version to the assembly version
This project uses AppVeyor for its CI. AppVeyor is configured to automatically run all of the unit tests whenever a new commit is pushed to GitHub, regardless of the branch. All of the AppVeyor settings are configured in the Sendwithus_csharp/appveyor.yml file. All unused settings are simply commented out, so all available settings can be identified in that file.
The appveyor.yml file is configured to automatically deploy new commits to NuGet. It is configured so that only new commits on the master branch will be deployed. Therefore, please develop all features on a feature branch and only integrate with master when ready for deployment. This setting can be changed under the "build:" settings in the appveyor.yml file. It is also possible to manually build and deploy the solution from www.appveyor.com.
Settings for the NuGet deployment can be edited in the sendwithus_csharp/Sendwithus/SendwithusClient.nuspec file.
The project is CLS compliant, so the package can be used in any .NET language that supports CLS compliant packages. For example, this includes VB.NET and might also include F# and Visual C++. The lattter two haven't been tested, but support for VB.NET has been. To add the package to a solution in a different language, simply follow the same procedure that you would for C#:
- In the Solution Explorer window, right click on your solution and select "Manage NuGet Packages for Solution..."
- Search for "SendwithusClient"
- Be sure to use the one that's by sendwithus. There's another one called SendWithUs.Client by Mimeo, but that is not supported by sendwithus and might not be CLS compliant.
- Select the "SendwithusClient" package and choose "Install" for your solution/project.
The tests are run using Visual Studio's standard unit-testing libaries and built in test runner. Simply select "Test->Run->All Tests" to run the unit tests.
Sendwithus' API typically sends responses back in these ranges:
- 2xx – Successful Request
- 4xx – Failed Request (Client error)
- 5xx – Failed Request (Server error)
If you're receiving an error in the 400 response range follow these steps:
- Double check the data and ID's getting passed to sendwithus
- Ensure your API key is correct
- Make sure there's no extraneous spaces in the id's getting passed