1
votes

I was able to upload a file to the Google Cloud Storage bucket with the following code. I created the bucket manually.

        String serviceAccountEmail = "xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com";

        var certificate = new X509Certificate2(@"C:\...\projectname-xxxxxxxxxxxx.p12", "notasecret", X509KeyStorageFlags.Exportable);
        var scopes = new[] { @"https://www.googleapis.com/auth/devstorage.full_control" };

        ServiceAccountCredential credential = new ServiceAccountCredential(
            new ServiceAccountCredential.Initializer(serviceAccountEmail)
            {
                Scopes = scopes
            }.FromCertificate(certificate));

        StorageService service = new StorageService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "Shipment Feed",
        });

        var bucketToUpload = "bucket-created-by-me";
        var newObject = new Google.Apis.Storage.v1.Data.Object()
        {
            Bucket = bucketToUpload,
            Name = "ShipmentFeed.txt"
        };


        FileStream fileStream = null;
        var path = @"C:\...\file.txt";
        fileStream = new FileStream(path, FileMode.Open);
        var uploadRequest = new ObjectsResource.InsertMediaUpload(service, newObject,
           bucketToUpload, fileStream, "text/plain");
        uploadRequest.Upload();

Now I ran into the problem when I tried to upload the file to the bucket, generated by Google Merchant Center, for the same Google account. I used the code above by simply changing the bucket name to the value provided by the Google Merchant center from Settings->Google Cloud Storage

var bucketToUpload = "merchantxxxxxxx";

This procedure did not get the file uploaded to the bucket (tested with gsutil - bucket exists in my project but is empty). Why can't I upload the file?

1
What error do you get back, a 403? If so, you probably need to change the bucket's ACL to grant write permissions to the service account.Travis Hobrla
I was not able to trace whether I get back a response for my service account request - could you give me a hint on how to do that?Artem S
You are running the code above, yes? Do you get an exception or a return value from .Upload()? You could also configure gsutil to use the service account with "gsutil config -e"Travis Hobrla

1 Answers

1
votes

Your code does not authorize the access to Google Cloud Storage. After you create ServiceAccountCredential, you must get Access Token by calling:

 ServiceAccountCredential sac = new ServiceAccountCredential(
            new ServiceAccountCredential.Initializer(serviceAccountEmail)
            {
                Scopes = scopes
            }.FromCertificate(certificate));
 var cts = new CancellationToken();
 var response = sac.RequestAccessTokenAsync(cts).Result;

If the response is true, your ServiceAccountCredential object will have ServiceAccountCredential.Token.AccessToken set.

Then, when you create your uploadRequest, you must provide the AccessToken you obtained:

var uploadRequest = new ObjectsResource.InsertMediaUpload(service, newObject,
       bucketToUpload, fileStream, "text/plain");

uploadRequest.OauthToken = sac.Token.AccessToken;

And finally call:

uploadRequest.Upload();