You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#通过SOAP/REST API停用并激活Salesforce自定义触发器

Hey there! I’ve tackled exactly this scenario before—here’s a practical, step-by-step solution using C# with Salesforce’s REST API to safely toggle your trigger’s activation status. This works perfectly for Developer Edition orgs, and includes error handling to ensure you don’t leave triggers inactive accidentally:

Prerequisites

First, make sure you have these set up:

  • A Salesforce Connected App with API access (enable OAuth2, grant Full Access or Modify All Data permissions)
  • Your org’s instance URL, connected app credentials (client ID/secret), and a user account with permissions to modify Apex triggers
  • A C# project (Console App, ASP.NET, etc.) with System.Net.Http and System.Text.Json packages installed (or use the official Salesforce.NET SDK if you prefer)
Step 1: Authenticate with Salesforce REST API

First, we need to get an OAuth2 access token to make API calls. Here’s a reusable method:

using System.Net.Http;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Net.Http.Headers;

public async Task<string> GetSalesforceAuthToken(string instanceUrl, string clientId, string clientSecret, string username, string password)
{
    var tokenEndpoint = $"{instanceUrl}/services/oauth2/token";
    var formData = new Dictionary<string, string>
    {
        {"grant_type", "password"},
        {"client_id", clientId},
        {"client_secret", clientSecret},
        {"username", username},
        {"password", password} // Don't forget to append your Salesforce security token here!
    };

    using var httpClient = new HttpClient();
    var response = await httpClient.PostAsync(tokenEndpoint, new FormUrlEncodedContent(formData));
    response.EnsureSuccessStatusCode();
    
    var tokenResponse = await response.Content.ReadAsAsync<dynamic>();
    return tokenResponse.access_token;
}
Step 2: Deactivate the Target Trigger

Next, we’ll query the ApexTrigger object to find our target trigger, then update its IsActive field to false:

public async Task DeactivateTrigger(string instanceUrl, string accessToken, string triggerDeveloperName)
{
    // Query the active trigger to get its ID
    var queryEndpoint = $"{instanceUrl}/services/data/v59.0/query?q=SELECT+Id+FROM+ApexTrigger+WHERE+DeveloperName='{triggerDeveloperName}'+AND+Status='Active'";
    
    using var httpClient = new HttpClient();
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    
    var queryResponse = await httpClient.GetAsync(queryEndpoint);
    queryResponse.EnsureSuccessStatusCode();
    
    var queryResult = await queryResponse.Content.ReadAsAsync<dynamic>();
    if (queryResult.totalSize == 0)
    {
        throw new Exception($"Trigger {triggerDeveloperName} not found or already inactive.");
    }
    
    var triggerId = queryResult.records[0].Id;
    
    // Update trigger to inactive
    var updateEndpoint = $"{instanceUrl}/services/data/v59.0/sobjects/ApexTrigger/{triggerId}";
    var updateBody = new { IsActive = false };
    
    var updateResponse = await httpClient.PatchAsync(updateEndpoint, new StringContent(
        System.Text.Json.JsonSerializer.Serialize(updateBody), 
        System.Text.Encoding.UTF8, 
        "application/json"));
    
    updateResponse.EnsureSuccessStatusCode();
    Console.WriteLine($"Trigger {triggerDeveloperName} deactivated successfully.");
}
Step 3: Perform Your Org Operations

This is where you run your custom org tasks—like bulk contact updates, data migrations, or any process that needs the trigger disabled. Wrap this in error handling to ensure we can recover the trigger status if something goes wrong:

private void ExecuteOrgOperations()
{
    // Replace this with your actual org-specific logic
    Console.WriteLine("Running org operations...");
    // Example: Bulk update Contact records, run a custom Apex class, etc.
}
Step 4: Reactivate the Trigger

Once your operations are done, re-enable the trigger using a similar method to deactivation:

public async Task ReactivateTrigger(string instanceUrl, string accessToken, string triggerDeveloperName)
{
    // Query the inactive trigger to get its ID
    var queryEndpoint = $"{instanceUrl}/services/data/v59.0/query?q=SELECT+Id+FROM+ApexTrigger+WHERE+DeveloperName='{triggerDeveloperName}'+AND+Status='Inactive'";
    
    using var httpClient = new HttpClient();
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    
    var queryResponse = await httpClient.GetAsync(queryEndpoint);
    queryResponse.EnsureSuccessStatusCode();
    
    var queryResult = await queryResponse.Content.ReadAsAsync<dynamic>();
    if (queryResult.totalSize == 0)
    {
        throw new Exception($"Trigger {triggerDeveloperName} not found or already active.");
    }
    
    var triggerId = queryResult.records[0].Id;
    
    // Update trigger to active
    var updateEndpoint = $"{instanceUrl}/services/data/v59.0/sobjects/ApexTrigger/{triggerId}";
    var updateBody = new { IsActive = true };
    
    var updateResponse = await httpClient.PatchAsync(updateEndpoint, new StringContent(
        System.Text.Json.JsonSerializer.Serialize(updateBody), 
        System.Text.Encoding.UTF8, 
        "application/json"));
    
    updateResponse.EnsureSuccessStatusCode();
    Console.WriteLine($"Trigger {triggerDeveloperName} reactivated successfully.");
}
Full Workflow with Error Handling

Put it all together with robust error handling to guarantee the trigger gets reactivated even if your operations fail:

public async Task RunTriggerToggleWorkflow()
{
    // Replace these values with your org's details
    string instanceUrl = "https://your-dev-ed.my.salesforce.com";
    string clientId = "YOUR_CONNECTED_APP_CLIENT_ID";
    string clientSecret = "YOUR_CONNECTED_APP_CLIENT_SECRET";
    string username = "your-username@example.com";
    string password = "your-password+security-token";
    string targetTrigger = "UpdateContactData";
    
    string accessToken = string.Empty;
    
    try
    {
        // Authenticate
        accessToken = await GetSalesforceAuthToken(instanceUrl, clientId, clientSecret, username, password);
        
        // Deactivate trigger
        await DeactivateTrigger(instanceUrl, accessToken, targetTrigger);
        
        // Run org operations
        ExecuteOrgOperations();
        
        // Reactivate trigger
        await ReactivateTrigger(instanceUrl, accessToken, targetTrigger);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error occurred: {ex.Message}");
        
        // Attempt to reactivate the trigger even if something fails
        if (!string.IsNullOrEmpty(accessToken))
        {
            try
            {
                await ReactivateTrigger(instanceUrl, accessToken, targetTrigger);
                Console.WriteLine("Trigger reactivated as part of error recovery.");
            }
            catch (Exception recoveryEx)
            {
                Console.WriteLine($"Failed to recover trigger status: {recoveryEx.Message}");
            }
        }
    }
}
Key Notes & Troubleshooting
  • API Version: Replace v59.0 with the latest API version supported by your org (check Setup > API > API Versions)
  • Managed Packages: If your trigger is in a managed package, add AND NamespacePrefix='YOUR_PACKAGE_NAMESPACE' to your SOQL query
  • Permissions: Ensure your user has Modify All Data or Author Apex + Customize Application permissions to modify triggers
  • SOAP API Alternative: If you prefer SOAP, use the update() call on the ApexTrigger object—just generate the WSDL for your org and use it in your C# project

内容的提问来源于stack exchange,提问作者Shripal Gandhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:42:26