aspx.net uploading files to a server side - c#

I have 2 pages. One page sends an id number that I will use to upload data from database later on.
I send this id number through the url - location += "fileUploadPage.aspx?"+ ID".
Then I need to upload files on the server side on that page. I need the form to not reload the page, as it's removing my URL extension.
I thought about using sessionStorage - but I feel like it's better in my case, as the user can have multiple tabs open for different items to upload files to.
After uploading the file to a server side - I will also need to convert it into a PDF.
I've been trying to do this for a few days and I couldn't fix it.
I managed to upload a file from a form to a server side folder, but I couldn't deny the reload of the page.
When I did deny the reload of the page the server side function did not execute. Also, I have failed to convert into PDF.
I work with aspx.net c# on serverside.
Sadly I can't share the original code as it's on a closed place, but I made a demo on my local pc:
Any suggestions? I'm new to the area of working with files-never done that before. Any suggestions on refactoring my code or how I move the ID is more than welcomed.
The input number is also a text I will need to add to my file name
after converting it to a PDF.
<form id="myForm" name="myForm" action="FilesProblemPage.aspx" runat="server" style="margin-top: 20px;">
<select id="Number" runat="server">
<option value="3">333333333</option>
<option value="2">222222222</option>
</select>
<label runat="server">
click me to choose a file
<input id="uploadFile" name="uploadFile" style="visibility: hidden" type="file" runat="server" />
</label>
<p id="ChosenFile">no file selected</p>
<asp:Button ID="uploadButton" runat="server" Text="Upload" type="button"
OnClick="uploadButton_Click" BorderStyle="None" CssClass="button" />
</form>
let makat = location.href.split("?")[1];
if (makat == 44459999) {
$("#makat").val("workssss");
$(".checkingTemp")[0].checked = true;
$(".checkingTemp")[1].checked = true;
}
$("#body_uploadFile")[0].addEventListener("change", function (e) {
console.log($("#body_uploadFile")[0].files);
if ($("#body_uploadFile")[0].files[0] != undefined)
$("#ChosenFile").text($("#body_uploadFile")[0].files[0].name);
else
$("#ChosenFile").text("no file chosen");
})
server side :
added :
using System.IO;
protected void uploadButton_Click(object sender, EventArgs e)
{
if (uploadFile.PostedFile != null && uploadFile.PostedFile.ContentLength > 0)
{
string fileName = Path.GetFileName(uploadFile.PostedFile.FileName);
string folder = Server.MapPath("~/TempFiles/");
Directory.CreateDirectory(folder);
uploadFile.PostedFile.SaveAs(Path.Combine(folder, fileName));
try
{
Response.Write("<script>alert('operation success')</script>");
}
catch
{
Response.Write("<script>alert('operation failed')</script>");
}
}
}

well, you could still use session() to pass the ID, but then on first page load (on the next page, you save that ID into ViewState. That way, it will not matter if they have multiple pages open since when they jump to the next page, then on first page load IsPostBack = false, then you transfer to ViewState.
ViewState is per web page, were as session() is global. so, pass the id via session, and FIRST thing on next page is to transfer the value to ViewState.
However, the problem with just using a simple FileUpLoad control, is they are not all that great, and if files are larger, then you don't get any kind of progress during the up-load.
For this reason, I tend to spend some REAL efforts on file uploading. (since it is a pain for developers, and often for users alike). There are a LOT of choices in this area, but I was using the AjaxToolKit in my project, and thus adopted that one.
So, users can drag + drop files, or select many files and then hit a up-load button.
the AjaxToolKit up-loader thus looks like this:
So, the user can select a bunch of files - remove them, do whatever.
Then they can hit the up-load button.
Each file uploads - with a progress bar. And then after up-loading, I display the files uploaded.
eg this:
And the other advantage of the up-loader, is there not really a file size limit - it uploads in small chunks.
So, it really depends on how fancy you want to get, but there are quite a few "up-loader" examples and even some jquery + JavaScript ones that are quite nice.
As suggested, if you not using the AjaxControl toolkit, then you could consider it (it a bit over kill - but the toolkit does have a lot of other nice features).
As noted, you might want to better use at least a asp.net FileUpload control, but it depends on how many files, how large, and what kind of UI your looking for here?

Related

Invalid ViewState when using jQuery tabs

I have a fairly simple page with a set of jQuery tabs, the content of some is called via ajax. I also have a search box in the masterpage in my header.
When I open the tabbed page the search box works fine. However once I have clicked on one of the ajax tabs the search box fails to work with an "Invalid Viewstate" yellow screen of death.
I believe this is because the ajax page is replacing the __VIEWSTATE hidden input with its own.
How can I stop this behaviour?
UPDATE: I have noticed that the YSOD only appears in IE and Chrome, Firefox doesn't seem to have the same issue. Although how the browser influences the ViewState, I'm not sure.
UPDATE: I've put a cut down version of the site that shows the issue here: http://dropbox.com/s/7wqgjqqdorgp958/stackoverflow.zip
The reason of such behavior is that you getting content of the ajaxTab.aspx page asynchronously and paste it into another aspx page. So you getting two instances of hidden fields with __VIEWSTATE name and when page posted back to server theirs values are mixing (might depends on how browser process multiple controls with same name on submit). To resolve this you can put second tab's content into a frame:
<div id="tabs">
<ul>
<li>Default Tab</li>
<li>ajax Content</li>
</ul>
<div id="tabs-1">
<p>
To replicate the error:
<ul>
<li>First use the search box top right to search to prove that code is ok</li>
<li>Then click the second ajax tab, and search again.</li>
<li>N.B. Chrome / IE give a state error, Firefox does not</li>
</ul>
</p>
</div>
<iframe id="tabs-2" src="ajaxTab.aspx" style="width:100%;" ></iframe>
</div>
Also, I'm not sure but this seems like error in the Web_UserControls_search control. In my opinion, NavBarSearchItemNoSearchItem_OnClick method must be refactored as below:
protected void NavBarSearchItemNoSearchItem_OnClick(object sender, EventArgs e)
{
var searchFieldTbx = NavBarSearchItemNo;
var navBarSearchCatHiddenField = NavBarSearchCatHiddenField;
var term = searchFieldTbx != null ? searchFieldTbx.Text : "";
if (term.Length > 0) //There is actually something in the input box we can work with
{
//Response.Redirect(Url.GetUrl("SearchResults", term));
Response.Redirect(ResolveClientUrl("~/Web/SearchResults.aspx?term=" + term + "&cat=" + navBarSearchCatHiddenField.Value));
}
}
Draw attention that we resolving client url when redirecting to search results page and instead of navBarSearchCatHiddenField use navBarSearchCatHiddenField.Value as cat parameter.
I guess that you use AJAX to fill the content of the tab. So in this case, content of your tab will be replaced by the new one from ajax and certainly _VIEWSTATE will be replaced. At server, do you use data from ViewState? In the "static tabs", you should prevent them auto reload by using cache:true
Your issue is that with your ajax call you bring in a complete ASPX page. Including the Form tag and its Viewstate. If you remove the Form tag from ajaxTab.aspx you will see everything works fine. asp.net does not know how to handle two Form tags in one page. Same goes for hidden Viewstate fields. You cannot bring in a full aspx page via ajax. Just bring in the content Div you want to display and you`ll be good to go.

Is there a way I continue on with a website while a file is being uploaded?

Background:
I am working on an undergrad research project for my CS department. The project is a website for the biology department and a key feature is that the biology students are able to upload their own .xml files and then a *model is built for them on the server side using Matlab.
The front end is in an ASP.NET, javascript and C# environment. My little association with this project is all the knowledge I have of these systems, tools and languages.
Question:
The .xml files I mentioned earlier can take hours to upload and build. My professor wants the user to be able to continue on with the page using models that are already completed while the new model is sent to the background and the user receives an email when it is completed. I've found material for sending the email, but not for continuing with the page.
I heard something about using AJAX to load a page?
Place a file upload control on your page
<asp:FileUpload ID="FileUpload1" runat="server"/>
Build an http handler to handle the file upload:
public class Handler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
HttpPostedFile fileToUpload = context.Request.Files["Filedata"];
string pathToSave = HttpContext.Current.Server.MapPath("~/Files/")
+ fileToUpload.FileName;
fileToUpload.SaveAs(pathToSave);
//Process file
}
public bool IsReusable {
get {
return false;
}
}
}
Take a look if you can integrate an upload plugin like uploadify into the project(needs jQuery).
<script type = "text/javascript">
$(document).ready(function()
{
$("#<%=FileUpload1.ClientID %>").uploadify(
{
'swf': 'Scripts/uploadify.swf',
'uploader': 'Handler.ashx',
'auto': true,
'buttonText': 'Select File(s)'
});
});
</script>
If you cannot do this, you need to understand how ajax works
Ajax normally uses XMLHttpRequest, which does not allow you encode and send local files to a server.
You could, either use a Flash swf to handle the uploading on the same page, or to use a form that has a target of an invisible 1x1 iframe.
I found the code posted on this blog about file uploads in asp.net
I think having a small i-frame open up, which will actually do the upload, will let your current page continue working.
So on your current page, you ask for file location and file name and all, then open a new page in an i-frame. Let that i-frame know the source file/folder, destination file/folder, and let it work in the background. So now your current page is free to continue its work.
Hope that helps.
Use a headless Java Upload Applet.
Load the file transfer applet in an iFrame, let the user initiate the file transfer and when a user wants to browse the rest of the website, just don't reload the iFrame containing the Java Applet (which will be uploading the file). After the transfer is complete, do a JAvaScript call to close the iframe.
The following example uses a Java Applet by FileCatalyst, but the idea will be practically with any other Java FTP Applet or ActiveX
<script>
var browsePath = "";
function browseAndAdd() {
browsePath = document.FileCatalyst.browseLive(true);
}
function upload() {
document.FileCatalyst.uploadLive();
}
function clearQueue() {
document.FileCatalyst.clearQueue();
}
</script>
<!--Uses onClick for demonstration only-->
<form id="uploadform">
<!--Launch a browse dialog and add the selected file to the queue-->
<input type=button onClick="javascript:browseAndAdd();" value="Browse and Add to Queue" />
<!-- Force upload of whatever is currently found in the transfer queue -->
<input type=button onClick="javascript:upload();" value="Upload">
<!-- Clear transfer queue (can be called only if no transfers are in progress) -->
<input type=button onClick="javascript:clearQueue();" value="Clear Queue">
</form>
Apologies for lack of indentation, I find the stackoverflow markup for inserting code snipets not very user friendly.
You need to set up somekind of asynchronous processing ideally. Personally I like to use Celery and RabbitMQ for my async and messaging.

Restrict file uploads so that only files smaller than 1 MB can be uploaded

I came across this question while studying for the Microsoft Web-Application Developer exam,
You are implementing a Web page that allows users to upload files to a Web server. The page includes a
form that has a Submit button.
You want to restrict uploads so that only files smaller than 1 MB can be uploaded.
The answer given was:
Add an ASP.NET FileUpload control and configure it to run on the server.
Add a server-side OnClick handler to the form's Submit button to save the file only if the file size is
allowed
But wouldn't this mean that the file would have already been uploaded to the server? and we are just choosing whether to save it or not? Can it be done on the client Side?
When doing file uploads there are a number of things you can check. On the server side, there is also the maximum request size, which will actually stop an upload. But you are correct, the upload will have been already performed by the time either of these checks are caught.
You can now use the HTML5 File API on supported browsers to be cleverer with file uploads, including retrieving the size of them on the client-side, and even displaying previews. See here for an example: Client Checking file size using HTML5?
using IE :
<html>
<head>
<script>
function getSize()
{
var myFSO = new ActiveXObject("Scripting.FileSystemObject");
var filepath = document.upload.file.value;
var thefile = myFSO.getFile(filepath);
var size = thefile.size;
alert(size + " bytes");
}
</script>
</head>
<body>
<form name="upload">
<input type="file" name="file">
<input type="button" value="Size?" onClick="getSize();">
</form>
</body>
</html>
using Chrome or Firefox :
With jQuery and the HTML5 File API specification implemented, you can use this simple snippet to access file properties such as size:
//binds to onchange event of your input field
$('#myFile').bind('change', function() {
alert(this.files[0].size);
});
Source : the excellent article on the topic here : http://www.kavoir.com/2009/01/check-for-file-size-with-javascript-before-uploading.html

can i upload a user-selected image to server using web service?

I am doing a ASP .NET website where among other things a user can upload an image, that needs to be saved to the server.
In the whole website I'm trying to accomplish as minimal communication between the client and server as possible. This means that on onload() I invoke web services which return all data needed for that page, and then manipulate them using javascript.
So far, it has worked flawlessly. The problem arises when a user wishes to make changes to his profile. I can take all the information entered in the text fields and the sort, and pass them as arguments to a webservice which saves them to the database. The thing I dont know how to do, or if it is even possible, is to pass the selected image as an argument to the webservice.
I am using html5: <input type="file"> for the image selection
If you use the asp:FileUpload control instead, when the user clicks submit you can do something similar to the following in the page's code-behind:
protected void UploadButton_Click( object sender, EventArgs e ) {
if ( !ImageUpload.HasFile ) {
return;
}
string imageBase64 = System.Convert.ToBase64String( ImageUpload.FileBytes );
YourService service = new YourService();
service.UploadImage( imageBase64 );
This assumes of course that your service has a method called UploadImage that takes a string as a parameter.
Then on the back end, convert the string to a byte array:
byte[] imageArray = System.Convert.FromBase64String( base64ImageData );
And save it as binary data to your database.
As a warning, you may want to add length checks on the webpage to prevent someone from uploading images that are too large... otherwise your server could be bogged down.
You should use a html formular. But you need to change some of the default configuration of the form-tag
<form action="url" method="post" enctype="multipart/form-data">
<input type="file" name="my-file" />
</form>
and you can use an iframe as target of the form, than the page does not reload. You can react on the iframe then...
<form ... target="youriframe">
see this website for a full example

dynamic file upload in c#

I have absolutely no idea on how to upload multiple files in asp.net using c#,with single upload button.Its not known in advance ,how many files are there.
Can somebody provide me the code in c#??I would be grateful.
Thanks in advance!!
Multiple uploads are not possible using a single upload control (you'll have to upload one file, then repeat the whole process again after the first file has been uploaded).
You can use an IFrame & some JS to rig up one such control which will allow you to upload multiple files at once (But then also, only one file will be posted to the server at a time, and its for the better, for the server).
Or you can use some third party controls created using Java technology (Applets) or in Flash.
This is an example using multiple textboxes and browse buttons to collect the paths of up to 5 files and then uploads them at once.
DotNetJunkies File Upload Tutorial
This one from MSDN uses the File Field Control to accomplish the same thing.
There is a lot of code in both of those articles that should get you well on your way.
You can create one upload input and have a button to add more dynamically using Javascript. When you click the save button, the files will all be in Request.Files.
<script type="text/javascript">
var uploadCount = 2;
function AddUpload()
{
var uploads = document.getElementById("uploads");
var id = "upload" + uploadCount;
uploads.innerHTML += ("<input type='file' id='" + id + "' name='" + id + "' />");
}
</script>
Add Upload
<div id="uploads">
<asp:FileUpload runat="server" ID="upload1" />
</div>
<asp:Button runat="server" ID="btnSave" Text="Save" />

Categories

Resources