共用方式為


逐步解說:C 中的 Bing 廣告 API 傳統型應用程式#

此範例 C# 控制台應用程式會透過您提供的認證提示使用者同意,然後取得已驗證使用者可以存取的帳戶。

您必須先註冊應用程式,並記下用戶端標識碼 (已註冊的應用程式識別碼) 。 如需註冊應用程式和授權碼授與流程的詳細資訊,請參閱 使用 OAuth 進行驗證

您也需要生產 開發人員令牌。 您可以依照下面所述逐步建立範例,或從 GitHub 下載更多範例。

程式碼逐步解說

  1. 開啟 Visual Studio 開發環境。

  2. 透過檔案 -New ->>Project 建立專案

  3. 在 [ 新增專案] 視窗的下拉式清單中選擇 [.NET Framework 4.8 ],然後按兩下 [控制台應用程式] (.NET [Framework) ] 範本。 將專案命名為 BingAdsConsoleApp ,然後按兩下 [ 確定]

  4. 透過 NuGet 為 BingAdsConsoleApp 安裝 SDK。 如需相依性的詳細資訊,請 參閱安裝 SDK。 按兩下 [工具->NuGet 套件管理員 ->套件管理員主控台]。 在提示字元中,輸入下列命令,一次安裝一個套件: 和 Install-Package System.Configuration.ConfigurationManagerInstall-Package Microsoft.BingAds.SDK

  5. 開啟 App.config 檔案,並以下列程式代碼區塊取代其內容。 編輯 BingAdsEnvironment 以從沙箱移至生產環境。 如果您的目標是生產環境,則必須將 4c0b021c-00c3-4508-838f-d3127e8167ff 取代為註冊生產應用程式時所布建的應用程式標識符,並將BBD37VB98取代為生產開發人員令牌

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <configSections>
            <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
                <section name="BingAdsConsoleApp.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
            </sectionGroup>
        </configSections>
        <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" />
        </startup>
        <appSettings>
          <!-- To use the production environment, set this value to "Production". -->
          <add key="BingAdsEnvironment" value="Sandbox"/>
          <add key="ClientSettingsProvider.ServiceUri" value=""/>
        </appSettings>
        <userSettings>
            <BingAdsConsoleApp.Properties.Settings>
                <setting name="DeveloperToken" serializeAs="String">
                    <value>BBD37VB98</value>
                </setting>
                <setting name="ClientId" serializeAs="String">
                    <value>4c0b021c-00c3-4508-838f-d3127e8167ff</value>
                </setting>
            </BingAdsConsoleApp.Properties.Settings>
        </userSettings>
    </configuration>
    
  6. 建立配置檔案。 在 BingAdsConsoleApp 的項目檢視中,以滑鼠右鍵按兩下 [ 屬性] ,然後按兩下 [ 開啟]。 按兩下 [ 設定],然後按下文字 [專案不包含預設配置檔案]。按兩下這裡建立一個。 系統會自動新增來自 app.config 的新值。

  7. 開啟Program.cs檔案,並以下列程式代碼區塊取代其內容。

    using System;
    using System.Linq;
    using System.Configuration;
    using System.Net.Http;
    using System.ServiceModel;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Microsoft.BingAds;
    using Microsoft.BingAds.V13.CustomerManagement;
    using BingAdsConsoleApp.Properties;
    using System.IO;
    
    namespace BingAdsConsoleApp
    {
        class Program
        {
            private static AuthorizationData _authorizationData;
            private static ServiceClient<ICustomerManagementService> _customerManagementService;
            private static string ClientState = "ClientStateGoesHere";
    
            static void Main(string[] args)
            {
                try
                {
                    Authentication authentication = AuthenticateWithOAuth();
    
                    // Most Bing Ads API service operations require account and customer ID. 
                    // This utiltiy operation sets the global authorization data instance 
                    // to the first account that the current authenticated user can access. 
                    SetAuthorizationDataAsync(authentication).Wait();
    
                    // You can extend the console app with the examples library at:
                    // https://github.com/BingAds/BingAds-dotNet-SDK/tree/main/examples/BingAdsExamples
                }
                // Catch authentication exceptions
                catch (OAuthTokenRequestException ex)
                {
                    OutputStatusMessage(string.Format("OAuthTokenRequestException Message:\n{0}", ex.Message));
                    if (ex.Details != null)
                    {
                        OutputStatusMessage(string.Format("OAuthTokenRequestException Details:\nError: {0}\nDescription: {1}",
                        ex.Details.Error, ex.Details.Description));
                    }
                }
                // Catch Customer Management service exceptions
                catch (FaultException<AdApiFaultDetail> ex)
                {
                    OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error =>
                    {
                        if ((error.Code == 105) || (error.Code == 106))
                        {
                            return "Authorization data is missing or incomplete for the specified environment.\n" +
                                   "To run the examples switch users or contact support for help with the following error.\n";
                        }
                        return string.Format("{0}: {1}", error.Code, error.Message);
                    })));
                    OutputStatusMessage(string.Join("; ",
                        ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                }
                catch (FaultException<Microsoft.BingAds.V13.CustomerManagement.ApiFault> ex)
                {
                    OutputStatusMessage(string.Join("; ",
                        ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                }
                catch (HttpRequestException ex)
                {
                    OutputStatusMessage(ex.Message);
                }
            }
    
            /// <summary>
            /// Utility method for setting the customer and account identifiers within the global 
            /// <see cref="_authorizationData"/> instance. 
            /// </summary>
            /// <param name="authentication">The OAuth authentication credentials.</param>
            /// <returns></returns>
            private static async Task SetAuthorizationDataAsync(Authentication authentication)
            {
                _authorizationData = new AuthorizationData
                {
                    Authentication = authentication,
                    DeveloperToken = Settings.Default["DeveloperToken"].ToString()
                };
    
                var apiEnvironment = 
                    ConfigurationManager.AppSettings["BingAdsEnvironment"] == ApiEnvironment.Sandbox.ToString() ?
                    ApiEnvironment.Sandbox : ApiEnvironment.Production;
    
                _customerManagementService = new ServiceClient<ICustomerManagementService>(
                    _authorizationData, 
                    apiEnvironment
                );
    
                var getUserRequest = new GetUserRequest
                {
                    UserId = null
                };
    
                var getUserResponse = (await _customerManagementService.CallAsync((s, r) => s.GetUserAsync(r), getUserRequest));
                var user = getUserResponse.User;
    
                var predicate = new Predicate
                {
                    Field = "UserId",
                    Operator = PredicateOperator.Equals,
                    Value = user.Id.ToString()
                };
    
                var paging = new Paging
                {
                    Index = 0,
                    Size = 10
                };
    
                var searchAccountsRequest = new SearchAccountsRequest
                {
                    Ordering = null,
                    PageInfo = paging,
                    Predicates = new[] { predicate }
                };
    
                var searchAccountsResponse =
                    (await _customerManagementService.CallAsync((s, r) => s.SearchAccountsAsync(r), searchAccountsRequest));
    
                var accounts = searchAccountsResponse.Accounts.ToArray();
                if (accounts.Length <= 0) return;
    
                _authorizationData.AccountId = (long)accounts[0].Id;
                _authorizationData.CustomerId = (int)accounts[0].ParentCustomerId;
    
                OutputArrayOfAdvertiserAccount(accounts);
    
                return;
            }
    
            /// <summary>
            /// Authenticates the current user via OAuth.
            /// </summary>
            /// <returns>The OAuth authentication instance for a user.</returns>
            private static Authentication AuthenticateWithOAuth()
            {
                var apiEnvironment = 
                    ConfigurationManager.AppSettings["BingAdsEnvironment"] == ApiEnvironment.Sandbox.ToString() ?
                    ApiEnvironment.Sandbox : ApiEnvironment.Production;
                var oAuthDesktopMobileAuthCodeGrant = new OAuthDesktopMobileAuthCodeGrant(
                    Settings.Default["ClientId"].ToString(),
                    apiEnvironment
                );
    
                // It is recommended that you specify a non guessable 'state' request parameter to help prevent
                // cross site request forgery (CSRF). 
                oAuthDesktopMobileAuthCodeGrant.State = ClientState;
    
                string refreshToken;
    
                // If you have previously securely stored a refresh token, try to use it.
                if (GetRefreshToken(out refreshToken))
                {
                    AuthorizeWithRefreshTokenAsync(oAuthDesktopMobileAuthCodeGrant, refreshToken).Wait();
                }
                else
                {
                    // You must request user consent at least once through a web browser control. 
                    Console.WriteLine(string.Format(
                        "Open a new web browser and navigate to {0}\n\n" +
                        "Grant consent in the web browser for the application to access " +
                        "your advertising accounts, and then enter the response URI that includes " +
                        "the authorization 'code' parameter: \n", oAuthDesktopMobileAuthCodeGrant.GetAuthorizationEndpoint())
                    );
    
                    // Request access and refresh tokens using the URI that you provided manually during program execution.
                    var responseUri = new Uri(Console.ReadLine());
    
                    if (oAuthDesktopMobileAuthCodeGrant.State != ClientState)
                        throw new HttpRequestException("The OAuth response state does not match the client request state.");
    
                    oAuthDesktopMobileAuthCodeGrant.RequestAccessAndRefreshTokensAsync(responseUri).Wait();
                    SaveRefreshToken(oAuthDesktopMobileAuthCodeGrant.OAuthTokens.RefreshToken);
                }
    
                // It is important to save the most recent refresh token whenever new OAuth tokens are received. 
                // You will want to subscribe to the NewOAuthTokensReceived event handler. 
                // When calling Bing Ads API service operations with ServiceClient<TService>, BulkServiceManager, or ReportingServiceManager, 
                // each instance will refresh your access token automatically if they detect the AuthenticationTokenExpired (109) error code. 
                oAuthDesktopMobileAuthCodeGrant.NewOAuthTokensReceived +=
                    (sender, tokens) => SaveRefreshToken(tokens.NewRefreshToken);
    
                return oAuthDesktopMobileAuthCodeGrant;
            }
    
            /// <summary>
            /// Requests new access and refresh tokens given an existing refresh token.
            /// </summary>
            /// <param name="authentication">The OAuth authentication instance for a user.</param>
            /// <param name="refreshToken">The previous refresh token.</param>
            /// <returns></returns>
            private static Task<OAuthTokens> AuthorizeWithRefreshTokenAsync(
                OAuthDesktopMobileAuthCodeGrant authentication, 
                string refreshToken)
            {
                return authentication.RequestAccessAndRefreshTokensAsync(refreshToken);
            }
    
            /// <summary>
            /// You should modify the example, and store the refresh token securely.
            /// </summary>
            /// <param name="newRefreshtoken">The refresh token to save.</param>
            private static void SaveRefreshToken(string newRefreshtoken)
            {
                if (newRefreshtoken != null)
                {
                    using (StreamWriter outputFile = new StreamWriter(
                    Environment.CurrentDirectory + @"\refreshtoken.txt",
                    false))
                    {
                        outputFile.WriteLine(newRefreshtoken);
                    }
                }
            }
    
            /// <summary>
            /// Returns the prior refresh token if available.
            /// </summary>
            /// <param name="refreshToken"></param>
            /// <returns>The latest stored refresh token.</returns>
            private static bool GetRefreshToken(out string refreshToken)
            {
                var filePath = Environment.CurrentDirectory + @"\refreshtoken.txt";
                if (!File.Exists(filePath))
                {
                    refreshToken = null;
                    return false;
                }
    
                String fileContents;
                using (StreamReader sr = new StreamReader(filePath))
                {
                    fileContents = sr.ReadToEnd();
                }
    
                if (string.IsNullOrEmpty(fileContents))
                {
                    refreshToken = null;
                    return false;
                }
    
                try
                {
                    refreshToken = fileContents;
                    return true;
                }
                catch (FormatException)
                {
                    refreshToken = null;
                    return false;
                }
            }
    
            #region OutputHelpers
    
            /**
             * You can extend the console app with the example helpers at:
             * https://github.com/BingAds/BingAds-dotNet-SDK/tree/main/examples/BingAdsExamples
             **/
    
            private static void OutputArrayOfAdvertiserAccount(IList<AdvertiserAccount> dataObjects)
            {
                if (null != dataObjects)
                {
                    foreach (var dataObject in dataObjects)
                    {
                        OutputAdvertiserAccount(dataObject);
                        OutputStatusMessage("\n");
                    }
                }
            }
    
            private static void OutputAdvertiserAccount(AdvertiserAccount dataObject)
            {
                if (null != dataObject)
                {
                    OutputStatusMessage(string.Format("BillToCustomerId: {0}", dataObject.BillToCustomerId));
                    OutputStatusMessage(string.Format("CurrencyCode: {0}", dataObject.CurrencyCode));
                    OutputStatusMessage(string.Format("AccountFinancialStatus: {0}", dataObject.AccountFinancialStatus));
                    OutputStatusMessage(string.Format("Id: {0}", dataObject.Id));
                    OutputStatusMessage(string.Format("Language: {0}", dataObject.Language));
                    OutputStatusMessage(string.Format("LastModifiedByUserId: {0}", dataObject.LastModifiedByUserId));
                    OutputStatusMessage(string.Format("LastModifiedTime: {0}", dataObject.LastModifiedTime));
                    OutputStatusMessage(string.Format("Name: {0}", dataObject.Name));
                    OutputStatusMessage(string.Format("Number: {0}", dataObject.Number));
                    OutputStatusMessage(string.Format("ParentCustomerId: {0}", dataObject.ParentCustomerId));
                    OutputStatusMessage(string.Format("PaymentMethodId: {0}", dataObject.PaymentMethodId));
                    OutputStatusMessage(string.Format("PaymentMethodType: {0}", dataObject.PaymentMethodType));
                    OutputStatusMessage(string.Format("PrimaryUserId: {0}", dataObject.PrimaryUserId));
                    OutputStatusMessage(string.Format("AccountLifeCycleStatus: {0}", dataObject.AccountLifeCycleStatus));
                    OutputStatusMessage(string.Format("TimeStamp: {0}", dataObject.TimeStamp));
                    OutputStatusMessage(string.Format("TimeZone: {0}", dataObject.TimeZone));
                    OutputStatusMessage(string.Format("PauseReason: {0}", dataObject.PauseReason));
                    OutputArrayOfKeyValuePairOfstringstring(dataObject.ForwardCompatibilityMap);
                    OutputArrayOfCustomerInfo(dataObject.LinkedAgencies);
                    OutputStatusMessage(string.Format("SalesHouseCustomerId: {0}", dataObject.SalesHouseCustomerId));
                    OutputArrayOfKeyValuePairOfstringstring(dataObject.TaxInformation);
                    OutputStatusMessage(string.Format("BackUpPaymentInstrumentId: {0}", dataObject.BackUpPaymentInstrumentId));
                    OutputStatusMessage(string.Format("BillingThresholdAmount: {0}", dataObject.BillingThresholdAmount));
                    OutputAddress(dataObject.BusinessAddress);
                    OutputStatusMessage(string.Format("AutoTagType: {0}", dataObject.AutoTagType));
                    OutputStatusMessage(string.Format("SoldToPaymentInstrumentId: {0}", dataObject.SoldToPaymentInstrumentId));
                }
            }
    
            private static void OutputAddress(Address dataObject)
            {
                if (null != dataObject)
                {
                    OutputStatusMessage(string.Format("City: {0}", dataObject.City));
                    OutputStatusMessage(string.Format("CountryCode: {0}", dataObject.CountryCode));
                    OutputStatusMessage(string.Format("Id: {0}", dataObject.Id));
                    OutputStatusMessage(string.Format("Line1: {0}", dataObject.Line1));
                    OutputStatusMessage(string.Format("Line2: {0}", dataObject.Line2));
                    OutputStatusMessage(string.Format("Line3: {0}", dataObject.Line3));
                    OutputStatusMessage(string.Format("Line4: {0}", dataObject.Line4));
                    OutputStatusMessage(string.Format("PostalCode: {0}", dataObject.PostalCode));
                    OutputStatusMessage(string.Format("StateOrProvince: {0}", dataObject.StateOrProvince));
                    OutputStatusMessage(string.Format("TimeStamp: {0}", dataObject.TimeStamp));
                    OutputStatusMessage(string.Format("BusinessName: {0}", dataObject.BusinessName));
                }
            }
    
            private static void OutputArrayOfKeyValuePairOfstringstring(IList<KeyValuePair<string, string>> dataObjects)
            {
                if (null != dataObjects)
                {
                    foreach (var dataObject in dataObjects)
                    {
                        OutputKeyValuePairOfstringstring(dataObject);
                    }
                }
            }
    
            private static void OutputKeyValuePairOfstringstring(KeyValuePair<string, string> dataObject)
            {
                if (null != dataObject.Key)
                {
                    OutputStatusMessage(string.Format("key: {0}", dataObject.Key));
                    OutputStatusMessage(string.Format("value: {0}", dataObject.Value));
                }
            }
    
            private static void OutputCustomerInfo(CustomerInfo dataObject)
            {
                if (null != dataObject)
                {
                    OutputStatusMessage(string.Format("Id: {0}", dataObject.Id));
                    OutputStatusMessage(string.Format("Name: {0}", dataObject.Name));
                }
            }
    
            private static void OutputArrayOfCustomerInfo(IList<CustomerInfo> dataObjects)
            {
                if (null != dataObjects)
                {
                    foreach (var dataObject in dataObjects)
                    {
                        OutputCustomerInfo(dataObject);
                        OutputStatusMessage("\n");
                    }
                }
            }
    
            private static void OutputStatusMessage(String msg)
            {
                Console.WriteLine(msg);
            }
    
            #endregion OutputHelpers
        }
    }
    
  8. 按兩下 [建置 ->建置 BingAdsConsoleApp],然後執行應用程式。 當您啟動應用程式時,預設會提示您在生產環境中驗證 Microsoft 帳戶認證。

設定沙箱

若要使用沙箱,請在專案根目錄 App.config檔的 appSettings> 節點內<,將 BingAdsEnvironment 金鑰設定為沙箱。

<add key="BingAdsEnvironment" value ="Sandbox"/>

您也可以個別設定每個 ServiceClient 的環境,如下所示。

_customerManagementService = new ServiceClient<ICustomerManagementService>(
    _authorizationData, 
    ApiEnvironment.Sandbox
);

無論您是全域或個別設定 ServiceClient 環境,您也必須將 OAuth 環境設定為沙箱。

var oAuthDesktopMobileAuthCodeGrant = new OAuthDesktopMobileAuthCodeGrant(
    ClientId, 
    ApiEnvironment.Sandbox
);

另請參閱

沙箱
Bing 廣告 API 程式代碼範例
Bing 廣告 API Web 服務位址