Google AdWords library doesn't create an access token - c#

I'm trying to make a targetingIdeaService API call to Google AdWords. This is my code so far:
[HttpGet]
public IEnumerable<string> Get()
{
var user = new AdWordsUser();
using (TargetingIdeaService targetingIdeaService = (TargetingIdeaService)user.GetService(AdWordsService.v201802.TargetingIdeaService))
{
// Create selector.
TargetingIdeaSelector selector = new TargetingIdeaSelector();
selector.requestType = RequestType.IDEAS;
selector.ideaType = IdeaType.KEYWORD;
selector.requestedAttributeTypes = new AttributeType[] {
AttributeType.KEYWORD_TEXT,
AttributeType.SEARCH_VOLUME,
AttributeType.AVERAGE_CPC,
AttributeType.COMPETITION,
AttributeType.CATEGORY_PRODUCTS_AND_SERVICES
};
// Set selector paging (required for targeting idea service).
var paging = Paging.Default;
// Create related to query search parameter.
var relatedToQuerySearchParameter =
new RelatedToQuerySearchParameter
{ queries = new String[] { "bakery", "pastries", "birthday cake" } };
var searchParameters = new List<SearchParameter> { relatedToQuerySearchParameter };
var page = new TargetingIdeaPage();
page = targetingIdeaService.get(selector);
return new string[] { "value1", "value2" };
}
}
it looks ok, compiles at last, and so on. But then I went into debug mode. And I saw this:
So as you can see, the variable doesn't have the access token. The other data comes from app.config file.
I am quite certain the keys passed in are correct.
Then the code throws the famous invalid_grand error. In my case, I believe that's because the access token is not being generated. I'm new to AdWords and ASP.NET, so I probably missed something, but I have no idea what.
I used the
docs,
Code Structure instructions, and
code examples to put it all together.

I had my configuration wrong. I had to recreate all the credentials using incognito window. If you have any issues just open a thread here: https://groups.google.com/forum/#!forum/adwords-api

Related

Error querying the Rally API - DynamicJsonObject does not contain a definition for 'Errors'

I'm trying to query the search API of Rally, here is my c# code:
var searchRequest = new Request()
{
ArtifactName = "search",
Limit = 25,
Project = "/project/" + CurrentProject,
ProjectScopeDown = true,
ProjectScopeUp = true,
PageSize = 25,
Fetch = new List<string>() { "true" }
};
searchRequest.AddParameter("keywords", "foo");
QueryResult queryTaskResult = api.Query(searchRequest);
this works as expected and returns result, however i want to pass a parameter of compact=true, which will return slightly different data (mainly a standard web link to the item).
var searchRequest = new Request()
{
ArtifactName = "search",
Limit = 25,
Project = "/project/" + CurrentProject,
ProjectScopeDown = true,
ProjectScopeUp = true,
PageSize = 25,
Fetch = new List<string>() { "true" }
};
searchRequest.AddParameter("keywords", "foo");
///this is the new item
searchRequest.AddParameter("compact", "true");
QueryResult queryTaskResult = api.Query(searchRequest);
However when i fire this request I get the following error
Rally.RestApi.Json.DynamicJsonObject' does not contain a definition for 'Errors'
However when I try to do this request in the browser it works fine.
Any help as to what I'm doing wrong would be greatly appreciated!
Why do you want to do this?
What I want to do is build up a link to the WEB view of the object, eg:
https://rally1.rallydev.com/#/{CurrentProject}d/detail/{ObjectType}/{ObjectId}
I already know the CurrentProject, I need to know the ObjectType and the ObjectId
I have found, when i pass compact=true, the _ref provides this, '/defect/1234567' but this throws an exception.
If I do not pass compact=true, the _ref returns the API reference 'https://rally1.rallydev.com/slm/webservice/v2.x/defect/1234567'
Unfortunately the compact functionality was added to WSAPI after the .NET toolkit was created and we've never updated it to support it.
I filed a github issue here: https://github.com/RallyTools/RallyRestToolkitFor.NET/issues/37
compact=true was mainly a performance optimization to reduce the size of responses in large result sets.
Other than performance is there a reason you'd like to use it?

NetSuite SuiteTalk TransactionSearchAdvanced: recordList equals null

I have a small C# console application who's sole purpose is to receive records from a "Saved Search" in NetSuite(via SuiteTalk). I've been able to successfully connect and receive records from NetSuite for my Saved Search(the search runs fine through the web interface too), however when I attempt to access the results of the "Saved Search" through my application, I am unable to view them because the search object that is returned does not contain any data in the "recordList" property:
//Connect
var dataCenterAwareNetSuiteService = new DataCenterAwareNetSuiteService("XXXXXX");
dataCenterAwareNetSuiteService.Timeout = 1000 * 60 * 60 * 2;
//Adds Credentials etc...
dataCenterAwareNetSuiteService.tokenPassport = createTokenPassport();
//Setup Preferences
var prefs = new Preferences();
prefs.warningAsErrorSpecified = true;
prefs.warningAsError = false;
dataCenterAwareNetSuiteService.preferences = prefs;
var searchPrefs = new SearchPreferences();
dataCenterAwareNetSuiteService.searchPreferences = searchPrefs;
dataCenterAwareNetSuiteService.searchPreferences.pageSize = 5;
dataCenterAwareNetSuiteService.searchPreferences.pageSizeSpecified = true;
dataCenterAwareNetSuiteService.searchPreferences.bodyFieldsOnly = false;
dataCenterAwareNetSuiteService.searchPreferences.returnSearchColumns = false;
//Search
var tranSearchAdv = new TransactionSearchAdvanced();
var tranSearchRow = new TransactionSearchRow();
var tranSearchRowBasic = new TransactionSearchRowBasic();
tranSearchAdv.savedSearchId = "XXXX";
tranSearchRowBasic.internalId =
new SearchColumnSelectField[] { new SearchColumnSelectField() };
tranSearchRowBasic.tranId =
new SearchColumnStringField[] { new SearchColumnStringField() };
tranSearchRowBasic.dateCreated =
new SearchColumnDateField[] { new SearchColumnDateField() };
tranSearchRowBasic.total =
new SearchColumnDoubleField[] { new SearchColumnDoubleField() };
tranSearchRowBasic.entity =
new SearchColumnSelectField[] { new SearchColumnSelectField() };
tranSearchRow.basic = tranSearchRowBasic;
tranSearchAdv.columns = tranSearchRow;
//No errors,
//this works correctly and returns the "Saved Search" with the correct "totalRecords"
//but results.recordList == null while results.totalRecords = 10000000+
var results = dataCenterAwareNetSuiteService.search(tranSearchAdv);
I appears to me that the "recordList" object is the principal way data is retrieved from the results of a search(Related Java Example, Another Here). This is also the way the example API does it.
I have run this on multiple "Saved Search's" with the same results. I don't understand how you can have more than one record in "totalRecords" and yet the "recordList" remains null? Is there some configuration option that has to be set to allow me to access this property. Or maybe it's a security thing, the API user I have setup should have full access, is there anything else that need to be granted access?
NetSuite SuiteTalk is not well documented, and most of the examples online are not in C#, and not dealing with the issues that I'm experiencing. These factors make it very difficult to determine why the previously mentioned behavior is occurring, or even, to discover any alternative methods for retrieving the resulting data from the source "Saved Search".
Does anyone have any insight into this behavior? Is this the correct method of retrieving results from SuiteTalk? Is there any configuration from the API or Web Side that needs to be changed?
Update 1
I've also tried using the alternative way of getting result data by accessing the "searchRowList" object from the "SearchResult" object(suggested by #AdolfoGarza) However it returns mostly empty fields(null) similar to the "recordList" property I do not see a way to retrieve "Saved Search" data from this method.
Try getting the results with results.searchRowList.searchRow , thats how it works in php.
I was able to resolve the issue by removing this line in the code:
tranSearchRow.basic = tranSearchRowBasic;
Then like #AdolfoGarza reccomended, retrieving the results from "basic" field in "results.searchRowList"
For some reason the template API that I was using was setting up a "TransactionSearchAdvanced" referencing a blank "TransactionSearchBasic" record, not sure why but this was causing the results from "searchRowList" to be null. After removing it I now get non-null values in the proper fields.
As for "recordList", it's still null, not sure why, but as I have my data I don't think I'll continue to dig into this.

Unable to create Azure WebSpace

I'm trying to create a new Website using the nuget package Microsoft.WindowsAzure.Management.WebSites (Version 3.0.0)
This tutorial has been helpful (even though its Java):
http://azure.microsoft.com/fi-fi/documentation/articles/java-create-azure-website-using-java-sdk/
except it suggests to use the WebSpaceNames.WestUSWebSpace constant.
var hostingPlanParams = new WebHostingPlanCreateParameters
{
Name = this.webhostingPlanName,
NumberOfWorkers = 1,
SKU = SkuOptions.Free,
WorkerSize = WorkerSizeOptions.Small
};
var result = new WebSiteManagementClient(this.Credentials)
.WebHostingPlans
.CreateAsync(WebSpaceNames.WestUSWebSpace, hostingPlanParams, CancellationToken.None)
.Result
This will result in an exception: NotFound: Cannot find WebSpace with name westuswebspace.
I actually want to create a custom WebSpace.
Except I can't find any method for it. See MSDN
So the only way I can make this work is using an existing WebSpace, that had created through the manage.windowsazure.com site. Which defeats the whole purpose of automating this.
The only Create[...] Method on IWebSpaceOperations is CreatePublishingUserAsync which I have tried running this as well but it results in an exception This operation is not supported for subscriptions that have co-admins. Which is pretty annoying in itself, doesn't make much sense to me, but is not really the core of my question.
I resolved this by using the prerelease package: PM> Install-Package Microsoft.Azure.Management.WebSites -Pre
Which works perfectly well. Except that it's only a pre-release of cause
// Create Web Hosting Plan
var hostingPlanParams = new WebHostingPlanCreateOrUpdateParameters
{
WebHostingPlan = new WebHostingPlan()
{
Name = "WebHostingPlanName",
Location = "Australia Southeast",
Properties = new WebHostingPlanProperties
{
NumberOfWorkers = 1,
Sku = SkuOptions.Standard,
WorkerSize = WorkerSizeOptions.Small
}
},
};
var result = this.ManagementContext.WebSiteManagementClient.WebHostingPlans.CreateOrUpdateAsync(
"ResourceGroupName",
"WebHostingPlanName",
CancellationToken.None).Result;
// Create Website
var websiteParams = new WebSiteCreateOrUpdateParameters
{
WebSite = new WebSiteBase
{
Location = "Australia Southeast",
Name = "WebSiteName",
Properties = new WebSiteBaseProperties
{
ServerFarm = "WebHostingPlanName"
}
}
};
var siteResult = this.ManagementContext.WebSiteManagementClient.WebSites.CreateOrUpdateAsync(
"ResourceGroupName",
"WebSiteName",
null,
websiteParams,
CancellationToken.None).Result;
If you want to use deployment slots you have to take this under consideration:
https://github.com/Azure/azure-sdk-for-net/issues/1088

How does one connect to the RootDSE and/or retrieve highestCommittedUSN with System.DirectoryServices.Protocols?

Using System.DirectoryServices, one can get the highestCommittedUSN this way:
using(DirectoryEntry entry = new DirectoryEntry("LDAP://servername:636/RootDSE"))
{
var usn = entry.Properties["highestCommittedUSN"].Value;
}
However, I need to get this information from a remote ADLDS using System.DirectoryServices.Protocols, which does not leverage ADSI. Following is a simplified code sample of what I'm attempting to do:
using(LdapConnection connection = GetWin32LdapConnection())
{
var filter = "(&(highestCommittedUSN=*))";
var searchRequest = new SearchRequest("RootDSE", filter, SearchScope.Subtree, "highestCommittedUSN");
var response = connection.SendRequest(searchRequest) as SearchResponse;
var usn = response.Entries[0].Attributes["highestCommittedUSN"][0];
}
Unfortunately this kicks back a "DirectoryOperationException: The distinguished name contains invalid syntax." At first I thought there might be something wrong in GetWin32LdapConnection() but that code is called in numerous other places to connect to the directory and never errors out.
Any ideas?
Thanks for the idea, Zilog. Apparently to connect to the RootDSE, you have to specify null for the root container. I also switched the filter to objectClass=* and the search scope to "base." Now it works!
using(LdapConnection connection = GetWin32LdapConnection())
{
var filter = "(&(objectClass=*))";
var searchRequest = new SearchRequest(null, filter, SearchScope.Base, "highestCommittedUSN");
var response = connection.SendRequest(searchRequest) as SearchResponse;
var usn = response.Entries[0].Attributes["highestcommittedusn"][0];
}
I hope this saves someone else some time in the future.

CanvasAuthorize C# SDK Infinite Loop

I'm looking to try and get an MVC3 Canvas app working with the Facebook C# SDK, but am struggling to allow permissions - Below is my code, and when I open the app I get the 'Allow / Deny' dialog but when I click allow I get redirected to my app and the same dialog appears again (And again and so on no matter how many times I click allow)?
I guess I am missing something obvious... If I take the user_groups permission out it works fine, I just can't access the persons groups.
[CanvasAuthorize(Permissions = "user_groups")]
public class HomeController : Controller
{
public ActionResult Index()
{
IFacebookApplication settings = FacebookApplication.Current;
if (settings != null)
{
//CanvasPage = settings.CanvasPage;
//AppId = settings.AppId;
}
FacebookWebContext facebookContext = FacebookWebContext.Current;
FacebookSignedRequest signedRequest = facebookContext.SignedRequest;
var client = new FacebookWebClient(facebookContext.AccessToken);
dynamic me = client.Get("me");
var friends = client.Get("me/friends");
var groups = client.Get("me/groups");
ViewBag.Name = me.name;
ViewBag.Id = me.id;
JavaScriptSerializer sr = new JavaScriptSerializer();
var fbFriends = sr.Deserialize<FBFriends>(friends.ToString());
ViewData["friends"] = fbFriends.data;
return View("Friends");
}
}
Any help, tips or code samples greatly appreciated.
make sure u have set the appid and appsecret correctly.
download the source code and checkout the "samples" folder, there are a bunch of asp.net mvc samples.

Categories