https://forge.autodesk.com/en/docs/bim360/v1/tutorials/documen-management/upload-document/
I am following the tutorial above to upload a file into a BIM 360 folder through Autodesk Forge. I have reached Step 6: Upload the File to the Storage Object and I am trying to use the method UploadObjectAsync() to upload a file but I am getting an error stating: error getting value from 'ReadTimeout' on 'System.Web.HttpInputStream' and I am unsure how to fix this.
Am I using the wrong method or there something I am missing in the code? Below is the method I am using on .NET.
HttpPostedFile file = req.Files[0];
ObjectsApi objectsApi = new ObjectsApi();
dynamic objects = await objectsApi.UploadObjectAsync(bucketKey, objectName, file.ContentLength, file.InputStream);
Try use the underlying stream of a StreamReader from the file to upload, instead of the raw InputStream from multipart form:
using (StreamReader streamReader = new StreamReader(fileSavePath))
{
await objects.UploadObjectAsync(bucketKey, objectName,(int)streamReader.BaseStream.Length, streamReader.BaseStream, "application/octet-stream");
...
}
Given how the UploadObjectAsync and its chained method UploadObjectAsyncWith(code here) is implemented you'd better saved the posted file and then upload it instead of piping streams. See an example here.
Related
I am writing a discord bot using DSharp plus library.
The command I am currently writing gets an image from the discord chat I then edit the image and send the edited image back as a single frame gif.
I retrieve the image from the image url by using:
HttpClient client = new HttpClient();
Stream stream = await client.GetStreamAsync(attachments[0].Url);
Bitmap image = new Bitmap(System.Drawing.Image.FromStream(stream));
I then call my edit function and edit the image. I then save the image to my files using:
using (var stream = new FileStream("Images/output.gif", FileMode.Create))
{
imgToGif.SaveAsGif(stream);
}
where .SaveAsGif() is a function from the KGySoft.Drawing library I found online.
To send the edited image back I use:
FileStream file = new FileStream("Images/output.gif", FileMode.Open);
DiscordMessageBuilder messagefile = new DiscordMessageBuilder();
messagefile.AddFile(file);
ctx.RespondAsync(messagefile);
But this throws a "The process cannot access the file "Image/output.gif" because it is being used by another process." error.
After some googling I tried to close the FileStream which saves my image to my files using stream.close() or stream.dispose(). The problem however is that I cannot acces the stream again because it will throw the "Cannot acces closed stream error".
I also tried using FileShare.read, FileShare.ReadWrite.
Tried closing both stream and tried to use 1 stream only. So I kept the stream open and used it to send the message in discord chat but that would send a file with 0 bytes in the discord chat.
I think you closed the stream too early while sending the gif
you need to call file.Close() after you call RespondAsync() and you need to change ctx.RespondAsync(messagefile); to await ctx.RespondAsync(messagefile); because RespondAsync() is an asynchronous method if you dont use await rest of the code will continue running so the stream will close while ctx.RespondAsync(messagefile); is still running and it will give an error.
sending a gif part should look like this:
FileStream file = new FileStream("Images/output.gif", FileMode.Open);
DiscordMessageBuilder messagefile = new DiscordMessageBuilder();
messagefile.AddFile(file);
await ctx.RespondAsync(messagefile);
file.Close();
if you have done the rest of the code correct this should work.
I was trying to convert .docx file to .pdf using drive api, which sounds reasonable since you can do it manually.
Here is my code:
FilesResource.CreateMediaUpload request;
using (var stream = new System.IO.FileStream(#"test.docx",
System.IO.FileMode.Open))
{
request = driveService.Files.Create(
fileMetadata, stream, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
request.Fields = ""id, webViewLink, webContentLink, size";
var x = request.Upload();
Console.WriteLine(x);
}
var file = request.ResponseBody;
Afterwards, I am getting id of this file and trying to do:
var downloadRequest = driveService.Files.Export(file.Id, "application/pdf");
which fails with error: "Export only supports Google Docs"
Ofc! I suppose it hasn't yet become "Google DOC", however, this format is supported for conversion as mentioned here and here.
Ok, I've noticed if you go to the drive and open the file manually it will become google doc file and also will get new ID. The export on this ID will work just fine. However, doing something manually isn't acceptable approach for our needs.
Tried another approach, you can use direct link with &export=pdf parameter to convert google doc file.
https://docs.google.com/document/d/FILE_ID/export?format=doc
But passing FILEID to that link doesn't work in this case(works with "DOC" file just fine) Tried doing something similiar to stackoverflow answer. No way.
So. Is there any way to trigger File to become Google DOC and wait till it converts? Is there any other way?
Thanks in advance!
Thanks to #bash.d I was able to convert from docx to pdf.
Actually one have to use v2 of API and its "Insert" method.
https://developers.google.com/drive/v2/reference/files/insert#examples
use the code from this link and specify
request.Convert = true;
after that I used
var downloadRequest = driveService.Files.Export(file.Id, "application/pdf");
and voilĂ ! It worked! Takes about 30 seconds to convert file in my case.
I'm downloading in image from web to save it locally. It works great with any other image formats but it this method below fails with an argument exception when I try to read a WebP image.
private static Image GetImage(string url)
{
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
return Image.FromStream(response.GetResponseStream());
}
catch
{
return null;
}
}
How do you read .webp images in C#?
I found this other question that allows for converting between types but I do not want to do that WebP library for C#
Reason I'm not wanting to do it is because I think it might lose some quality. Besides, I want to know why is this not working.
The base class libraries won't help you to deal with WebP images. However, if you only want to save the received file to the disk, you don't have to even know that you are dealing with a WebP images. You can simply treat the received data as a binary blob and dump it to a file, for example using Stream.CopyTo and a FileStream.
The Content-Type HTTP header will give you the mime type of the file you're downloading, and the Content-Disposition header can provide you with a filename and extension (though you might have to do some parsing). You can access those using HttpWebResponse.ContentType and HttpWebResponse.Headers["Content-Disposition"].
#Trillian nailed it. Here is a code snippet for what I did based on his suggestion. Wanted to add code so not posting this as a comment.
To get just the image file extension, you can do this
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string fileExt = response.ContentType.Replace("image/", string.Empty);
To get the file name with extension, you can do the following and the do parsing like I did above. It just has some more data in it.
response.Headers["Content-Disposition"];
Once you have you file name you want to save as, create a file stream and copy the response stream into it.
FileStream fs = new FileStream(targetPath + fileName, FileMode.Create);
response.GetResponseStream().CopyTo(fs);
Assuming you app has access to the destination, image should get saved. Make sure to add try catch and handle exceptions properly. Also note that FileMode.Create will overwrite if the file already exists!
I have a REST API endpoint which receives zip file on .Net Core 1.1. I'm getting IFormFile from request like this
var zipFile = HttpContext.Request.Form.Files.FirstOrDefault();
And then I need to pass it to service method from .Net Standard 1.5, where IFormFile is not supported.
So the question is: how can I convert IFormFile to ZipFile or to some other type which is supported in Standard 1.5, or maybe there is some more proper way to operate with zip files?
Thanks!
IFormFile is just a wrapper for the received file. You should still read the actual file do something about it. For example, you could read the file stream into a byte array and pass that to the service:
byte[] fileData;
using (var stream = new MemoryStream((int)file.Length))
{
file.CopyTo(stream);
fileData = stream.ToArray();
}
Or you could copy the stream into a physical file in the file system instead.
But it basically depends on what you actually want to do with the uploaded file, so you should start from that direction and the convert the IFormFile into the thing you need.
If you want to open the file as a ZIP and extract something from it, you could try the ZipArchive constructor that takes a stream. Something like this:
using (var stream = file.OpenReadStream())
using (var archive = new ZipArchive(stream))
{
var innerFile = archive.GetEntry("foo.txt");
// do something with the inner file
}
I have a list of StorageFiles for my Windows 8 app. I need to submit them to a server via the Stream class. I've tried converting the Storage files like this:
Stream fs = temp[i].OpenAsync(FileAccessMode.Read);
temp[] is the list of StorageFiles that I have containing images. Obviously that code I have doesn't work. The error message suggests I might be missing a cast or something. Is there anyway to convert the StorageFiles or IAsyncOperation to a Stream?
Check if this works:
Stream fs = (await temp[i].OpenAsync(FileAccessMode.Read)).AsStream();
You have all the information in your error message - OpenAsync returns (after you await it) IRandomAccessStream, you can convert it to System.IO.Stream with AsStream method.