Google Drive upload fails - c#

I have a method that checks if my file exists on the drive and if not, it uploads one and adds permission.
This method worked while testing the first time and Update requests worked on the file to.
After deleting all existing files in my drive the upload stopped working, the responsebody is null and if I look at it in viddler the requestbody is also empty.
(the file is a valid docx)
I am using the following code:
DriveService service = Google_SDK.Authentication.AppFlowMetadata.BuildServerDriveService();
Google.Apis.Drive.v2.Data.File file;
var items = service.Files.List().Execute().Items.ToLookup(a => a.OriginalFilename = doc.Name + " (" + doc.Id + ".docx)");
if (items.Count > 0)
{
// This worked while testing:
//string fileId = items.FirstOrDefault().FirstOrDefault().Id;
//FilesResource.UpdateRequest uploadRequest = service.Files.(body, fileId, stream, "application/vnd.google-apps.document");
//uploadRequest.Convert = true;
//uploadRequest.Upload();
file = items.FirstOrDefault().FirstOrDefault();
}
else
{
Google.Apis.Drive.v2.Data.File body = new Google.Apis.Drive.v2.Data.File();
body.Title = doc.Name + " (" + doc.Id + ".docx)";
body.OriginalFilename = doc.Name + " (" + doc.Id + ".docx)";
body.Editable = true;
body.Shared = false;
body.WritersCanShare = false;
body.Copyable = false;
body.Description = doc.Notes;
body.MimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
byte[] byteArray = doc.DocxContent; // valid byteArray
System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
FilesResource.InsertMediaUpload uploadRequest = service.Files.Insert(body, stream, "application/vnd.google-apps.document");
uploadRequest.Convert = true;
uploadRequest.Upload();
file = uploadRequest.ResponseBody; // No errors or exceptions but returns null
PermissionsResource.InsertRequest permissionRequest = service.Permissions.Insert(new Permission()
{
Role = "writer",
Type = "user",
EmailAddress = "user#domain.com",
Value = "user#domain.com"
}, file.Id); // file.Id fails becase file equals null
permissionRequest.Execute();
}
I really do not see what I am doing wrong and why this worked the first time.
Thank you in advance.
Edit:
I've been debugging some other parts of my project and I found out that the changes still exist, this seems logical that any deletion is saved as a change for version controll.
Maybe that has something to do with my problems?
Also I forgot to mention that the deletion of all the files is done by code and the drive used is not a gmail account but an *.apps.googleusercontent.com account.
The code I used to remove all the files:
DriveService service = Google_SDK.Authentication.DriveServiceProvider.Service;
FilesResource.ListRequest listRequest = service.Files.List();
FileList listResponse = listRequest.Execute();
int amount = listResponse.Items.Count();
foreach(Google.Apis.Drive.v2.Data.File f in listResponse.Items.AsQueryable()){
FilesResource.DeleteRequest deleteRequest = service.Files.Delete(f.Id);
deleteRequest.Execute();
}
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(String.Format("Removed {0} items.",amount));
return response;
Edit 2:
I've created a completely new document in my system and tried uploading it to the google drive. This was succesfull! After deleting the new document from the drive I got the same behavior as described above, an empty responsebody while uploading.
So even though I removed the old document it still recognizes that it is the same document that used to be on the drive.
Does somebody know a way to prevent this?

Related

Google Document AI c# mime Unsupported input file format

I am trying to upload a pdf for processing to google's Document AI service. Using google's using Google.Cloud.DocumentAI.V1 for "C#". Looked at the github and docs, not much info. PDF is on the local drive. I converted the pdf to a byte array then converted that to a Bystring. Then set the request mime to "application/pdf" but it return was an error of:
Status(StatusCode="InvalidArgument", Detail="Unsupported input file format.", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"#1627582435.256000000","description":"Error received from peer ipv4:142.250.72.170:443","file":"......\src\core\lib\surface\call.cc","file_line":1067,"grpc_message":"Unsupported input file format.","grpc_status":3}")
Code:
try
{
//Generate a document
string pdfFilePath = "C:\\Users\\maponte\\Documents\\Projects\\SettonProjects\\OCRSTUFF\\DOC071621-0016.pdf";
var bytes = Encoding.UTF8.GetBytes(pdfFilePath);
ByteString content = ByteString.CopyFrom(bytes);
// Create client
DocumentProcessorServiceClient documentProcessorServiceClient = await DocumentProcessorServiceClient.CreateAsync();
// Initialize request argument(s)
ProcessRequest request = new ProcessRequest
{
ProcessorName = ProcessorName.FromProjectLocationProcessor("*****", "mycountry", "***"),
SkipHumanReview = false,
InlineDocument = new Document(),
RawDocument = new RawDocument(),
};
request.RawDocument.MimeType = "application/pdf";
request.RawDocument.Content = content;
// Make the request
ProcessResponse response = await documentProcessorServiceClient.ProcessDocumentAsync(request);
Document docResponse = response.Document;
Console.WriteLine(docResponse.Text);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
This is the problem (or at least one problem) - you aren't actually loading the file:
string pdfFilePath = "C:\\Users\\maponte\\Documents\\Projects\\SettonProjects\\OCRSTUFF\\DOC071621-0016.pdf";
var bytes = Encoding.UTF8.GetBytes(pdfFilePath);
ByteString content = ByteString.CopyFrom(bytes);
You instead want:
string pdfFilePath = "path-as-before";
var bytes = File.ReadAllBytes(pdfFilePath);
ByteString content = ByteString.CopyFrom(bytes);
I'd also note, however, that InlineDocument and RawDocument are alternatives to each other - specifying either of them removes the other. Your request creation would be better written as:
ProcessRequest request = new ProcessRequest
{
ProcessorName = ProcessorName.FromProjectLocationProcessor("*****", "mycountry", "***"),
SkipHumanReview = false,
RawDocument = new RawDocument
{
MimeType = "application/pdf",
Content = content
}
};

How to upload file to (shared drive) with google api v3?

How to upload file or folder to (shared drive) with google api v3 by c# ?
I tried this but not working, still uploaded in my drive not shared drive
var Folder = new Google.Apis.Drive.v3.Data.File()
{
Name = fName,
MimeType = "application/vnd.google-apps.folder",
DriveId=driveID
};
Google.Apis.Drive.v3.Data.File result = new Google.Apis.Drive.v3.Data.File();
var request = service.Files.Create(Folder);
request.Fields = "name,id,webViewLink";
request.SupportsAllDrives = true;
result = request.Execute();
Console.WriteLine("'" + Folder.Name + "' folder created");
I wrote Parents = new List<string> { driveID }
instead of DriveId=driveID and it worked

How to generate stream to save Word document at remote location?

I am working on Word AddIn project. I am trying to generate a MmoryStream to save that stream to remote location. Basically What I am supposed to do is take the content of ActiveDocument by using Globals.ThisAddIn.Application.ActiveDocument.WordOpenXML and save it at remote location.
Now for that I am converting this entire string which I am getting with WordOpenXML property to MemoryStream by this code.
After that, I am passing this MemoryStream to HttpContent and for that I have written below code.
public async Task<HttpResponseMessage> PostDocumentAsync(SendAttachement sendAttachement)
{
if (sendAttachement == null)
{
throw new ArgumentNullException(nameof(sendAttachement));
}
using (var _client = new HttpClient(clientHandler, false))
{
_client.Timeout = new TimeSpan(0, 30, 0);
_client.BaseAddress = _URLParams.HostName;
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Add("UserNameOrEmail", Settings.Default.UserName);
_client.DefaultRequestHeaders.Add("Password", Settings.Default.Password);
_client.DefaultRequestHeaders.Add("User-Agent", "Word-Addins");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
MultipartFormDataContent form = new MultipartFormDataContent();
foreach (var contentItem in sendAttachement.Contents)
{
HttpContent content = contentItem.streamContent;
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = contentItem.FileName
};
form.Add(content);
}
var uri = _URLParams.APIPath + "/" + _URLParams.AbsolutePath + "?ClientId=" + sendAttachement.ClientId + "&RoomId=" + sendAttachement.RoomId + "&FolderId=" + sendAttachement.FolderId + "&ConflictStatus=" + sendAttachement.ConflictStatus;
return await _client.PostAsync(uri, form);
}
}
Above code gives me 200 OK but as I download the uploaded file, It gives me error that Microsoft Word cannot open this document because some part of this file is missing is invalid.
Now I am unable to figure out that Whether am I creating wrong/corrupted stream or anything else.
Sorry for this silly question but I have tried as much as possible solutions I could have done it.

HttpGet return error 405

Using ASP Web API, I create a method that takes an ID then deliver a pdf file, then using Google docs viewer, or similar service, to view the file,
The code looks something like this,
[HttpGet]
public HttpResponseMessage GetAttachment(string id)
{
try {
string mapping = #"\\192.168.3.3\Archieve";
string sourcedir = #"\Digital\";
string filename = id + ".pdf";
string sourceFullPath = mapping + sourcedir + filename;
byte[] dataBytes = new byte[0];
// connect to other network using custom credential
var credential = new NetworkCredential("user", "pass", "192.168.3.3");
using (new NetworkConnection(mapping, credential)) {
dataBytes = File.ReadAllBytes(sourceFullPath);
}
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StreamContent(new MemoryStream(dataBytes));
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = filename;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return response;
}
catch (Exception ex) {
return Request.CreateResponse(HttpStatusCode.Gone, ex.Message);
}
}
With this code, I'm able to download the pdf file when I open the link on web browser, but when I try to display it using Google docs viewer, like this
https://docs.google.com/viewerng/viewer?url=http://myserver/webapi/api/File/GetAttachment/0317101532
Google failed to display the file without error,
And when I use other service like https://www.pdfescape.com/open/ the error is The remote server returned an error: (405) Method Not Allowed.
EDIT: I think both Google Docs viewer and pdfescape need direct link to the file, can I generate direct link on Web API controller?
Try to copy the file to local, and then return the file link, something like this
[HttpGet]
public IHttpActionResult GetAttachment(string id)
{
try {
string mapping = #"\\192.168.3.3\Archieve";
string sourcedir = #"\Digital\";
string filename = id + ".pdf";
string sourceFullPath = mapping + sourcedir + filename;
byte[] dataBytes = new byte[0];
// connect to other network using custom credential
var credential = new NetworkCredential("user", "pass", "192.168.3.3");
using (new NetworkConnection(mapping, credential)) {
dataBytes = File.ReadAllBytes(sourceFullPath);
}
// write file to local
string destFullPath = string.Format("{0}/Content/Data//{2}", HttpContext.Current.Server.MapPath("~"), filename);
File.WriteAllBytes(destFullPath, dataBytes);
// return the file name,
return Ok(filename);
// then you can view your docs using Google Viewer like this
// https://docs.google.com/viewer?url=http://[YOUR_SERVER_BASE_URL]/content/data/[FILENAME]
}
catch (Exception ex) {
return Content(HttpStatusCode.PreconditionFailed, ex.Message);
}
}
Don't forget to add required permission on 'Content' folder

can't replace file in amazon s3 bucket

can't replace file in amazon s3 bucket
when i am going to upload an image to amazon s3 bucket it shows error like below
An item with the same key has already been added.
i have uploaded an image file and i wanted replace that image when i need it. but it does not allow.
how can I fix it?
i am using C#
using (s3Client = Amazon.AWSClientFactory.CreateAmazonS3Client("key", "secret key", Amazon.RegionEndpoint.USWest2))
{
var stream2 = new System.IO.MemoryStream();
bitmap.Save(stream2, ImageFormat.Jpeg);
stream2.Position = 0;
PutObjectRequest request2 = new PutObjectRequest();
request2.InputStream = stream2;
request2.BucketName = "ezcimassets";
request2.CannedACL = S3CannedACL.PublicRead;
fileName = webpage + ".jpeg";
//fileName = Guid.NewGuid() + webpage + ".jpeg";)
request2.Key = "WebThumbnails/" + fileName;
Amazon.S3.Model.PutObjectResponse response = s3Client.PutObject(request2);
}
Thanks in advance
this line must be changed as
request2.CannedACL = S3CannedACL.PublicReadWrite
You can check if an object with that key already exists, and if so delete it:
public bool Exists(string fileKey, string bucketName)
{
try
{
response = _s3Client.GetObjectMetadata(new GetObjectMetadataRequest()
.WithBucketName(bucketName)
.WithKey(key));
return true;
}
catch (Amazon.S3.AmazonS3Exception ex)
{
if (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
return false;
//status wasn't not found, so throw the exception
throw;
}
}
public void Delete(string fileKey, string bucketName)
{
DeleteObjectRequest request = new DeleteObjectRequest();
request.BucketName = bucketName;
request.Key = fileKey;
client.DeleteObject(request);
}

Categories

Resources