When I try the following code with a postback the file download takes place normally:
FileInfo file = new FileInfo("C:\\a.txt");
Response.ClearContent();
Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
Response.AddHeader("Content-Length", file.Length.ToString());
Response.ContentType = "text/plain";
Response.TransmitFile(file.FullName);
Response.End();
However if I put the above code inside a public static web method and call it with AJAX I get error, like "Process was being aborted".(Of course to get the current response I write HttpContext.Current.Response) This makes me think that the nature of the two responses are different. My question is if they are different, then what exactly is/are different? Is there a way to achieve the same thing with AJAX?
The browser isn't going to receive the file via an XHR (Ajax) call. You will want to return the file location and then send the browser to that file via window.location or window.open.
Edit: Here's a Web Forms sample. My Web Forms skills are a little rusty since I've been using MVC now; the syntax is off the top of my head so you might need to fix it up a little.
ASPX Page
<div id="whateverIsContainingYourDialog">
<form id="mikeJMIsAwesome" runat="server">
<asp:TextBox id="firstName" runat="server" />
<asp:TextBox id="lastName" runat="server" />
<asp:Button id="submit" runat="server" />
</form>
</div>
Server Side Code
protected void submit_OnClick(object sender, EventArgs e) {
//Your logic for creating the file and the code you originally posted for serving the file.
}
What Ek0nomik said, file downloads are handled by the browser and cannot be handled through Javascript. The responses are both identical they are are both just http responses - you can verify this with fiddler or another tool (http://www.fiddler2.com/fiddler2/).
Essentially you ajax method will not be able to handle receiving a file and will certainly not have the permissions to assemble it and store it on you hard drive.
You can 'fake' a user clicking on a link using some Javascript.
Please check this similar question for an answer. I've pasted the answer from it below.
starting file download with JavaScript
We do it that way: First add this script.
<script type="text/javascript">
function populateIframe(id,path)
{
var ifrm = document.getElementById(id);
ifrm.src = "download.php?path="+path;
}
</script>
Place this where you want the download button(here we use just a link):
<iframe id="frame1" style="display:none"></iframe>
download
The file 'download.php' (needs to be put on your server) simply contains:
<?php
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".$_GET['path']);
readfile($_GET['path']);
?>
So when you click the link, the hidden iframe then gets/opens the sourcefile 'download.php'. With the path as get parameter. We think this is the best solution!
I am uploading a file from file upload control in asp.net. On that page there is a checkbox. User have to accept condition before he can upload the file. I am checking on code behind file that if the checkbox is not checked that show an alert message but the problem is that before calling that function the file is going to buffer whole on server and then the function is going called. But i want to to check that condition before temporary uploading of that file.
Below is my code that I am working with-
protected void btn_Upload_Click1(object sender, EventArgs e)
{
if (!chkBx_1.Checked )
{
dataclass.Message("Please accept all terms before uploading", this);
return;
}
else
{
if (FileUpload1.HasFile)
{
FileUpload1.SaveAs("path");
}
}
}
Use some client side technology (javascript, silverlight, etc..) to check the checkbox first before submitting your form to the server.
If you want to be sure, you can recheck the checkbox on the serverside then.
Try to validate this checkbox with toolbox validator "RequiredFieldValidator".
It will be much easier for you to validate the checkbox in client side before continue.
Have look at this article about Related checkbox validation with JQuery. Also within the click function you can use event.preventDefault()
eg.
<input id="chbTest" cssClass="clChb" value="1" type="checkbox">
<script language="javascript">
(document).ready(function(){
$("#btnUpload").click(function(event){
if ($(".clChb").attr("checked") == false){
event.preventDefault();
alert('Please accept all terms before uploading ');
}
});
});
</script>
Also if you are not much familiar, you can have a look at this article about Using jQuery with ASP.NET which shows you how to include necessary script libraries.
I have an image control and a file upload control in .NET 2.0 (VS.NET 2008) form. As soon as user selects an image file in the file upload control, i want the image to appear in the image control of the form. What would be the way to do this ?
(The only event File Upload seems to support is 'OnChange' and i don't know enough javascript to update Image1.URL based on content of FileUpload).
Thanks,
Chak.
You need to upload Asynchronously , and you could try AJAX AsyncFileUpload and this is what you are looking...
http://asp.net-informations.com/ajax/ajax-AsyncFileUpload.htm
Are you looking for a kind of preview? You can only show the image to the user after the file has been uploaded. I'm pretty sure the user has to actively do so (otherwise you could try to read the entire filesystem from the browser)
I think this is a good example:
http://www.codeproject.com/KB/ajax/AJAXUpload.aspx
this is a good starting point too:
http://www.eggheadcafe.com/community/aspnet/2/10204276/how-to-display-image-when-upload-image.aspx
or here:
http://www.eggheadcafe.com/community/aspnet/2/10236947/image-upload-and-display.aspx
updated
protected void Button4_Click(object sender, EventArgs e)
{
string strExtn;
string strpostedfile;
strpostedfile = fileuploading.PostedFile.FileName;
strExtn = System.IO.Path.GetExtension(strpostedfile);
strExtn = strExtn.ToLower();
string strEx = Path.GetExtension(fileuploading.PostedFile.FileName).ToLower();
String filename = Path.GetFileName(fileuploading.FileName);
filename = filename.Remove(filename.Length - strEx.Length);
fileuploading.SaveAs(Server.MapPath("~/Photos/") + filename);
uploadImage.ImageUrl = "~/Photos/" + filename;
}
Page:
<asp:FileUpload ID="fileuploading" runat="server" />
<asp:Button ID="Button4" runat="server" onclick="Button4_Click" Text="Button" />
<br />
<asp:Image ID="uploadImage" runat="server" />
i am using file upload control in ASP.NET for uploading images.
In my form there are two buttons.one for assigning criteria which redirects to other form and other for submitting form.
After assigning criteria only the user has to use submit button.
My problem is when is upload image and click on AssignCriteria button and return back to original page,the upload control is getting blank.
How to keep that upload image control value in that textbox even if we redirected to other page and come back.
<asp:FileUpload runat="server" ID="uploadStatement" />
<asp:Button runat="server" Text="Upload" OnClick="cmdUpload_Click" />
Next code uploads selected file to Temp folder on the server, in my case - parses it and deletes the file.
protected void cmdUpload_Click(object sender, EventArgs e)
{
var fileName = Server.MapPath(Path.Combine("Temp", String.Concat(Guid.NewGuid().ToString(), Path.GetExtension(uploadStatement.FileName))));
try
{
uploadStatement.SaveAs(fileName);
// parse file
}
finally
{
File.Delete(fileName);
}
}
Since any manipulation with the "input type='file'" element is a serious security threat I am afraid there is no way to do this.
Have you considered using of some AJAX overlay "dialog"?
I am using <input type="file" id="fileUpload" runat="server"> to upload a file in an ASP.NET application. I would like to limit the file type of the upload (example: limit to .xls or .xlsx file extensions).
Both JavaScript or server-side validation are OK (as long as the server side validation would take place before the files are being uploaded - there could be some very large files uploaded, so any validation needs to take place before the actual files are uploaded).
Seems like you are going to have limited options since you want the check to occur before the upload. I think the best you are going to get is to use javascript to validate the extension of the file. You could build a hash of valid extensions and then look to see if the extension of the file being uploaded existed in the hash.
HTML:
<input type="file" name="FILENAME" size="20" onchange="check_extension(this.value,"upload");"/>
<input type="submit" id="upload" name="upload" value="Attach" disabled="disabled" />
Javascript:
var hash = {
'xls' : 1,
'xlsx' : 1,
};
function check_extension(filename,submitId) {
var re = /\..+$/;
var ext = filename.match(re);
var submitEl = document.getElementById(submitId);
if (hash[ext]) {
submitEl.disabled = false;
return true;
} else {
alert("Invalid filename, please select another file");
submitEl.disabled = true;
return false;
}
}
It's pretty simple using regulare expression validator.
<asp:RegularExpressionValidator
id="RegularExpressionValidator1"
runat="server"
ErrorMessage="Only zip file is allowed!"
ValidationExpression ="^.+(.zip|.ZIP)$"
ControlToValidate="FileUpload1"
> </asp:RegularExpressionValidator>
Client-Side Validation of File Types Permissible to Upload
From javascript, you should be able to get the filename in the onsubmit handler. So in your case, you should do something like:
<form onsubmit="if (document.getElementById('fileUpload').value.match(/xls$/) || document.getElementById('fileUpload').value.match(/xlsx$/)) { alert ('Bad file type') ; return false; } else { return true; }">...</form>
I agree with Chris, checking the extension is not validation of the type of file any way you look at it. Telerik's radUpload is probably your best option, it provides a ContentType property of the file being uploaded, which you can compare to known mime types. You should check for:
application/vnd.ms-excel,
application/excel,
application/x-msexcel
and for the new 2k7 format:
application/vnd.openxmlformatsofficedocument.spreadsheetml.sheet
Telerik used to sell radUpload as an individual component, but now its wrapped into the controls suite, which makes it a little more expensive, but by far its the easiest way to check for the true type
You could use a regular expression validator on the upload control:
<asp:RegularExpressionValidator id="FileUpLoadValidator" runat="server" ErrorMessage="Upload Excel files only." ValidationExpression="^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*))(.xls|.XLS|.xlsx|.XLSX)$" ControlToValidate="fileUpload"> </asp:RegularExpressionValidator>
There is also the accept attribute of the input tag:
<input type="file" accept="application/msexcel" id="fileUpload" runat="server">
but I did not have much success when I tried this (with FF3 and IE7)
As some people have mentioned, Javascript is the way to go. Bear in mind that the "validation" here is only by file extension, it won't validate that the file is a real excel spreadsheet!
Based on kd7's reply suggesting you check for the files content type, here's a wrapper method:
private bool FileIsValid(FileUpload fileUpload)
{
if (!fileUpload.HasFile)
{
return false;
}
if (fileUpload.PostedFile.ContentType == "application/vnd.ms-excel" ||
fileUpload.PostedFile.ContentType == "application/excel" ||
fileUpload.PostedFile.ContentType == "application/x-msexcel" ||
fileUpload.PostedFile.ContentType == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" //this is xlsx format
)
return true;
return false;
}
returning true if the file to upload is .xls or .xlsx
Ensure that you always check for the file extension in server-side to ensure that no one can upload a malicious file such as .aspx, .asp etc.
Well - you won't be able to do it server-side on post-back as the file will get submitted (uploaded) during the post-back.
I think you may be able to do it on the client using JavaScript. Personally, I use a third party component called radUpload by Telerik. It has a good client-side and server-side API, and it provides a progress bar for big file uploads.
I'm sure there are open source solutions available, too.
I think there are different ways to do this. Since im not familiar with asp i can only give you some hints to check for a specific filetype:
1) the safe way: get more informations about the header of the filetype you wish to pass. parse the uploaded file and compare the headers
2) the quick way: split the name of the file into two pieces -> name of the file and the ending of the file. check out the ending of the file and compare it to the filetype you want to allow to be uploaded
hope it helps :)
Avoid the standard Asp.Net control and use the NeadUpload component from Brettle Development: http://www.brettle.com/neatupload
Faster, easier to use, no worrying about the maxRequestLength parameter in config files and very easy to integrate.
As an alternative option, could you use the "accept" attribute of HTML File Input which defines which MIME types are acceptable.
Definition here
Your only option seems to be client-side validation, because server side means the file was already uploaded. Also the MIME type is usually dictated by the file extension.
use a JavaScript Framework like jQuery to overload the onsubmit event of the form. Then check the extension. This will limit most attempts. However if a person changes an image to extension XLS then you will have a problem.
I don't know if this is an option for you, but you have more client side control when using something like Silverlight or Flash to upload. You may consider using one of these technologies for your upload process.
As another respondent notes, the file type can be spoofed (e.g., .exe renamed .pdf), which checking for the MIME type will not prevent (i.e., the .exe will show a MIME of "application/pdf" if renamed as .pdf). I believe a check of the true file type can only be done server side; an easy way to check it using System.IO.BinaryReader is described here:
http://forums.asp.net/post/2680667.aspx
and VB version here:
http://forums.asp.net/post/2681036.aspx
Note that you'll need to know the binary 'codes' for the file type(s) you're checking for, but you can get them by implementing this solution and debugging the code.
Client Side Validation Checking:-
HTML:
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="btnUpload" runat="server" Text="Upload" OnClientClick = "return ValidateFile()" OnClick="btnUpload_Click" />
<br />
<asp:Label ID="Label1" runat="server" Text="" />
Javascript:
<script type ="text/javascript">
var validFilesTypes=["bmp","gif","png","jpg","jpeg","doc","xls"];
function ValidateFile()
{
var file = document.getElementById("<%=FileUpload1.ClientID%>");
var label = document.getElementById("<%=Label1.ClientID%>");
var path = file.value;
var ext=path.substring(path.lastIndexOf(".")+1,path.length).toLowerCase();
var isValidFile = false;
for (var i=0; i<validFilesTypes.length; i++)
{
if (ext==validFilesTypes[i])
{
isValidFile=true;
break;
}
}
if (!isValidFile)
{
label.style.color="red";
label.innerHTML="Invalid File. Please upload a File with" +
" extension:\n\n"+validFilesTypes.join(", ");
}
return isValidFile;
}
</script>