Procedura dettagliata: Applicazione desktop API Bing Ads in C#

In questo esempio l'applicazione console C# richiede il consenso dell'utente tramite le credenziali specificate e quindi ottiene gli account a cui l'utente autenticato può accedere.

È innanzitutto necessario registrare un'applicazione e prendere nota dell'ID client (ID applicazione registrato). Per altre informazioni sulla registrazione di un'applicazione e sul flusso di concessione del codice di autorizzazione, vedere Autenticazione con OAuth.

Sarà necessario anche il token per sviluppatori di produzione. È possibile creare l'esempio passo dopo passo come descritto di seguito o scaricare altri esempi da GitHub.

Procedura dettagliata per il codice

  1. Aprire l'ambiente di sviluppo di Visual Studio .

  2. Creare un nuovo progetto tramite File ->Nuovo ->Project

  3. Nella finestra Nuovo progetto scegliere .NET Framework 4.8 nell'elenco a discesa e quindi fare clic sul modello App console (.NET Framework). Assegnare al progetto il nome BingAdsConsoleApp e fare clic su OK.

  4. Installare l'SDK tramite NuGet per BingAdsConsoleApp. Per altre informazioni sulle dipendenze, vedere Installare l'SDK. Fare clic su Strumenti ->Gestione pacchetti NuGet ->Console di Gestione pacchetti. Al prompt digitare questi comandi per installare i pacchetti uno alla volta: Install-Package Microsoft.BingAds.SDK e Install-Package System.Configuration.ConfigurationManager.

  5. Aprire il file App.config e sostituirlo con il blocco di codice seguente. Modificare BingAdsEnvironment per passare dalla sandbox alla produzione. Se si ha come destinazione l'ambiente di produzione, è necessario sostituire 4c0b021c-00c3-4508-838f-d3127e8167ff con l'ID applicazione di cui è stato effettuato il provisioning quando è stata registrata l'applicazione di produzione e sostituire BBD37VB98 con il token di sviluppo di produzione.

    <?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. Creare un file di impostazioni. Nella visualizzazione progetto per BingAdsConsoleApp fare clic con il pulsante destro del mouse su Proprietà e scegliere Apri. Fare clic su Impostazioni e quindi sul testo Il progetto non contiene un file di impostazioni predefinito. Fare clic qui per crearne uno. I nuovi valori di app.config verranno aggiunti automaticamente.

  7. Aprire il file Program.cs e sostituirlo con il blocco di codice seguente.

    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. Fare clic su Build ->Build BingAdsConsoleApp e quindi eseguire l'applicazione. Quando si avvia l'applicazione, per impostazione predefinita verranno richieste le credenziali dell'account Microsoft per l'autenticazione nell'ambiente di produzione.

Configurazione della sandbox

Per usare la sandbox, impostare la chiave BingAdsEnvironment su Sandbox all'interno del <nodo appSettings> del file diApp.config della radice del progetto.

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

È anche possibile impostare l'ambiente per ogni ServiceClient singolarmente come indicato di seguito.

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

Sia che si imposti l'ambiente ServiceClient a livello globale o singolarmente, separatamente è anche necessario impostare l'ambiente OAuth su sandbox.

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

Vedere anche

Sandbox
Esempi di codice API Bing Ads
Indirizzi del servizio Web dell'API Bing Ads