I am working on the server that receives a file stream uploaded by multipart uploader.
But I got an additional WebKitFormBoundary.
If I remove it manually, it will work. So I tried the following code:
var fileStream = File.Create(#"C:\Users\myname\Desktop\myimage.png");
stream sr = new streamReader(myStream);
string myText = sr.ReadToEnd();
string newText = myText.Substring(myText.IndexOf("‰")); // remove header
byte[] byteArray = Encoding.ASCII.GetBytes(newText);
MemoryStream data = new MemoryStream(byteArray);
data.CopyTo(filestream);
If I use the above way to convert it to string, remove boundary and convert back to stream
the first character "‰" will become "?"
(ie. So ‰PNG will become ?PNG and the file becomes not readable.)
Any suggestions?
Where could I possible got wrong?
Thanks
This drove me nuts. Finally understood that if you have access to the request, you can access just the contents (with no header) like this:
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var file = await provider.Contents[0].ReadAsStreamAsync();
Hope this helps you, or someone with the same issue.
I have got the same issue but after investigating several blogs with applied several solutions, I got final working one. Please follow below code approach to fix it.
MemoryStream memoryStream = new MemoryStream(File.ReadAllBytes(filePath));
StreamReader streamReader = new StreamReader(memoryStream, Encoding.Default, true);
memoryStream.Seek(0, SeekOrigin.Begin);
string fileString = streamReader.ReadToEnd();
string fileData = fileString.Substring(0, fileString.IndexOf("\r\n\r\n") + 4);
string finalData = Regex.Replace(fileString, fileData, "");
var fileDataArr = Regex.Split(fileData, "\r\n|\r|\n").ToList();
var resultData = Regex.Replace(finalData, fileDataArr[0] + "--", "");
byte[] buffer = Encoding.Default.GetBytes(resultData);
Steps:
Convert your filedata into memory stream which can be used to read file content.
Use StreamReader to read file content and remove webkitformBoundary Header with default Encoding format.
Code To remove first 4 lines including webkitformBoundary from Top.
Code to remove webkitformBoundary from Footer.
Convert the string into Byte Array with default encoding format to maintain the file Encoding format.
Example:
WebKitFormBoundary Header
------WebKitFormBoundaryL1NUALe5NDrNt9S0 <br/>
Content-Disposition: form-data; name="userfile"; filename="BRtestfile1.pdf" <br/>
Content-Type: application/pdf <br/>
WebKitFormBoundary Footer
------WebKitFormBoundaryL1NUALe5NDrNt9S0-- <br/>
Related
Currently, I can upload files(exist) with Grails's RestBuilder.
However, I want to upload a file without creating a file .
I want to create binary data (= Text File) in a program and send it directly
Is it possible?
RestBuilder rest = new RestBuilder()
RestResponse resp = rest.post(url){
contentType("multipart/form-data")
setProperty("dataFile",[filePath])// <- it can
setProperty("dataFile",[ byte[] or inputStream() or String ? ])// <- Is it possible?
}
'''
I'm sure you figured this out already, but you can just use a String reference or a byte[] just as you can use File instances for the multipart request using RestBuilder. It should 'just work' e.g.
RestBuilder rest = new RestBuilder()
RestResponse response = rest.post(url) {
contentType 'multipart/form-data'
stringPart = 'hello' // String
bytePart = '68656c6c6f'.decode64() // byte[]
filePart = new File('/path/to/file.jpg') // File
}
I have the following code:
var htmlToPdf = new NReco.PdfGenerator.HtmlToPdfConverter();
htmlToPdf.PdfToolPath = "~/files/";
htmlToPdf.GeneratePdf(template);
Which throws the following error:
Uri is not supported when saving pdf in server folder with nreco pdf generator.
You will need to set a regular path to your file system like e.g. "C:\temp\myfolder\". Or use a . instead of ~ and backslashes:
htmlToPdf.PdfToolPath = ".\\files\\";
If NReco is able to deliver you an byte-array or a stream you should prefer this instead of a file and return it directly.
UPDATE:
After takeing a look into the documentation of NReco all you need to do is following:
var htmlToPdf = new NReco.PdfGenerator.HtmlToPdfConverter();
htmlToPdf.PdfToolPath = "<CORRECT_PATH_FOR_TOOL>";
var output = htmlToPdf.GeneratePdf(template);
System.IO.File.WriteAllBytes("<OUTPUT_PATH>", output);
This should create your pdf in the OUTPUT_PATH.
#OlaFW thanx for your effort.
I got my answer.
var pdfBytes = htmlToPdf.GeneratePdf(template);
string filePath = "/files/Myfile.pdf";
string Url = System.Web.Hosting.HostingEnvironment.MapPath(filePath);
System.IO.File.WriteAllBytes(Url, pdfBytes);
I have an ASP.net application that allows the users to report bugs and attach files. The bug together with its detail and attachments should be saved in FogBugz.
I have managed to create everything except the file attachment part.
here is my code:
private void NewCaseWithFile()
{
string fbUrl = "https://test.fogbugz.com/api.asp";
string fbToken = logInFogBugz();
string param = "";
param += "cmd=new";
param += "&token=" + fbToken;
param += "&sTags=" + "OnlineService,";
param += "&sTitle=" + "Testing";
param += "&sEvent=" + "This case is being created from Visual Studio";
param += "&nFileCount=" + "1";
param += "&File1=" + "Picture.png";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(fbUrl + "?" + param);
httpWebRequest.Method = WebRequestMethods.Http.Post;
httpWebRequest.ContentType = "multipart/form-data";
httpWebRequest.Accept = "application/xml";
httpWebRequest.ContentLength = 0;
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
XDocument doc = XDocument.Load(streamReader);
}
I have tried all instructions under "Editing Cases" but it did not help. In fact I have no idea what are File 1, File 2 and how to send them to FogBugz.
Can anyone help me with this?
Many thanks!
File1 should be specified in the body of your multipart/form-data post (not as a querystring parameter).
You actually have to specify all the bytes in the file.
There's an answer on fogbugz.stackexchange.com as well as a C# FogBugz API wrapper that will handle all the parts for you.
The form parts in the body of your post would look like
--sdfjdsjsdflk SOME BOUNDARY--
Content-Disposition: form-data; name="File1"; filename="foo.jpg"
Content-Transfer-Encoding: base64
Content-Type: image/png
slfkajdflksjflajfdj
sldfjsd;aljfds
these are actual data bytes from the foo.jpg file
slfkjdsfljds
sdflajsdfs
Or you can look at this question which points to an RFC with an example.
thanks for reading, my doubt is the following, im trying to get data from an xls file but it has to be done locally, without uploading the file, i have done something similiar with txts files and works perfectly :
Function Send(ByVal file As HttpPostedFileBase) As ActionResult
Dim line As String
Dim textreader As System.IO.StreamReader = New StreamReader(file.InputStream)
While Not textreader.EndOfStream
line = textreader.ReadLine()
ViewBag.line = line
End While
Return View("Index")
End Function
but i cant do the same to the excel file, first of all, because i cant use the streamreader, so when using this code i dont know how to specify the dir of my xls file
Dim oApp As Excel.Application = New Excel.Application
Dim oWB As Excel.Workbook
Dim oSheet As Excel.Worksheet
oWB = oApp.Workbooks.Open(file.inputstream) <-- HERE IS WHERE I GET (AN OBVIOUS) ERROR
does anybody knows how to open the file locally? thanks for reading :)
There are several ways of doing it, one of them is accessing the file "database style"
...
...
string filePath = string.Format("C:\\TEST\\{0}.xlsx", Guid.NewGuid().ToString());
var fileStream = File.Create(filePath);
input.CopyTo(file.InputStream);
fileStream.Close();
string cn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=\"Excel 12.0;HDR=YES;\"";
string query = "SELECT * FROM SHEET_NAME";
conn= new OleDbConnection(cn);
conn.Open();
OleDbCommand woOleCommand = new OleDbCommand(query, conn);
DbDataReader result = woOleCommand.ExecuteReader();
// Read the DataReader...
...
So basically you query Sheets like tables, if they are indeed tables, this code might be what you're looking for.
On the other hand, if you still need to use automation, try something like this instead:
...
object missing = System.Reflection.Missing.Value;
wBook = (Excel._Workbook)xl.Workbooks.Open(filePath, false, false, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
...
Reading InputStream
using (var fileStream = File.Create(filePath)) {
file.InputStream.CopyTo(fileStream);
}
// Now you got your stream on a file (filePath) so you can work with it.
Issue #1
When i'm uploading a file to google docs i receive status code "201" created, but when i try to open the file it seems that i'm doing something wrong, because i can't open it, and when i'm trying to download and open it on my PC i see the binary data instead of text or image. Current language is APEX, but i think it's pretty understandable.
First of all i'm getting Upload URL and then putting data to this URL;
public void getUploadURL()
{
Httprequest req = new Httprequest();
req.setEndpoint('https://docs.google.com/feeds/upload/create-session/default/private/full?convert=false');
req.setMethod('POST');
req.setHeader('GData-Version', '3.0');
req.setHeader('Authorization', 'OAuth '+accessToken);
req.setHeader('Content-Length', '359');
req.setHeader('X-Upload-Content-Type', fileType);
req.setHeader('X-Upload-Content-Length', fileSize);
Dom.Document requestDoc = new Dom.Document();
String xml =
'<?xml version=\'1.0\' encoding=\'UTF-8\'?>'
+'<entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007">'
+'<title>'+fileName+'</title></entry>';
requestDoc.load(xml);
req.setBodyDocument(requestDoc);
Http h = new Http();
Httpresponse res = h.send(req);
System.debug('response=\n'+res.getHeader('Location'));
uploadFIle(res.getHeader('Location'));
}
public void uploadFIle(String uploadUrl)
{
Httprequest req = new Httprequest();
req.setEndpoint(uploadUrl);
req.setMethod('PUT');
req.setHeader('GData-Version', '3.0');
req.setHeader('Authorization', 'OAuth '+accessToken);
req.setHeader('Host', 'docs.google.com');
req.setHeader('Content-Length', fileSize);
req.setHeader('Content-Type', fileType);
req.setBody(''+binaryData);
Http h = new Http();
Httpresponse res = h.send(req);
System.debug('response=\n'+res.getBody());
}
As for "binaryData" property - i receive it from the page using javascript like this:
<input type="file" id="myuploadfield" onchange="getBinary()"/>
<script>
function getBinary()
{
var file = document.getElementById('myuploadfield').files[0];
fileSizeToController.val(file.size.toString());
fileNameToController.val(file.name.toString());
fileTypeToController.val(file.type.toString());
var r = new FileReader();
r.onload = function(){ binaryToController.val(r.result); };
r.readAsBinaryString(file);
}
</script>
r.onload = function(){ binaryToController.val(r.result); }; - this is the string that sends file binary data to my controller.
Issue #2
I'm trying to move one collection(folder) to another, and using this article (protocol tab instead of .NET). The issue is that i need to move collection instead of copying it and when i add my collection to another using this article, i'm currently adding reference to my collection instead of moving the whole collection from one place to another.
Please tell me what am i doing wrong.
Thank you for consideration.
Your "binary" data is being corrupted, when you are performing '' + binaryData.
In general, I have had more success using slicing of files, here is an example for webkit:
var chunk = this.file.webkitSlice(startByte, startByte + chunkSize, file_type);
// Upload the chunk
uploadChunk(startByte, chunk, callback);