I am attempting to use Google Drive as a storage location in my UWP application. I started at the quickstart provided by Google. I copy the code into a blank UWP project, change some of the output code (Console.Writeline to a textbox.append method) and I try to build it. It fails to build and reports the error:
Cannot find type System.ComponentModel.ExpandableObjectConverter in module System.dll
I am running Windows 10 and VS 2015 and I have installed the sdk through NuGet. The example code in the quickstart does work in a console application. It is the UWP application that is having issues.
For the UWP application, I put the quickstart code in a button click method. This was because the API actually has an async method for the uwp apps which is a bit different then the code given in the quickstart.
Includes:
using System;
using System.Collections.Generic;
using System.IO;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Drive.v3.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System.Threading;
The Button Method:
private async void button_Click(object sender, RoutedEventArgs e)
{
UserCredential credential;
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = ""; //System.Environment.GetFolderPath(
//System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/drive-dotnet-quickstart.json");
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
new Uri("ms-appx:///Assets/client_secrets.json"),
Scopes,
"user",
CancellationToken.None);
//Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Drive API service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
FilesResource.ListRequest listRequest = service.Files.List();
listRequest.PageSize = 10;
listRequest.Fields = "nextPageToken, files(id, name)";
// List files.
IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute()
.Files;
textBox.Text += "Files:\n";
if (files != null && files.Count > 0)
{
foreach (var file in files)
{
textBox.Text += (file.Name + file.Id + "\n");
}
}
else
{
textBox.Text += ("No files found.");
}
}
The test code will not work once the app is compiled as it is missing the code to load the client secret. Since I have not been able to test the code, this is all I can provide.
There is another post that is semi-related except that the answer is just that it wont work and the post has been dead for 4 years. I also wanted to create a new post that tags the google team specifically (like the quickstart says to do).
My specific question is: Is there a work around to this issue or am I just doing this wrong?
I agree with #Vincent, UWP apps use COM as a base and builds from there. Not all .Net API can be used in UWP apps, this SDK is based on .Net APIs, this is why your console app is OK, but your UWP app is down. For the differences between them, here is a great answer which explain this issue. But,
"You will need an UWP SDK from Google to build an UWP applications."
I just tried to search for this without any luck, but here is a suggestion, you can use JavaScript to make request to the Drive API. To do this, you can refer to JavaScript Quickstart. Then you can turn it to a web hosted UWP app, for more information, you can refer to Convert your web application to a Universal Windows Platform (UWP) app.
Another suggestion which can probably make the work easier is using Rest API to send HTTP requests, you can also refer to API Reference.
The final suggestion which is as #Vincent said, if you have access to the SDK code, you can also try to adapt it for UWP. It means you need to modify the source code of this SDK.
The .Net flavor used to build Windows Store/UWP apps has less features than the full .Net framework. Unfortunately, the ExpandableObjectConverter object is not available for UWP applications.
You will need an UWP SDK from Google to build an UWP applications.
If you have access to the SDK code, you can also try to adapt it for UWP.
Related
I recently joined a team, and am adding Android Management Api to the already existing project. I added the management API, created service accounts with permissions, and am writing the .NET project to test it out.
I made a service account with Android Management User and Owner permissions. However, when I try to use the .NET library to make an enterprise, I get
The service androidmanagement has thrown an exception. HttpStatusCode is Forbidden. Caller is not authorized to manage project.
If it helps:
The API key I'm using is allowed to call any API, and the application name is a temporary one that does NOT match the project name. As for the service account with private key, I am using a FileStream to read a .json file downloaded when the service account was created.
This is my code, based on the sample app https://developers.google.com/android/management/sample-app
The error gets thrown on the createRequst.Execute()
string CreateEnterprise()
{
SignupUrlsResource.CreateRequest signupUrlRequest = managementService.SignupUrls.Create();
signupUrlRequest.ProjectId = cloud_project_id;
signupUrlRequest.CallbackUrl = "https://www.yahoo.com";
var signupUrl = signupUrlRequest.Execute();
string enterpriseToken = signupUrl.Url;
Console.WriteLine("Signup: " + enterpriseToken);
EnterprisesResource.CreateRequest createRequest = managementService.Enterprises.Create(new Enterprise());
createRequest.ProjectId = "Test Project";
createRequest.SignupUrlName = signupUrl.Name;
createRequest.EnterpriseToken = enterpriseToken;
var enterprise = createRequest.Execute();
return enterprise.Name;
}
Turns out the createRequest.ProjectId must match the project name that has the Android Management API, aka the project I'm working with.
I'm fighting with Google Docs for setting up Cloud PubSub with .NET using a PubSub emulator.
https://cloud.google.com/dotnet/docs/getting-started/using-pub-sub
https://cloud.google.com/pubsub/docs/publisher
https://cloud.google.com/pubsub/docs/emulator
Coming from a Rails background, I'm tasked to implement Cloud PubSub for a .NET product, running our google cloud on .NET Core, to enable it to publish.
Google::Cloud::Pubsub.new(project: project_id, emulator_host: emulator_host)
From the documentation using .NET, I keep coming back to the following:
PublisherServiceApiClient publisherClient = PublisherServiceApiClient.Create();
PublisherClient publisher = PublisherClient.Create(...)
However, the library used from the docs Google.Cloud.PubSub.V1 -Pre
does not contain the definition.
'PublisherClient' does not contain a definition for 'Create'.
Instead, I get CreateAsync that takes in TopicName, PublisherClient.ClientCreationSettings and PublisherClient.Settings.
https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.PubSub.V1/api/Google.Cloud.PubSub.V1.PublisherClient.html
I noticed that PublisherServiceApiClient can take in a Channel, but I'm confused on how to get this going.
To conclude with an actual question, how does one currently implement Cloud PubSub with .NET for in cloud and then locally with emulator? Adding to that, am I using the wrong library or the wrong docs?
Any suggestions, pointers or piece of advice would be truly appreciated.
I managed a solution that I am happy with.
Instead of using the PublisherClient, I went with using the PublisherServiceApiClient alone.
emulatorAddr = Environment.GetEnvironmentVariable("PUBSUB_EMULATOR_HOST");
if (emulatorAddr != null)
{
channel = new Channel(emulatorAddr, ChannelCredentials.Insecure);
pub = PublisherServiceApiClient.Create(channel);
}
else
{
pub = PublisherServiceApiClient.Create();
}
Which meant that publishing was slightly more involved then sending string to the PublisherClient, but overall not so bad.
PubsubMessage msg = new PubsubMessage
{
Data = ByteString.CopyFromUtf8(JsonConvert.SerializeObject(payload))
};
pub.PublishAsync(topic, new[]{ msg });
If the project is running in a Google Compute Engine, it will have default credentials. Otherwise, wether you're running an emulator locally or in docker you can define PUBSUB_EMULATOR_HOST.
What really helped was this https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.PubSub.V1/index.html
To make the PublisherClient connect to a local emulator, you need to pass custom ServiceEndpoint and ChannelCredentials to CreateAsync:
var serviceEndpoint = new ServiceEndpoint(theEmulatorHost, theEmulatorPort);
var publisherClient = await PublisherClient.CreateAsync(
topicName,
new PublisherClient.ClientCreationSettings(credentials: ChannelCredentials.Insecure, serviceEndpoint: serviceEndpoint));
To switch to the real PubSub, just leave away the ClientCreationSettings.
You can use the EmulatorDetection property on the ClientCreationSettings using extension method .WithEmulatorDetection(EmulatorDetection.EmulatorOrProduction). Like this:
PublisherClient publisher = await PublisherClient.CreateAsync(
topicName,
new PublisherClient.ClientCreationSettings()
.WithEmulatorDetection(EmulatorDetection.EmulatorOrProduction));
This will work if you have the following environment variable for the local emulator endpoint: PUBSUB_EMULATOR_HOST=localhost:8085
(If you use Visual Studio you might have to restart VS for the environment variable to be detected)
In windows I had problems using the set PUBSUB_EMULATOR_HOST=localhost:8085 command, so I ended up adding it manually.
Details here: https://cloud.google.com/pubsub/docs/emulator
Extra tip: you can add topics directly to API using curl: curl -X PUT http://localhost:8085/v1/projects/my-project-name/topics/my-topic
I'm new to Sharepoint online, and don't have an own account (yet), just an username/password from a client.
Need to build a service that gets the folder structure and archives from Sharepoint. And then allows to up/download archives.
Since the package
Microsoft.SharePointOnline.CSOM
is not compatible with .NET Core, I'm using this github solution that seems to cover the main functionality in an equal way: https://github.com/OneBitSoftware/NetCore.CSOM
I think there is nothing wrong with that so far - but when trying to connect using
SharePointOnlineCredentials
...I'm getting the error
PPCRL_REQUEST_E_PARTNER_HAS_NO_ASYMMETRIC_KEY
So I guess there's some account setting missing on the server side? Or am I following a wrong approach? I would have no problem implementing an OAuth access to get a Bearer token, but which API would that be, and how can I register an app for Sharepoint?
My research about API's and this particular error didn't result in anything yet, so I'm reaching out for help here.
Get NuGet package TTCUE.NetCore.SharepointOnline.CSOM.16.1.8029.1200.
You can also download an official package Microsoft.SharePointOnline.CSOM but it will attach wrong dlls to your project and you would need to change them according to the link from a different answer here - https://rajujoseph.com/getting-net-core-and-sharepoint-csom-play-nice/
Note - Your .NET Core project will compile, but it doesn't mean that it will work on, for example, linux. Those CSOM dlls are not finished and Microsoft is still working on them.(for a loooong time...)
Check the example below:
Create a .NET Core console app.
Add the references: Microsoft.SharePoint.Client.Portable.dll, Microsoft.SharePoint.Client.Runtime.Portable.dll, and Microsoft.SharePoint.Client.Runtime.Windows.dll.
Note: If the project has references to Microsoft.SharePoint.Client.dll and Microsoft.SharePoint.Client.Runtime.dll, please remove them.
These references can be accessed by installing CSOM library into another project, and then navigating to installed nuget packages in the file directory:
c:\Users\user\\.nuget\packages\microsoft.sharepointonline.csom\\(version)\lib\netcore45
Add the code below to the .NET Core 2.0 console application:
using System;
using Microsoft.SharePoint.Client;
namespace ConsoleApp1 {
class Program {
static void Main(string[] args) {
string targetSiteURL = #"https://xxx.sharepoint.com/sites/xxx";
var login = "xxx#xx.onmicrosoft.com";
var password = "xxx";
SharePointOnlineCredentials onlineCredentials = new SharePointOnlineCredentials(login, password);
ClientContext ctx = new ClientContext(targetSiteURL);
ctx.Credentials = onlineCredentials;
WebCreationInformation wci = new WebCreationInformation();
wci.Url = "Site1"; // This url is relative to the url provided in the context
wci.Title = "Site 1";
wci.UseSamePermissionsAsParentSite = true;
wci.WebTemplate = "STS#0";
wci.Language = 1033;
var newWeb = ctx.Web.Webs.Add(wci);
ctx.Load(newWeb, w => w.Title);
ctx.ExecuteQueryAsync();
Console.WriteLine("Web title:" + newWeb.Title);
Console.ReadKey();
}
}
}
More information: Getting .NET Core and SharePoint CSOM Play Nice
I am trying to download file from Google Drive using ASPSnippets.GoogleAP.dll and Google.Apis.Drive.v3.dll. But facing some challenges. File is being downloaded, but it is in some type of weird HTML content.
I am using following code to download it :
GoogleConnect.ClientId = "xxxx.apps.googleusercontent.com";
GoogleConnect.ClientSecret = "xxxxxx";
GoogleConnect.RedirectUri = Request.Url.AbsoluteUri.Split('?')[0];
GoogleConnect.API = EnumAPI.Drive;
if (!string.IsNullOrEmpty(Request.QueryString["code"]))
{
string code = Request.QueryString["code"];
string json = GoogleConnect.Fetch("me", code);
GoogleDriveFiles files = new JavaScriptSerializer().Deserialize<GoogleDriveFiles>(json);
//Remove the deleted files.
var driveService = new DriveService();
Label1.Text = theHiddenField1.Value;
WebClient wb = new WebClient();
wb.DownloadFile(theHiddenField1.Value, "C://" + fileName);
}
else if (Request.QueryString["error"] == "access_denied")
{
ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", "alert('Access denied.')", true);
}
else
{
GoogleConnect.Authorize("https://www.googleapis.com/auth/drive.readonly");
}
Can someone please help me to resolve the issue?
I'm not a C# developer, but if you're using Google.Apis.Drive.v3, then that is the latest version of the Google Drive API. I don't see any part of your code that references the Google APIs Client Library for .NET, but that's the recommended way to talk to modern Google APIs.
If you've installed it, take a look at the C# quickstart sample for the Drive API. Then check out the C#/.NET examples on the Download Files page in the docs, and it should lead you to a working solution. In your other comment, you asked about passing auth tokens, so if you're using the client library, you shouldn't have to worry about that part. On that docs page, you'll find a sample for regular file downloads and another for exporting Google documents (Docs, Sheets, Slides).
Finally, for additional reference, here are the .NET reference docs for the Drive API and the .NET Google APIs Client Library developers guide.
I have been attempting to upload files using c# into Hadoop using the WebHDFS REST API.
This code works fine:
using (var client = new System.Net.WebClient())
{
string result = client.DownloadString("http:/ /host:50070/webhdfs/v1/user/myuser/?op=LISTSTATUS");
client.DownloadFile("http:/ /host:50070/webhdfs/v1/user/myuser/tbible.txt?user.name=myuser&op=OPEN","d:\tbible.txt");
}
This code gets a 403 Forbidden:
using (var client = new System.Net.WebClient())
{
client.UploadFile("http:/ /host:50070/webhdfs/v1/user/myuser/?user.name=myuser&op=CREATE", "PUT", "d:\bible.txt");
}
I have tried adding a network credential, with no luck.
How do I authenticate to our Cluster from .NET? The Cluster is Hortonworks HDP1.3 on RHEL5.
(The extra spaces in this post are to keep http:/ / from being a link)
Also, I would have liked to use Microsoft's hadoop SDK, but it is alpha and wont compile in my environment :(
Make sure that you are writing to a directory that is under the group which WebHDFS operates under. By default this is hdfs.
A quick way to check this doing hadoop fs -ls on the directory's parent directory to get the group permission settings (the second column that may look like a username).