Im trying to make an ajax post request to an aspx that is supposed to handle my file uploads. However when i read the requests Files, it contains no files.
public partial class SaveFile : System.Web.UI.Page
{
public bool isSaved = false;
[HttpPost]
protected void Page_Load(object sender, EventArgs e)
{
//Get the files from the request
var request = HttpContext.Current.Request;
var files = request.Files; <---- this is empty when it should have files
//temporary path until put on server
string basePath = #"C:\Users\ClonePC\Desktop\UploadedFiles";
//write each file to the disk and save it to the mongodatastructure
foreach (HttpPostedFile file in files) {
SavedFile sf = new SavedFile();
var fileType = file.ContentType;
var fileNameOnDisk = $#"{sf.UID}.{fileType}";
var fullPath = $#"{basePath}\{fileNameOnDisk}";
sf.FileName = file.FileName;
sf.FilePath = fullPath;
var byteStream = file.InputStream;
BinaryReader br = new BinaryReader(byteStream);
byte[] byteArr = br.ReadBytes((Int32)byteStream.Length);
File.WriteAllBytes(fullPath, byteArr);
}
isSaved = true;
}
}
this is my ajax request
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
console.log(this.response);
};
xhr.open('POST', PathProvider.GetRooPath() + "/SaveFile.aspx");
console.log(formData.getAll("files"));
xhr.send(filesAdded[0]);<--any generic file
Related
i want to send an image as json to a post api,but when i send the url of the image in json the reponse shows error.But in postman when i send the image with file upload it works.
My json:
{
name:"xxx",
image:"someurl"
}
my c# code:
{
string url = "xxxxxxxxxx";
HttpWebRequest webRequest = null;
HttpWebResponse webResponse = null;
string responseFromServer = "";
webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Credentials = CredentialCache.DefaultCredentials;
webRequest.ContentType = "application/json";
webRequest.Method = "POST";
webRequest.ReadWriteTimeout = 300000;
// Get the response.
using (var streamWriter = new StreamWriter(webRequest.GetRequestStream()))
{
streamWriter.Write(jsonREQ);
streamWriter.Flush();
streamWriter.Close();
}
using (webResponse = (HttpWebResponse)webRequest.GetResponse())
{
Stream responseStream = webResponse.GetResponseStream();
using (StreamReader sr = new StreamReader(responseStream))
{
responseFromServer = sr.ReadToEnd();
sr.Close();
}
webResponse.Close();
}
return responseFromServer;
}
Here the json request have the json,when i use this i dont get the expected response,but when i use postman with file upload,
It works ,Kindly suggest me a way to send my image in json.(* have tried base64 and byte,it doesnt work as expected*)
Try this:
var formData = new FormData();
formData.append("image", fileInputElement.files[0]);
var request = new XMLHttpRequest();
request.open("POST", "http://example.com/submitform.php");
request.send(formData);
And this on the server to upload to another server:
string responseString;
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
var formData = new MultipartFormDataContent {
{ new StreamContent(fileStream), #"image", Path.GetFileName(filePath) }
};
var request = (HttpWebRequest)WebRequest.Create("URL");
request.Method = WebRequestMethods.Http.Post;
request.AllowWriteStreamBuffering = false;
request.SendChunked = true; // set to true to avoid exception when AllowWriteStreamBuffering = false and ContentLength is not set
request.Headers.Add("abc", "def");
request.ContentType = formData.Headers.ContentType.ToString();
try
{
// Get the request stream with the default timeout
using (Stream requestStream = await request.GetRequestStreamAsyncWithTimeout())
{
// Upload the file with no timeout
await formData.CopyToAsync(requestStream);
}
// Get response with the default timeout, and parse the response body
using (WebResponse response = await request.GetResponseAsyncWithTimeout())
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
responseString = reader.ReadToEnd();
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.Timeout)
{
throw new TimeoutException("Timeout while uploading file.", ex);
}
throw;
}
}
ResultModel result = JsonConvert.DeserializeObject<ResultModel>(responseString);
These extensions so your upload request won't be timeout if you have a big file or slow connection:
public static class WebRequestExtensions
{
public static async Task<Stream> GetRequestStreamAsyncWithTimeout(this WebRequest request, int? millisecondsTimeout = null)
{
Task<Stream> getTask = request.GetRequestStreamAsync();
if (await Task.WhenAny(getTask, Task.Delay(request.Timeout)) == getTask)
{
// task completed without timeout
return getTask.Result;
}
else
{
// timeout
var ex = new TimeoutException();
throw new WebException(ex.Message, ex, WebExceptionStatus.Timeout, null);
}
}
public static async Task<WebResponse> GetResponseAsyncWithTimeout(this WebRequest request, int? millisecondsTimeout = null)
{
Task<WebResponse> getTask = request.GetResponseAsync();
if (await Task.WhenAny(getTask, Task.Delay(request.Timeout)) == getTask)
{
// task completed without timeout
return getTask.Result;
}
else
{
// timeout
var ex = new TimeoutException();
throw new WebException(ex.Message, ex, WebExceptionStatus.Timeout, null);
}
}
private static T AsyncToSyncWithTimeout<T>(
Func<AsyncCallback, object, IAsyncResult> begin,
Func<IAsyncResult, T> end,
int millisecondsTimeout)
{
var iar = begin(null, null);
if (!iar.AsyncWaitHandle.WaitOne(millisecondsTimeout))
{
var ex = new TimeoutException();
throw new WebException(ex.Message, ex, WebExceptionStatus.Timeout, null);
}
return end(iar);
}
}
I am trying to POST a .tgz file using XHR as part of a file upload.
The file itself is valid and I have tested it via manual upload. The issue I am having (I think) is when I encode the file into base64 and upload it, it is being corrupted and not not being picked up as valid.
The file itself is a plugin module for Atmail, which I have tested manually like I said.
This is my upload function with the base64 truncated.
I am encoding the target file initially with:
cat myfile.tgz | base64 > base64_file
and shortening/removing new lines with:
sed ':a;N;$!ba;s/\n/ /g' plugin.base64 > t
My question is, is this the correct way to encode a compressed file for use in my POST request? And if so what is wrong with my implementation?
function uploadPlugin()
{
var uri = "/index.php/admin/plugins/preinstall";
var name = "newPlugin";
filename = "RCE.tgz";
// Comments and extra lines removed to reduce payload size
// Remove new lines: sed ':a;N;$!ba;s/\n/ /g' plugin.base64 > t
var content = "H4sIAAAAAAAAA+0aa2/bOLJfk1/BFYJaLvyIs0m6TZpss30Awe22vabXA65XqLREx2xkSSWppNlu ...";
var formData = new FormData();
var blob = new Blob([atob(content)],
{
type: "application/x-gtar-compressed"
}
)
formData.append(name, blob, filename);
var request = new XMLHttpRequest();
request.open("POST", uri);
request.send(formData);
}
This is the ATMail plugin class I am using.
<?php
class Atmail_Test_Plugin extends Atmail_Controller_Plugin
{
protected $_pluginFullName = 'rce';
protected $_pluginModule = 'mail';
private $_loginPage = false;
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
$request = $this->getRequest();
if (($request->getControllerName() == 'index' && $request->getActionName() == 'index') ||
($request->getControllerName() == 'auth' && $request->getActionName() == 'logout')) {
$this->_loginPage = true;
}
}
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
if ($this->_loginPage) {
$page = $this->getResponse()->getBody();
$page = str_replace("</body>", "<!-- plugins working -->\n</body>", $page);
$this->getResponse()->setBody($page);
}
}
public function setup()
{
$db = zend_Registry::get("dbAdapter");
$db->query("drop table if exists `TestPluginSettings`");
$db->query("create table `TestPluginSettings` (`id` int auto_increment primary key, `keyName` varchar(12), `keyValue` text, index `keyName` (`keyName`))");
}
public function setViewRenderScript()
{
//return "/path/to/nothing.phtml";
}
public function setViewRenderAction()
{
}
}
I eventually found out what was going wrong. I was trying to post binary data incorrectly. Below is the working solution.
function uploadPlugin()
{
var uri = "/index.php/admin/plugins/preinstall";
var name = "newPlugin";
filename = "Upload.tgz";
var body = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xed\x1a\x6b\x6f\xdb" +
"\x38\xb2\x5f\x93\x5f\xc1\x15\x82\x5a\x2e\xfc\x88\xb3\x49\xba" +
"..." +
"...";
var formData = new FormData();
var payload = new Uint8Array(body.length);
for (var i = 0; i < payload.length; i++)
{
payload[i] = body.charCodeAt(i);
}
var blob = new Blob([payload])
formData.append(name, blob, filename);
var xhr = new XMLHttpRequest();
xhr.open("POST", uri);
xhr.send(formData);
}
I can't get it to work to download an excel file that was created by closedxml through web API.
If I save the file on the server it looks good, but as soon as I put it in a stream and return it to the web api, then only a corrupt file is recieved in the browser.
As suggested on several posts I use httpResponseMessage, but also in the browser the filename in the header never arrives.
We are using:
"Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net461
"ClosedXML" version="0.88.0" targetFramework="net461"
WebAPI Code:
var wb = new XLWorkbook();
var ws = wb.Worksheets.Add("Parcel List");
MemoryStream fs = new MemoryStream();
wb.SaveAs(fs);
fs.Position = 0;
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new ByteArrayContent(fs.GetBuffer());
result.Content.Headers.ContentLength = fs.Length;
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "List" + "_" + DateTime.Now.ToShortDateString() + ".xlsx"
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return result;
Here the javascript code:
context.$http.post(config.get_API_URL() + 'api_call', excel_list,
{responseType: 'application/octet-stream'})
.then(
success_function,
error_function)
}
success_function:
function(response) {
var headers = response.headers;
var blob = new Blob([response.body],
{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'},
);
window.open(window.URL.createObjectURL(blob));
}
I could successfully download a workbook with this code now:
using ClosedXML.Excel;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
namespace ClosedXML.Extensions.WebApi.Controllers
{
public class ValuesController : ApiController
{
public IHttpActionResult Get(int id)
{
return new TestFileActionResult(id);
}
}
public class TestFileActionResult : IHttpActionResult
{
public TestFileActionResult(int fileId)
{
this.FileId = fileId;
}
public int FileId { get; private set; }
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpResponseMessage response = null;
var ms = new MemoryStream();
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("Sheet1");
ws.FirstCell().Value = this.FileId;
wb.SaveAs(ms);
ms.Seek(0, SeekOrigin.Begin);
response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContent(ms);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = "test.xlsx";
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.Content.Headers.ContentLength = ms.Length;
ms.Seek(0, SeekOrigin.Begin);
}
return Task.FromResult(response);
}
}
}
Have a look at the Mvc extension package at https://www.nuget.org/packages/ClosedXML.Extensions.Mvc/
PS: I've been told I have to disclaim this everytime. I'm the maintainer of ClosedXML and ClosedXML.Extensions.Mvc.
The problem seems to be that the response type for the web api call has to be {responseType: 'arraybuffer'} instead of {responseType: 'application/octet-stream'}
context.$http.post('api-url', excel_list,
{responseType: 'arraybuffer'})
.then(
success_function,
error_function)
}
Thanks anyhow for your quick help
the problem is that i want to populate var docfiles = new List<string>(); with some files names uploaded by user using dropzone js but the list wont populate because for first time page loaded httpRequest.Files.Count > 0 which means there's no file uploaded by user is there any idea to fill the list after user upload file and for sure that will be after page load ?
protected void Page_Load(object sender, EventArgs e)
{
var httpRequest = System.Web.HttpContext.Current.Request;
HttpFileCollection uploadFiles = httpRequest.Files;
var docfiles = new List<string>();
if (httpRequest.Files.Count > 0)
{
int i;
for (i = 0; i < uploadFiles.Count; i++)
{
HttpPostedFile postedFile = uploadFiles[i];
int fileSizeInBytes = postedFile.ContentLength;
string fileName = postedFile.FileName;// Request.Headers["X-File-Name"];
string fileExtension = "";
fileExtension = Path.GetExtension(fileName);
string savedFileName = Guid.NewGuid().ToString() + fileExtension;
string path = HttpContext.Current.Server.MapPath("~/img/items/");
string filename = path + savedFileName;
postedFile.SaveAs(filename);
docfiles.Add(filename);
}
itm.img1 = "ASs";
}
}
the IsPostBack property will tell you if this is an initial page load or the result of a post-back, so check it before checking for uploaded files.
MSDN Docs on IsPostBack
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
//your code
}
}
I am working on classic ASP with WinCE OS. I want to upload a file from WinCE and Save in the local machine. Please share the necessary JScript function for file upload which i can put it in a include file. Thank you.
Better way is to use any JavaScript library.. like jQuery..
Here are the file upload examples..
http://pixelcone.com/jquery/ajax-file-upload-script/
How can I upload files asynchronously?
Cheers :)
I have no information about asp classic but I have used Asp.net and you can use asp to receive file in order to upload file from wince use can develop app using c# here is an example.
Its client WinCE Application Code Function Upload(string Path, String FileName) takes File Path and File Name as Input and Post it to web page
#region Upload
public bool Upload(string FilePath, string FileName)
{
string Url = "HTTP://test.mtsonweb.com/fileupload.ashx"; // Change it to your page name
string BytesConfirmedReceived = "";
int BytesSent = 0;
bool Ret = false;
ASCIIEncoding encoding = new ASCIIEncoding();
try
{
if (File.Exists(FilePath +"\\"+ FileName) == false) { return true; }
//FileInfo oInfo = new FileInfo(FilePath + "\\" + FileName);
//BytesSent = Convert.ToInt32(oInfo.Length.ToString());
Url += "?myfile=" + FileName.Trim();
FileStream fr = new FileStream(FilePath + "\\" + FileName, FileMode.Open);
BinaryReader r = new BinaryReader(fr);
byte[] FileContents = r.ReadBytes((int)fr.Length);
BytesSent = FileContents.Length;
r.Close();
fr.Close();
WebRequest oRequest = WebRequest.Create(Url);
oRequest.Method = "POST";
oRequest.Timeout = 15000;
oRequest.ContentLength = FileContents.Length;
Stream oStream = oRequest.GetRequestStream();
BinaryWriter oWriter = new BinaryWriter(oStream);
oWriter.Write(FileContents);
oWriter.Close();
oStream.Close();
WebResponse oResponse = oRequest.GetResponse();
BytesConfirmedReceived = new StreamReader(oResponse.GetResponseStream(),
Encoding.Default).ReadToEnd();
oResponse.Close();
if (BytesSent.ToString() == BytesConfirmedReceived.Trim())
{
Ret = true;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return Ret;
}
#endregion
Now of you page you can handle file uploaded using script whatever you want, I have used asp.net with c# as back-end and below is the source of page:
<%# WebHandler Language="C#" Class="FileUpload" %>
using System;
using System.Xml;
using System.Data;
using System.Web;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
public class FileUpload : IHttpHandler
{
public void ProcessRequest(HttpContext oContext)
{
int BytesSent = 0;
//string LocalPath = #"C:\Inetpub\wwwroot\";
string MyFile = "";
try
{
MyFile = oContext.Request["myfile"].ToString().Trim();
MyFile = HttpContext.Current.Server.MapPath("~/Demo/Files/" +
ASCIIEncoding encoding = new ASCIIEncoding();
BytesSent = oContext.Request.TotalBytes;
Class1 obj = Class1.GetInstance();
obj.FileName = MyFile;
obj.FileLength = BytesSent;
byte[] InComingBinaryArray =
oContext.Request.BinaryRead(oContext.Request.TotalBytes);
obj.Data = InComingBinaryArray;
if (File.Exists(MyFile) == true)
{
File.Delete(MyFile);
}
FileStream fs = new FileStream(MyFile, FileMode.CreateNew);
BinaryWriter w = new BinaryWriter(fs);
w.Write(InComingBinaryArray);
w.Close();
fs.Close();
FileInfo oInfo = new FileInfo(MyFile);
long a = (long)BytesSent;
oContext.Response.Write(oInfo.Length.ToString());
}
catch (Exception err) { oContext.Response.Write(err.Message); }
}
public bool IsReusable { get { return true; } }
}