Hello and apologies in advance for the noob question. I'm also relatively new to c#. In ASP.NET core, I can save files via the file upload control to AWS S3. However, this relies on me saving the files first to a location on my hard drive and then I can send in the path for the AWS code to pick it up from there. I'm sure it will be a simple answer but I can't find this after a few days' searching. As anyone who uses my site can upload (and later download) pdfs and jpegs, how do I either (1) save the file to a temporary location on their machine or phone, or, preferably, (2) 'somehow' send in the path so the AWS code can pick it up? There are many posts stating how you can't get at the path for security reasons but as far as I can tell, the AWS code relies on it.
Here's the AWS code I'm using (from their documentation). It works for me (overwrites the last file and there's no error handling yet, but one thing at once for me). The bucketName and keyName are set up elsewhere.
It's how to send in the filePath without saving it anywhere that I can't get to work. The error just says that it can't find the file, understandably.
public void FileProcess(string filePath)
{
client = new AmazonS3Client(Amazon.RegionEndpoint.EUWest2);
Amazon.S3.Model.PutObjectRequest request = new Amazon.S3.Model.PutObjectRequest()
{
BucketName = bucketName,
Key = keyName,
FilePath = filePath
};
PutObjectResponse response2 = client.PutObject(request);
}
Related
I have been trying to upload to a OneDrive account and I am hopelessly stuck not being able to upload neither less or greater than 4MB files. I have no issues accessing the drive at all, since I have working functions that create a folder, rename files/folders, and a delete files/folders.
https://learn.microsoft.com/en-us/graph/api/driveitem-put-content?view=graph-rest-1.0&tabs=csharp
This documentation on Microsoft Graph API is very friendly to HTTP code, and I believe I am able to fairly "translate" the documentation to C#, but still fail to grab a file and upload to OneDrive. Some places online seem to be using byte arrays? Which I am completely unfamiliar with since my primary language is C++ and we just use ifstream/ofstream. Anyways, here is the portion of code in specific (I hope this is enough):
var item = await _client.Users[userID].Drive.Items[FolderID]//"01YZM7SMVOQ7YVNBXPZFFKNQAU5OB3XA3K"].Content
.ItemWithPath("LessThan4MB.txt")//"D:\\LessThan4MB.txt")
.CreateUploadSession()
.Request()
.PostAsync();
Console.WriteLine("done printing");
As it stands, it uploads a temporary file that has a tilde "~" in the OneDrive (like as if I was only able to open but not import any data from the file onto it). If I swap the name of the file so it includes the file location it throws an error:
Message: Found a function 'microsoft.graph.createUploadSession' on an open property. Functions on open properties are not supported.
Try this approach with memory stream and PutAsync<DriveItem> request:
string path = "D:\\LessThan4MB.txt";
byte[] data = System.IO.File.ReadAllBytes(path);
using (Stream stream = new MemoryStream(data))
{
var item = await _client.Me.Drive.Items[FolderID]
.ItemWithPath("LessThan4MB.txt")
.Content
.Request()
.PutAsync<DriveItem>(stream);
}
I am assuming you have already granted Microsoft Graph Files.ReadWrite.All permission. Check your API permission. I tested this code snippet with pretty old Microsoft.Graph library version 1.21.0. Hopefully it will work for you too.
I have a unique scenario in which I'd like the end result to help me upload a zip file. Here is what is happening in my workflow:
Our user is given an application on their local machine. With a click of a button, it will copy files and a zip file to remote-machine-1.
On remote-machine-2, it is running a .NET Core web app.
On remote-machine-1, I'd like to ping an endpoint off the web app in order to upload the zip file to remote-machine-2. However, the caveat is that the user will not be able to specify where this zip file is - the location of the zip file already known due to the structure of how the files and zip file are copied over in the first place.
So the question remains, with the code below - how do I pass in an IFormFile object when I call the endpoint localhost:5000/PublishTargetAsync?file=[???]? Or is there another workaround?
public async Task<bool> PublishTargetAsync(IFormFile file)
{
if (file != null)
{
using (var fileStream = new FileStream(Path.Combine(_targetOutputDirectory.ToFileSystemPath(), file.Name), FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
}
return true;
}
A simple, but non optimized approach would be to use HttpClient and post the file contents as a base64 encoded string as Json using sample code similar to what is in my link. From there you could work your way back to using HttpWebRequests and a network stream and crafting the Http request by hand if necessary for performance, but the above approach should work for most small files. You'll have to modify your PublishTargetAsync endpoint to handle a post request with the right type.
I have an app with which at startup it downloads a file from a remote location (through the net) and parses it's contents.
I am trying to speed up the process of startup as the bigger the file gets the slower the app starts.
As a way to speed up the process I thought of getting the last modified date of the file and if it is newer from the file on the user's pc then and only then download it.
I have found many ways to do it online but none of them are in C# (for windows store apps). Does anybody here know of a way of doing this without the need to download the file? If I am to download the file then the process is sped up at all.
My C# code for downloading the file currently is this
const string fileLocation = "link to dropbox";
var uri = new Uri(fileLocation);
var downloader = new BackgroundDownloader();
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("feedlist.txt",CreationCollisionOption.ReplaceExisting);
DownloadOperation download = downloader.CreateDownload(uri, file);
await download.StartAsync();
If it helps the file is stored in dropbox but if any of you guys have a suggestion for another free file hosting service I am open to suggestions
Generally, you can check the file time by sending HEAD request and parsing/looking HTTP header response for a Last-Modified filed. The remote server should support it and DropBox does not support this feature for direct links (only via API). But DropBox have another feature, the headers have the etag field. You should store it and check in the next request. If it changed - the file has been changed too. You can use this tool to check the remote file headers.
I created a PDF webapp where users are able to generate various type of PDF on both the computer and mobile phone. However, i run my program on a localhost and this is how i save my PDF based on my computer's file directory
var output = new FileStream(Path.Combine("C:\\Users\\apr13mpsip\\Downloads", filename), FileMode.Create);
However, when i publish my webapp onto azure, i wasn't able to download from both my computer and mobile phone. Therefore i believe that it could be due to my default file directory.
Hence i would like to ask how to do a default file directory for all computer and mobile phone?
Or could it be i left out something that is necessary when the webapp is published online
Thanks.
PS : I hardcoded a default file path in order for me to test my application on a localhost to ensure a perfect working condition. Therefore i'm finding a way to find a default common file directory for all mobile/computer users when they attempt to download the PDF instead of my usual hard-coded file path
UPDATE
I tried using the method Server.MapPath but receive some error.
var doc1 = new Document();
var filename = Server.MapPath("~/pdf") + "MyTestPDF" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".pdf";
// var output = new FileStream(Path.Combine("C:\\Users\\apr13mpsip\\Downloads", filename), FileMode.Create);
//iTextSharp.text.pdf.PdfWriter.GetInstance(doc1, output);
using (var output = File.Create(filename))
{
iTextSharp.text.pdf.PdfWriter.GetInstance(doc1, output);
}
doc1.Open();
This is the error i received
ObjectDisposedException was unhandled by user code
Cannot access a closed file.
When you write a Web Application you shall never use hard coded paths, and the last place where you should save files is C:\Users !! It does not matter whether this is Azure or not. It is general rule for any kind of web applications!
In your case I suggest that you create a folder within your application named pdf or something like that and save files there with the following code:
var fileName = Server.MapPath("~/pdf") + filename;
using (var output = File.Create(fileName) )
{
// do what you want with that stream
// usually generate the file and send to the end user
}
However there is even more efficient way. Use the Response.OutputStream and write the resulted PDF directly to the response. Will save you a lot of space on the local server, and the logic to delete unused generated files.
I'm able to upload files or directories to a bucket with the AWS .NET SDK, but they always end up in the root folder.
Is there a way to upload a file to an existing directory?
edit. More info:
So I'm using a TransferUtilityUploadDirectoryRequest to upload a directory from my local disk to S3. I would like the files to be uploaded to a folder in the bucket with the same name as the folder I've selected.
For example. if I choose the directory c:/stuff to be upload, I want the contents of c:/stuff to go in BucketName/stuff, not directly into the bucket.
I hope it's clear what I'm trying to do, if not I'll try to provide more info
It seems after googling around, you specify a key. It took me a while, but I believe the key is something like this example:
string key = string.Format("{0}/{1}", folder, filename);
PutObjectRequest rq = new PutObjectRequest()
{
AutoCloseStream = false,
BucketName = s3BucketName,
InputStream = stream,
Key = key
};
S3ClientInstance.PutObject(rq).Dispose();
The newest version of the AWS SDK for .NET allows you to set the KeyPrefix property on the UploadDirectoryRequest (more info here).