Upload video file to server with BackgroundUploader - c#

I am creating Windows store app targeting to Windows 8.0
I have Windows 8.1 preview installed on my PC,I created app with VS2012 and implemented file uploading to server with BackgroundUploader and createUploadFromStreamAsync method with the fallowing code -
string url = //url to upload videostring boundray = string.Format("abcboundry");
String header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\n" + "Content-Type: {3}\r\n\r\n", boundray, "file", source.Name, "application/octet-stream");
string footer = string.Format("\r\n--{0}--\r\n", boundray);
Stream headerStream = GenerateStreamFromString(header);
Stream footerStream = GenerateStreamFromString(footer);
//Stream dataStream = iRandomstream.AsStream();
Stream dataStream = await source.OpenStreamForReadAsync();
MemoryStream fileDataStream = new MemoryStream();
await headerStream.CopyToAsync(fileDataStream);
await dataStream.CopyToAsync(fileDataStream);
await footerStream.CopyToAsync(fileDataStream);
fileDataStream.Position = 0;
IInputStream stream = fileDataStream.AsInputStream();
BackgroundUploader backgroundUploader = new BackgroundUploader();
backgroundUploader.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundray);
backgroundUploader.Method = "POST";
UploadOperation uploadOpration = await backgroundUploader.CreateUploadFromStreamAsync(new Uri(url), stream);
await HandleUploadAsync(uploadOpration, true);
and it is working fine to me but when test on other system with Windows 8.0 installed app getting crash with AccessViolationException was unhandled. Attempted to read or write protected memory. This is often an indication that other memory is corrupt." at the InitializeComponent. error
Now I tried to implenent BackgroundTransferContentPart for multipart upload but not success with this code -
List<BackgroundTransferContentPart> parts = new List<BackgroundTransferContentPart>();
BackgroundTransferContentPart part = new BackgroundTransferContentPart("file", source.Name);
part.SetHeader("Content-Type", "application/octet-stream");
part.SetFile(source);
parts.Add(part);
BackgroundUploader uploader = new BackgroundUploader();
uploader.Method = "POST";
UploadOperation uploadOp = await uploader.CreateUploadAsync(new Uri(url), parts, "form-data",boundray);
await HandleUploadAsync(uploadOp, true);
What can I do to solve my problem ?
How to Upload large file to server ?

I solved my problem.
Create a temporary raw file in LocalFolder and write stream which we need to upload to file (stream contains header and footer)
Synchronize this newly created temporary file to storage file
Get input stream from storage file
Now create upload with this stream and same boundary used to create stream.
StorageFile VideoFileStream = await ApplicationData.Current.LocalFolder.CreateFileAsync("tempStream", CreationCollisionOption.OpenIfExists);
var fs2 = await VideoFileStream.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
IInputStream aaaa= fs2.GetInputStreamAt(0);
BackgroundUploader backgroundUploader = new BackgroundUploader();
backgroundUploader.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundray);
backgroundUploader.Method = "POST";
UploadOperation uploadOpration = await backgroundUploader.CreateUploadFromStreamAsync(new Uri(url),aaaa);
await HandleUploadAsync(uploadOpration, true);

Have you tried using a WinRT stream instead?? Instead of System.Net.MemoryStream, try Windows.Storage.Streams.InMemoryRandomStream. You can use RandomAccessStream.CopyAsync() to fill it.

Related

.NET HttpClient Image Upload to PlantNet API

I am trying to make a Request to the PlantNet API via .NET HttpClient. I have a FileStream and I am using the StreamContent and when I look via debugger at the content before it is sent it's looking good. However PlantNet response is Unsupported file type for image[0] (jpeg or png).
I tried everything that came in my mind, the same request from VS Code Rest Client is working (with the same file), does anyone have any ideas if the StreamContent is messing somehow with the file data?
HttpResponseMessage responseMessage;
using (MultipartFormDataContent content = new("abcdef1234567890")) //Fixed boundary for debugging
{
content.Add(new StringContent("flower"), "organs");
using Stream memStream = new MemoryStream();
await stream.CopyToAsync(memStream, cancellationToken);
StreamContent fileContent = new(memStream);
fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
content.Add(fileContent, "images", fileName);
responseMessage = await _httpClient.PostAsync(url, content, cancellationToken);
}
Note: stream is the stream of the file, in this case it comes from an ASP.NET Core API controller usingIFormFile.OpenReadStream() but I also tried opening the file directly via
new FileStream("path", FileMode.Open, FileAccess.Read)
In the Debugger content.ReadAsStringAsync() resolves to the following
--abcdef1234567890
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=organs
flower
--abcdef1234567890
Content-Type: image/jpeg
Content-Disposition: form-data; name=images; filename=test-flower.jpeg; filename*=utf-8''test-flower.jpeg
--abcdef1234567890--
which is looking absolutely fine for me, so my guess is, that somehow the file binary data may be corrupt in the content or something?
When I use the above for VS Code rest client with the same file it works and I get a successful response from the PlantNet API.
(Background: I am using .NET 6 on Fedora Linux)
Ok I solved it by removing the copy to the memory stream. This was needed as at first for debugging I opened the file directly and received exceptions if I didn't do it.
The code that is working for me is
HttpResponseMessage responseMessage;
using (MultipartFormDataContent content = new("abcdef1234567890"))
{
content.Add(new StringContent("flower"), "organs");
StreamContent fileContent = new(stream);
fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = fileName,
Name = "images"
};
content.Add(fileContent, "images", fileName);
responseMessage = await _httpClient.PostAsync(url, content, cancellationToken);
}

Prevent IDM from downloading automatically in web api

I have a web api method that returns an HttpResponseMessage containing a PDF file. The method looks something like this:
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StreamContent(new FileStream(path, FileMode.Open, FileAccess.Read));
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = fileName;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return response;
When I call this api from client (which is written in angularJS), the Internet Download Manager automatically catches the PDF file and wants to download it. And because I have a security plan for my project, the IDM automatically requests username and password.
Does anyone have an idea about how I'm supposed to programmatically stop IDM from catching the PDF file?
Update: Here's my angularJS code:
$http.post(url, { transactionId: txId }
, {responseType: 'arraybuffer'})
.success(function (response) {
var reader = new FileReader();
var file = new Blob([response.data], {type: 'application/pdf'});
reader.onload = function (e) {
var printElem = angular.element('#printPdfLink');
printElem.attr('target', '_blank');
printElem.attr('href', reader.result);
printElem.attr('ng-click', '');
};
reader.readAsDataURL(file);
})
.error(function (error) {});
Change the mime type to application/octet-stream as a way to work around your problem. Make sure that the file name includes a proper file extension so that it can be recognized by the client system once downloaded.
Another issue is the attachment disposition of the content which typically forces it to save it as a file download. Change it to inline so that the client can consume it without IDM trying to download it as an attachment.
FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
StreamContent content new StreamContent(stream);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline");
content.Headers.ContentDisposition.FileName = fileName;
content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = content;
return response;
I have try to use HttpResponseMessage.
If I use ContentDisposition is inline then response break the file. If use attachment then IDM can detect it.
At the end of the day, I found Accept-Ranges header can make download without IDM but it not valid in HttpResponseMessage.
You can try out my code below to make download file without IDM:
[HttpGet]
[Route("~/download/{filename}")]
public void Download(string filename)
{
// TODO lookup file path by {filename}
// If you want to have "." in {filename} you need enable in webconfig
string filePath = "<path>"; // your file path here
byte[] fileBytes = File.ReadAllBytes(filePath);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("Accept-Ranges", "bytes");
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.AddHeader("ContentDisposition", "attachment, filename=" + filename);
HttpContext.Current.Response.BinaryWrite(fileBytes);
HttpContext.Current.Response.End();
}
Note: filename parameter serve for download file name so you can config in webconfig if you want to have file extension (disabled by default).

Downloading a file with response doesn't show a filesize

I have this piece of code in a function:
Response.Clear();
Response.ContentType = "text/xml; charset=utf-8";
Response.AddHeader("Content-Disposition", "attachment; filename=test.xml");
// Put xml into response here
Response.End();
And this works, but, when it, it doesn't show a file size, in firefox it shows the filesize -1 and in chrome and ie it doesn't show a file size at all. How can I show the file size?
Did you try giving this:
Response.AddHeader("Content-Length", someBytes.Length.ToString());
If the content-length is set the web browser will show a progress bar while downloading. This is a very important usability feature for medium and large files, and you really want it. You want your user to know how far along they are, so they don't cancel the download and start it over, or worse just abandon your site.
Refer
If your Response is of type System.Net.Http.HttpResponseMessage, you can insert a Content-Length header by using:
response.Content.Headers.ContentLength = <length in bytes>;
If you are stream a file your code could look like:
FileStream fileStream = File.Open("<source file name>", FileMode.Open);
HttpResponseMessage response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
response.Content = new StreamContent(fileStream);
response.Content.Headers.ContentLength = fileStream.Length;
response.Content.Headers.ContentType =
new MediaTypeHeaderValue("<media type e.g. application/zip>");
response.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("file")
{
FileName = "<destination file name>"
};
return response;

Upload files using ASP.NET

<form action="http://s0.filesonic.com/abc" method="post" enctype="multipart/form-data">
<input type="file" name="files[]" />
<button type="submit">submit</button>
</form>
The above code uploads the files to file sonic server, but I want to do this using programmatically using C#, basically my requirement is that the program creates the form and file control and sends the file to the Filesonic server URL mentioned in action attribute..
I have gone through many links but with no success, I have gone through the following links with no success.
Upload files with HTTPWebrequest (multipart/form-data)
The following code will upload the file to the server as long as the server can accept it outside of files[] array.
WebRequest webRequest = WebRequest.Create("http://s0.filesonic.com/abc");
FileStream reader = new FileStream("file_to_upload", FileMode.Open);
byte[] data = new byte[reader.Length];
webRequest.Method = "POST";
webRequest.ContentType = "multipart/form-data";
webRequest.ContentLength = reader.Length;
webRequest.AllowWriteStreamBuffering = "true";
reader.Read(data, 0, reader.Length);
using (var request = webRequest.GetRequestStream())
{
request.Write(data, 0, data.Length);
using (var response = webRequest.GetResponse())
{
//Do something with response if needed
}
I that case your action on the form would point to your own page on your asp.net server. You are going to post a file back to your asp.net server using http, you will then either hold it in memory or write it to a temp directory, then you could HttpWebRequest to send the file to the filesonic server.
In your case you can also do form a post directly using HttpWebRequest, a quick sample that i could find is here
You can upload file to your server using FTP credentials
Here , path means your local file path or source file & DestinationPath is server path where you have to upload file Ex. 'www.....com/upload/xxx.txt'
FtpWebRequest reqObj = (FtpWebRequest) WebRequest.Create(DestinationPath);
reqObj.Method = WebRequestMethods.Ftp.UploadFile;
reqObj.Credentials = new NetworkCredential(FTP_USERNAME, FTP_PASSWORD);
byte[] fileContents = File.ReadAllBytes(path);
reqObj.ContentLength = fileContents.Length;
Stream requestStream = reqObj.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)reqObj.GetResponse();
response.Close();

Help needed on Uploading Files in windows mobile

I have an desktop application running on my desktop.
I need to send the file path to the CGI script running at server.
CGI script taks the file path and upload the contents from my machine.
I tried to send the file path through httppost method; it is not working - can any one suggest me how to do.. methods I have tried are:
WebClient upload = new WebClient();
NetworkCredential nc = new NetworkCredential("test", "admin");
Uri URL = new Uri("http:\\10.10.21.55\\cgi-bin\\file_upload.cgi");
upload.Credentials = nc;
byte [] data = upload.UploadFile(filepath, "c:/Data.txt");
Console.WriteLine(data.ToString());
and the other way I tried is:
byte[] buf = new byte[8192];
// prepare the web page we will be asking for
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create("http://10.10.21.55/cgi-bin/file_upload.cgi");
WebResponse rsp = null;
request.Method = "POST";
request.ContentType = "text/xml";
StreamWriter writer = new StreamWriter(request.GetRequestStream());
writer.WriteLine("hi hiw are you");
writer.Close();
both ways are not working.
but the below answered code works in desktop in winmo its telling WebClient not implimented...
please tell how to send data to script present in server in windows mobile
Is this as simple as getting the WebClient parameters right? (you seem to be passing in file-path as the url, and not using the encoding):
using(WebClient upload = new WebClient()) {
NetworkCredential nc = new NetworkCredential("test", "admin");
upload.Credentials = nc;
byte[] data = upload.UploadFile(
#"http://10.10.21.55/cgi-bin/file_upload.cgi", #"c:\Data.txt");
Console.WriteLine(upload.Encoding.GetString(data));
}

Categories