CampaignService get always returning null with no error

537 views
Skip to first unread message

Martin Tierney

unread,
May 11, 2016, 9:02:50 AM5/11/16
to AdWords API Forum
Hi,

I was hoping someone can point me in the right direction.

in my app i need to be able to connect to other accounts so i have implemented oauth2flow which i took from the example app.
it lets me log in to an account just fine and i get the oath object back. I can also make a call to the campaign service with no errors returned but the campaign page object always returns with no entries.

i don't think its  permission thing because when i run the example app i get my test accounts back.

i just wish i had an error to work with

below is my code:

Base controller: (used to store the oauth object between controllers)
public class BaseController : Controller
    {
        protected internal static HttpSessionStateBase MySession { get; set; }

        protected internal static OAuth2ProviderForApplications OAuth { get; set; }
    }

Auth controller:
[HttpPost]
        public ActionResult AuthUser()
        {
            var config = _user.Config as AdWordsAppConfig;
            if (_user.Config.OAuth2Mode == OAuth2Flow.APPLICATION &&
            string.IsNullOrEmpty(config.OAuth2RefreshToken))
            {
                return RedirectToAction("AuthLogin");
            }
            
            //TODO: need to add error page
            return RedirectToAction("Index");
        }

        public ActionResult AuthLogin()
        {
            AdWordsAppConfig config = new AdWordsAppConfig();
            if (config.OAuth2Mode == OAuth2Flow.APPLICATION &&
                string.IsNullOrEmpty(config.OAuth2RefreshToken))
            {
                DoAuth2Configuration(config);
            }

            return RedirectToAction("Index");
        }

        private void DoAuth2Configuration(AdWordsAppConfig config)
        {
            // Since we use this page for OAuth callback also, we set the callback
            // url as the current page. For a non-web application, this will be null.
            config.OAuth2RedirectUri = Request.Url.GetLeftPart(UriPartial.Path);

            // Create an OAuth2 object for handling OAuth2 flow.
            OAuth2ProviderForApplications oAuth = new OAuth2ProviderForApplications(config);

            if (Request.Params["state"] == null)
            {
                // This is the first time this page is being loaded.
                // Set the state variable to any value that helps you recognize
                // when this url will be called by the OAuth2 server.
                oAuth.State = "callback";

                // Create an authorization url and redirect the user to that page.
                Response.Redirect(oAuth.GetAuthorizationUrl());
            }
            else if (Request.Params["state"] == "callback")
            {
                // This page was loaded because OAuth server did a callback.
                // Retrieve the authorization code from the url and use it to fetch
                // the access token. This call will also fetch the refresh token if
                // your mode is offline.
                oAuth.FetchAccessAndRefreshTokens(Request.Params["code"]);

                // Save the OAuth2 provider for future use. If you wish to save only
                // the values and restore the object later, then save
                // oAuth.RefreshToken, oAuth.AccessToken, oAuth.UpdatedOn and
                // oAuth.ExpiresIn.
                //
                // You can later restore the values as
                // AdWordsUser user = new AdWordsUser();
                // user.Config.OAuth2Mode = OAuth2Flow.APPLICATION;
                // OAuth2ProviderForApplications oAuth =
                //     (user.OAuthProvider as OAuth2ProviderForApplications);
                // oAuth.RefreshToken = xxx;
                // oAuth.AccessToken = xxx;
                // oAuth.UpdatedOn = xxx;
                // oAuth.ExpiresIn = xxx;
                //
                // Note that only oAuth.RefreshToken is mandatory. If you leave
                // oAuth.AccessToken as empty, or if oAuth.UpdatedOn + oAuth.ExpiresIn
                // is in the past, the access token will be refreshed by the library.
                // You can listen to this event as
                //
                // oAuth.OnOAuthTokensObtained += delegate(AdsOAuthProvider provider) {
                //    OAuth2ProviderForApplications oAuth =
                //        (provider as OAuth2ProviderForApplications);
                //    // Save oAuth.RefreshToken, oAuth.AccessToken, oAuth.UpdatedOn and
                //    // oAuth.ExpiresIn.
                //};
                Session["OAuthProvider"] = oAuth;
                OAuth = oAuth;
                var t = Session["OAuthProvider"];
                // Redirect the user to the main page.
                Response.Redirect("Index");
            }
            else
            {
                throw new Exception("Unknown state for OAuth callback.");
            }
        }

Reporting controller:
[HttpPost]
        public ActionResult Index(string customerId)
        {
            var test = customerId;

            ConfigureUserForOAuth();

            CampaignService campaignService = (CampaignService)_user.GetService(AdWordsService.v201603.CampaignService);

            (_user.Config as AdWordsAppConfig).ClientCustomerId = customerId;

            // Create the selector.
            Selector selector = new Selector()
            {
                fields = new string[] {
          Campaign.Fields.Id, Campaign.Fields.Name, Campaign.Fields.Status
        },
                paging = Paging.Default
            };

            CampaignPage page = new CampaignPage();

            try
            {
                do
                {
                    // Get the campaigns.
                    page = campaignService.get(selector);

                    // Display the results.
                    if (page != null && page.entries != null)
                    {
                        int i = selector.paging.startIndex;
                        foreach (Campaign campaign in page.entries)
                        {
                            Console.WriteLine("{0}) Campaign with id = '{1}', name = '{2}' and status = '{3}'" +
                              " was found.", i + 1, campaign.id, campaign.name, campaign.status);
                            i++;
                        }
                    }
                    selector.paging.IncreaseOffset();
                } while (selector.paging.startIndex < page.totalNumEntries);
                Console.WriteLine("Number of campaigns found: {0}", page.totalNumEntries);
            }
            catch (Exception e)
            {
                throw new System.ApplicationException("Failed to retrieve campaigns", e);
            }

            return null;
        }

        private void ConfigureUserForOAuth()
        {
            AdWordsAppConfig config = (_user.Config as AdWordsAppConfig);
            if (config.OAuth2Mode == OAuth2Flow.APPLICATION &&
                  string.IsNullOrEmpty(config.OAuth2RefreshToken))
            {
                var t = Session["OAuthProvider"];
                var n = OAuth;
                //_user.OAuthProvider = (OAuth2ProviderForApplications)Session["OAuthProvider"];
                _user.OAuthProvider = OAuth;
            }
        }

Umesh Dengale

unread,
May 11, 2016, 1:55:04 PM5/11/16
to AdWords API Forum
Hello,

Could you please provide SOAP XML request and response logs for above API call? Just click Reply privately to author in the forum when responding.

Thanks,
Umesh Dengale, AdWords API Team.

Martin Tierney

unread,
May 11, 2016, 2:17:54 PM5/11/16
to AdWords API Forum
Hi,

Thanks for the reply and sorry if this is a stupid question but I am new to the adwords api and i can't find in the docs how to capture the soap logs.
Please can you tell me how to do this in .net?

thanks a lot

Umesh Dengale

unread,
May 11, 2016, 2:34:58 PM5/11/16
to AdWords API Forum
Hello,

You could enable the logs for .NET client library by following these instructions.

Thanks,
Umesh, AdWords API Team.

Martin Tierney

unread,
May 11, 2016, 4:38:11 PM5/11/16
to AdWords API Forum
Hi 

thanks again for the fast reply, getting the soap log was massively helpful.

so it looks like the clientcustomerid is not being set correctly, it was still the management account number and not the actual account number.
I am setting this by;

(_user.Config as AdWordsAppConfig).ClientCustomerId = customerId;

do you have any idea why this is being reset?

thanks

Umesh Dengale

unread,
May 11, 2016, 5:25:27 PM5/11/16
to AdWords API Forum
Hello,

Could you please check your application config file (App.config) for clientCustomerId?

Regards,
Umesh, AdWords API Team.

Martin Tierney

unread,
May 11, 2016, 5:44:10 PM5/11/16
to AdWords API Forum
Thanks a LOT Umesh, you are my new favourite person.

I needed to remove the customer id from my web config, I also needed to set the customer id before the campaign service was created, not just before the get call.
Reply all
Reply to author
Forward
0 new messages