Uploading files to server - c# - c#

I build a client server application for uploading file from a client folder to server.
My server WebMethod for uploading follows -
[WebMethod]
public string UploadFile(byte[] f, string fileName)
{
// the byte array argument contains the content of the file
// the string argument contains the name and extension
// of the file passed in the byte array
new general().logError("UploadFile " + fileName);
try
{
// instance a memory stream and pass the
// byte array to its constructor
MemoryStream ms = new MemoryStream(f);
FileStream fs = new FileStream(System.Web.Hosting.HostingEnvironment.MapPath
("~/data/") + fileName, FileMode.Create);
// write the memory stream containing the original
// file as a byte array to the filestream
ms.WriteTo(fs);
// clean up
ms.Close();
fs.Close();
fs.Dispose();
new general().logError("After saving the file");
// return OK if we made it this far
return "OK";
}
catch (Exception ex)
{
return ex.Message.ToString();
}
}
The function that calls this WebMethod follows -
private void uploadIt(string fName)
{
FileStream f = File.OpenRead(fName);
cloudius.cloudius m = new cloudius.cloudius();
using (MemoryStream ms = new MemoryStream())
{
f.CopyTo(ms);
//string[] drive = fName.Split(':');
string[] p = fName.Split('\\');
string b = m.UploadFile(ms.ToArray(), p[p.Length - 1]); //
}
}
When running the aboce code I get the following error -
Client found response content type of 'text/html', but expected 'text/xml'.
Any idea what is causing this error ?

By the looks of things after some research, it looks like it is a form of a error page coming back. Go have a look here as well as here.
Hope this gives you some form of clarification on your problem.

Hey buddy if the main purpose of your method is just to upload a file you can use :
FileUpload fu; // Get the FileUpload object.
using (FileStream fs = File.OpenWrite("file.dat"))
{
fu.PostedFile.InputStream.CopyTo(fs);
fs.Flush();
}
That will be more efficient, as you will be directly streaming the input file to the destination host, without first caching in memory or on disk.

Related

Create a valid PDF from a web request

I'm trying to create a scanning solution. Basically the user is physically scanning a page. The printer is making an API call, passing in the binary data of the scan in the body.
I'm trying to save this as a PDF on the server, but when I go to open the file, i'm getting an error "There is an error while reading a stream".
var bodyStream = new StreamReader(HttpContext.Current.Request.InputStream);
bodyStream.BaseStream.Seek(0, SeekOrigin.Begin);
var bodyText = bodyStream.ReadToEnd();
string pathToFiles = HttpContext.Current.Server.MapPath("~\\UploadedFiles\\WriteLines.pdf");
try
{
using (StreamWriter outputFile = new StreamWriter(pathToFiles, false))
{
outputFile.WriteLine(bodyText);
}
HttpContext.Current.Response.ContentType = "application/pdf";
}
catch (Exception ex)
{
throw (ex);
}
This is just testing something, and I have permissions etc for writing the file, it's just not creating a valid file.
Any thoughts on what I should use? I have looked into some libraries, but they don't seem to cover what i'm after
StreamReader.ReadToEnd convert bytes to string in particular encoding (UTF8 by default). I don't think this work for PDF.
You need copy bytes directly in the output file :
var bodyStream = HttpContext.Current.Request.InputStream;
bodyStream.Seek(0, SeekOrigin.Begin);
string pathToFiles = HttpContext.Current.Server.MapPath("~\\UploadedFiles\\WriteLines.pdf");
using (FileStream outputFile = File.Create(pathToFiles))
{
bodyStream.CopyTo(outputFile);
}

VirusTotal Uploaded File is Zero Bytes

I'm trying to upload a file to VirusTotal using .Net Core.But the uploaded file size is Zero Bytes.Why does this happen?
[Route("api/[controller]")]
public class ScannerController : Controller
{ [HttpGet]
public async Task<VirusTotalNet.Results.FileReport> ScanAsync(string file_id)
{
file_id = "./wwwroot/Upload/node-v12.14.1-x64.msi";
VirusTotal virusTotal = new VirusTotal("");
// virusTotal.UseTLS = true;
FileStream stream = System.IO.File.OpenRead(file_id);
byte[] fileBytes = new byte[stream.Length];
stream.Read(fileBytes, 0, fileBytes.Length);
VirusTotalNet.Results.FileReport report = await virusTotal.GetFileReportAsync(stream);
return report;
}
}
You've read the entire file into a byte[] and there's an overload of GetFileReportAsync that will take that, so change the parameter from stream to fileBytes:
VirusTotalNet.Results.FileReport report = await virusTotal.GetFileReportAsync(fileBytes);
Derviş Kayımbaşıoğlu suggested resetting the stream's position but it turns out that the location mentioned was incorrect. Either of these:
stream.Seek(0L, SeekOrigin.Begin);
// or
stream.Position = 0L;
Needed to be done immediately before calling GetFileReportAsync, after the file had been read, not before. That would've worked.
But wait, there's more!
There's no need to read the file into fileBytes, which means there's no need to reset the position. The stream can be opened and passed directly to GetFileReportAsync. Including proper resource disposal, the entire method becomes this:
[HttpGet]
public async Task<VirusTotalNet.Results.FileReport> ScanAsync(string file_id)
{
file_id = "./wwwroot/Upload/node-v12.14.1-x64.msi";
VirusTotal virusTotal = new VirusTotal("");
// virusTotal.UseTLS = true;
using (FileStream stream = System.IO.File.OpenRead(file_id))
{
VirusTotalNet.Results.FileReport report = await virusTotal.GetFileReportAsync(stream);
return report;
}
}
This allows both the file to be read and the socket to be written asynchronously, and the data can be buffered in small amounts so that large files don't have to be loaded entirely into memory.

From URL of Video GetThumbnail Using Nreco

I working on a sharepoint project in which i have to upload the videos in the document library as videoset. after creating a video set i have have to upload the video and fetch the thumbnail from the video and upload it. video is uploaded succesfully using
spfile = item.Folder.Files.Add(fuUpload.FileName, fuUpload.PostedFile.InputStream, true);
I am using using Nreco to get thumbnail from the video. However my code works fine on local machine but its giving error "http://mysite/Download/abc/abc.mp4: Server returned 401 Unauthorized (authorization failed) (exit code: 1)" when i am using my application from other pc browsers.
ffMpeg.GetVideoThumbnail(videoPath, ms, 10); the error line.
here is the code i am using
private MemoryStream SaveThumbnail(string videoPath)
{
MemoryStream ms;
try
{
videoPath = "http://mysitehttp/Download/abc/abc.mp4"
ms = new MemoryStream();
SPSecurity.RunWithElevatedPrivileges(delegate() {
var ffMpeg = new NReco.VideoConverter.FFMpegConverter();
ffMpeg.GetVideoThumbnail(videoPath, ms, 10);
});
}
catch(Exception ex)
{
throw ex;
}
return ms;
}
Finally I have managed to solve this. For some reason SharePoint did not allow me to access the file directly from URL using NReco so i tweaked the function like this.
Instead of using file URL as argument i used the file object it self. and copied the stream on server temp folder in virtual directories then i used the file path on the system for NRreco to create the thumbnail. and in the end deleted the file from the server.
private MemoryStream SaveThumbnail(SPFile videoFile)
{
MemoryStream ms;
try
{
//Creating Temp File Path to be used by Nreco
ms = new MemoryStream();
SPSecurity.RunWithElevatedPrivileges(delegate() {
string destinationFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + videoFile.Name);
//Copying the content the content of the file at temp loaction from stream
using (FileStream fileStream = File.Create(destinationFile))
{
Stream lStream = videoFile.OpenBinaryStream();
byte[] contents = new byte[lStream.Length];
lStream.Read(contents, 0, (int)lStream.Length);
lStream.Close();
// Use write method to write to the file specified above
fileStream.Write(contents, 0, contents.Length);
fileStream.Close();
}
var ffMpeg = new NReco.VideoConverter.FFMpegConverter();
ffMpeg.GetVideoThumbnail(destinationFile, ms, 10);
System.IO.File.Delete(destinationFile);
});
}
catch(Exception ex)
{
throw ex;
}
return ms;
}
Someone might save some time from my answer. if anyone has a better solution let me know please.

Telegram Bot download image file

I'm trying to download file (image ) using my bot, but when I download the image ( which is done successfully ) after using getFile, the image I received is very small 1.7 kb while it's bigger than that on my mobile phone
This is an old post. But since there is not a good documentation on how you should download file in telegram bot, for anyone wondering, that's how you should do it(One way of it):
DownloadFile(message.Photo[message.Photo.Length - 1].FileId, #"c:\photo.jpg");
in which:
private static async void DownloadFile(string fileId, string path)
{
try
{
var file = await Bot.GetFileAsync(fileId);
using (var saveImageStream = new FileStream(path, FileMode.Create))
{
await file.FileStream.CopyToAsync(saveImageStream);
}
}
catch (Exception ex)
{
Console.WriteLine("Error downloading: " + ex.Message);
}
}
The message.Photo[message.Photo.Length - 1] is the last element in message.Photo array, which contains the highest quality image data. Obviously you can use DownloadFile to download other kind of files(for example message.Document) as well.
the getFile Method present a JSON object (the 1.7 KB response) that contain the data for accessing your image file.
also note that telegram create an array of image for any image. the first element of this array contain the small thumbnail of your original image and the latest element of the array contain your original image.
var file = await Bot.GetFileAsync(message.Document.FileId);
FileStream fs=new FileStream("Your Destination Path And File Name",FileMode.Create);
await Bot.DownloadFileAsync(file.FilePath, fs);
fs.Close();
fs.Dispose();
I use telegram.bot v14.10.0 but I can't find file.FileStream so I find alternative way to get image from telegram. my way is to use telegram api directly for this case.
var test = _myBot.GetFileAsync(e.Message.Photo[e.Message.Photo.Count() - 1].FileId);
var download_url = #"https://api.telegram.org/file/bot<token>/" + test.Result.FilePath;
using (WebClient client = new WebClient())
{
client.DownloadFile(new Uri(download_url), #"c:\temp\NewCompanyPicure.png");
}
//then do what you want with it
You need use await botClient.DownloadFileAsync(file.FilePath, saveImageStream); instead await file.FileStream.CopyToAsync(saveImageStream);
Your code should look like this:
static async void DownloadFile(ITelegramBotClient botClient, string fileId, string path)
{
try
{
var file = await botClient.GetFileAsync(fileId);
using (var saveImageStream = new FileStream(path, FileMode.Create))
{
await botClient.DownloadFileAsync(file.FilePath, saveImageStream);
}
}
catch (Exception ex)
{
Console.WriteLine("Error downloading: " + ex.Message);
}
}
Telegram.Bot from version 14.2.0 commit in examples: https://github.com/TelegramBots/Telegram.Bot.Examples/commit/ff5a44133ad3b0d3c1e4a8b82edce959d0ee0d0e

Using updateEntry() method with dotnetzip won't overwrite files correctly

I've been having a bit of a problem lately. I've been trying to extract one zip file into a memory stream and then from that stream, use the updateEntry() method to add it to the destination zip file.
The problem is, when the file in the stream is being put into the destination zip, it works if the file is not already in the zip. If there is a file with the same name, it does not overwrite correctly. It says on the dotnetzip docs that this method will overwrite files that are present in the zip with the same name but it does not seem to work. It will write correctly but when I go to check the zip, the files that are supposed to be overwritten have a compressed byte size of 0 meaning something went wrong.
I'm attaching my code below to show you what I'm doing:
ZipFile zipnew = new ZipFile(forgeFile);
ZipFile zipold = new ZipFile(zFile);
using(zipnew) {
foreach(ZipEntry zenew in zipnew) {
percent = (current / zipnew.Count) * 100;
string flna = zenew.FileName;
var fstream = new MemoryStream();
zenew.Extract(fstream);
fstream.Seek(0, SeekOrigin.Begin);
using(zipold) {
var zn = zipold.UpdateEntry(flna, fstream);
zipold.Save();
fstream.Dispose();
}
current++;
}
zipnew.Dispose();
}
Although it might be a bit slow, I found a solution by manually deleting and adding in the file. I'll leave the code here in case anyone else comes across this problem.
ZipFile zipnew = new ZipFile(forgeFile);
ZipFile zipold = new ZipFile(zFile);
using(zipnew) {
// Loop through each entry in the zip file
foreach(ZipEntry zenew in zipnew) {
string flna = zenew.FileName;
// Create a new memory stream for extracted files
var ms = new MemoryStream();
// Extract entry into the memory stream
zenew.Extract(ms);
ms.Seek(0, SeekOrigin.Begin); // Rewind the memory stream
using(zipold) {
// Remove existing entry first
try {
zipold.RemoveEntry(flna);
zipold.Save();
}
catch (System.Exception ex) {} // Ignore if there is nothing found
// Add in the new entry
var zn = zipold.AddEntry(flna, ms);
zipold.Save(); // Save the zip file with the newly added file
ms.Dispose(); // Dispose of the stream so resources are released
}
}
zipnew.Dispose(); // Close the zip file
}

Categories