ASP .NET PageMethods - File Upload - asp.net

I am trying to create an ajaxy file upload.
Here is the asp code:
<input type="file" id="supportingDocs" runat="server"/>
<input type="button" id="uploadBtn" onclick="upload();" value="Upload"/>
Here is the javascript:
function upload()
{
PageMethods.uploadFile($get('supportingDocs').value, onSucceed, onFail);
}
Here is the relevant C# code:
[WebMethod]
[ScriptMethod]
public static string uploadFile(string files) {
HttpRequest request = HttpContext.Current.Request
........
}
What I am trying to get is the HttpFilesCollection from the request which is empty. I know that PageMethods do not follow the normal asp .net lifecycle. However looking at the HttpRequest object while stepping through the code in debugging I see that everything else in the request is there but the "Files" property is empty. I'm probably missing something here and this method of uploading files might not even be possible.

You could always just use the one provided by the AjaxControlToolkit, i.e. ASyncFileUpload

You could consider the jquery plugin: http://www.uploadify.com/
The file upload control works by sending a post request back to the server with the file contents. That is how the file upload is built. with that said, I'm not sure how the inner workings of all these file upload plugins operate, but out of the box even with ASP.NET AJAX services, it may be better to consider some other service.
If you wanted to use a service, you could try the Sys.Net.WebServiceProxy.invoke method, which gives you control over the post, serialize the form data to post to the server. Again, that's in theory, I'm not 100% sure how this all works through AJAX.
HTH.

If you want to upload a file without a full postback, try SWFUpload. It has a very nice file browser option and other features, unlike ASP.NET AJAX AsyncFileUpload which looks very limited.
SWFUpload demo: http://demo.swfupload.org
A popular jquery option is uploadify, see this stackoverflow post.
I never was able to get asynchronous file upload working without flash.
Update
This post claims that AsyncFileUpload doesn't use flash, so that may be an advantage over uploadify and SWFUpload.

Ok so I ended up using both the asp async upload and page methods.
The AsyncFileUpload worked well for actually saving the file on the server but I still needed to run some server-side code to write out the DB and also list the current files uploaded to the server. Unfortunately anything you change client-side will not get rendered since there is no post-back after the upload. So I just set the OnClientUploadComplete to a JS function that uses a page method.
ASP Code:
<asp:AsyncFileUpload ID="asyncFileUpload" runat="server" OnUploadedComplete="uploadFile" OnClientUploadComplete="showUploadedFiles" ThrobberID="uploading"/>
Javascript:
function showUploadedFiles()
{
PageMethods.getUploadedFiles(onSucceed, onFail);
}
function deleteDoc(docId)
{
PageMethods.deleteDocument(docId, onSucceed, onFail);
}
function onSucceed(result, userContext, methodName)
{
$get('uploadedFiles').innerHTML = result;
}
function onFail(error, userContext, methodName)
{
$get('uploadedFiles').innerHTML = "<p style='color: red;'>AJAX Error!</p>";
}

Related

Put autocomplete methods in separate web file?

I have a web site with a growing number of AJAX calls.
I have AJAX code that looks like this:
function setupNameAutocomplete(id) {
$(id).autocomplete({
source: function(request, response) {
$.ajax({
url: "selectName.aspx/getNameAutocomplete",
....
Originally, the above javascript code was used on a web page where a user typed in the name of a person to search for; I decided I wanted to have autocomplete on the name.
However, as I continued to develop the web site, I decided that I wanted to be able to use the same "name" autocomplete on many pages. Logically, it made sense to put my javascript code in an external .js file instead of repeating it on every page.
It also makes sense that I would want to put the .net code that handles the AJAX in its own file as well. The .net autocomplete code looks like this:
[WebMethod]
public static IEnumerable<string> getNameAutocomplete(string text)
{
IEnumerable<string> values = lookupNamesThatStartWith(text);
return values;
}
Naturally, it seemed like this codes belongs in an external .asmx or perhaps a .ashx file, but I can't get my javascript code working unless I call the above code from selectName.aspx.
How can I get my AJAX .net code in a separate code file?
If I understand your problem correctly, a viable solution would be to have a base class that your services inherit from that would implement the generic WebMethod.
That, or you could get it "pretty clean" by having the logic of the autocomplete lookup abstracted into a class and just call it from your WebMethods each time, as needed.

AJAX Toolkit - AsyncFileUpload Control Return Data

I am using the AsyncFileUpload control provided by the Ajax Toolkit. I am needing to store the file uploaded in a temporary directory and then return the temporary file name back to the client (or set viewstate) so that on the next post back it can be committed to a database.
Does anyone have any ideas as the best approach to do this, if even possible?
Yes. It is possible.
OnClientUploadComplete is fired on the client-side after the upload has completed. Then just use get_fileName() to return the name of the file being uploaded.
Example:
function uploadCompleted(sender, args)
{
alert(args.get_fileName());
}

ASP.net - Multiple Upload with jQuery Multiple File Upload Plugin

I know how to upload with ASP.net's FileUpload control.
What I want to do is use this jQuery Multiple File Upload Plugin to upload multiple files.
Here is exactly what it does when multiple files are selected for upload:
<input type="file class="multi MultiFile" id="MultiFile1_F3" name="file1[]" style="position: absolute; top: -3000px;">
But I cannot figure out how to manipulate these files from asp.net.
I have tried using Request.Files as the following link instructs:
ASP.Net Upload of multiple files after choosing them from jQuery
That doesn't work. I think that only works for controls marked with runat="server" at compile time.
Does anyone know how to do this? Maybe something in Request.Form...?
Thanks for your help!
Two things to check:
Make sure your form has the enctype="multipart/form-data" attribute set. This is required to enable uploads.
Make sure all file inputs have both id and name attributes set. For some reason, if you don't set both, wierd things happen.
Also, runat="server" shouldn't have anything to do with whether Request.Files works or not -- this is more an issue of the browser actually posting the files.
This jQuery plugin was giving every generated input control the exact same name attribute.
For this reason, the files were not posting.
I built my own javascript solution.
I will post a link to the code in a comment.
Edit
I revisited this and found that what I was trying to do wasn't very difficult at all. I got the the jquery multiple file upload plugin to work fine with my aspx form. I don't know why I was having so much trouble before.
1.) Include the jQuery library on the web form:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript" />
2.) Reference the multiple file plugin on the web form (Download it here):
<script src="jquery.MultiFile.pack.js" type="text/javascript">
3.) Add a file input on your web form with class="multi":
<input type="file" class="multi" />
4.) Execute some code or call a method like this on form submission:
void SendMail(string from, string to, string subject, string body, string smtpServer)
{
// create mail message
MailMessage mail = new MailMessage(from, to, subject, body);
// attach posted files
for (int i = 0; i < Request.Files.Count; i++)
{
HttpPostedFile file = Request.Files[i];
mail.Attachments.Add(new Attachment(file.InputStream, file.FileName));
}
//send email
new SmtpClient(smtpServer).Send(mail);
}
This is all that I had to do to attach multiple files to an email sent from an aspx page.
If you want to increase the total size of the files that can be uploaded, add this to your web.config file:
<system.web>
<httpRuntime executionTimeout="240" maxRequestLength="30720"/>
</system.web>
The executionTimeout is measured in seconds and maxRequestLength is measured in kilobytes. In this example, the request will timeout after 4 minutes and will allow a 30mb request.
It's been a bit since I did that kind of thing in .NET, but once you begin cloning form inputs dynamically, I think you have to go out to Request.Form and find the submitted values manually. I wrote up the jQuery code to clone some (non-file) inputs with sequential identifiers here. As long as you have unique identifiers, you can run a loop to see if Request.Form["MultiFile1_F" + counter] exists and go from there.
I highly recommend Uploadify as a mulitple file uploader. It uses jquery and flash to allow the user to upload multiple files at once through ctrl + clicking on all desired files. It then displays a queue of the files uploading and removes the file from the queue on completion. It also allows you to specify which extension to allow the user to upload as well which prevents you from having to do extension validation.
EDIT:
If you dont want to use flash Ajax Upload works really well too. If users on my site company's site dont have the right version of flash that works best with uploadify, I switch to Ajax Upload. They both work very well for me.

AJAX+ASP.NET

As far i learned ....AJAX is used for partial page refresh (overcoming the flickering effect in the web page) ....Is there any other features in AJAX....
Technically Yes. Ajax is used for "partial page" refresh there by eliminating the complete page refresh. There are 2 main advantages
Data transfer : Data transfer (To and from the server) is less compared to the entire page refresh
Better User experience : Since the user will not be seeing a blank page it gives the user an illusion of interacting with the site.
What can be done using AJAX is an ever ending list.
Ex: Gmail uses AJAX for it email. If you are using gmail and compare it with other email providers you will know the difference.
Facebook has rich AJAX features in its site.
SO uses AJAX for comments
I think What AJAX cannot do will be easier to mention. For example
AFAIK web browsers cannot maintain the view state of the AJAX enabled website.
Some AJAX enabled websites do not render properly in mobile browsers.
Anythign more?
Your question is a bit confusing, but you can do Ajax with ASP.NET. You can do partial page refreshes with Ajax among other things using the UpdatePanel in ASP.NET. You may also want to look at jQuery for a simpler more lightweight Ajax solution.
I think you're very mistaken. If AJAX had been created only to solve the problem of partial page refresh/page flickering, it would not have revolutionized the web in the way it has.
The single biggest advantage offerred by AJAX is Client-to-Server Communication that is initiated based on some action on the client. This instantly gives us the ability to make the web much more responsive and user friendly without users having to wait for page reloads and postbacks.
I would suggest that you spend some time researching the subject. Read up on the Wiki article on AJAX.
As far as ASP.NET is concerned, AJAX integrates very well into it. Mature AJAX frameworks such as ASP.NET AJAX and Anthem.NET obfuscate much of the internal details of the XmlHttpRequest.
Ajax has let me add some great new features to my web applications with the free Ajax toolkit. See the link
Ajax Examples
They do not come with out their issues but once you learn how to use them they can really add to the the users experience in you site.
ASP.NET uses as you know UpdatePanel for partial page refresh using AJAX.
A less known feature is something .NET calls web methods. This is really AJAX calls that is not connected to the GUI part of the page. You can declare (server-side) a method as a WebMethod, and in the client side, you can call that using JavaScript.
Example:
This example shows how to get the value of a session variable. Note that the method must be Shared - which means that it does not know of any member values on the page object.
As for all ASP.NET AJAX functionality, you need to have a ScriptManager element on the page. To enable page methods, you also need to add EnablePageMethods="true" to the ScriptManager like this:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" />
Server side code (VB):
<Services.WebMethod()> Public Shared Function GetPreviewImages() As String
Dim lPreviewImages As String = HttpContext.Current.Session("mPreviewImages")
If lPreviewImages IsNot Nothing Then
Return lPreviewImages
Else
Return ""
End If
End Function
Client side code:
//Declare the return methods:
function GetPreviewImages_Success(result, userContext, methodName) {
alert(result);
}
function GetPreviewImages_Failed(error, userContext, methodName) {
var errorMessage = 'Error in map server method ' + methodName ;
if(error !== null) errorMessage += '\n' + error.get_message();
alert(errorMessage);
}
// Call the page method:
PageMethods.GetPreviewImages(GetPreviewImages_Success, GetPreviewImages_Failed);
See also example in C#, which also includes how parameters work in the web method.

ASP.NET JavaScript Callbacks Without Full PostBacks?

I'm about to start a fairly Ajax heavy feature in my company's application. What I need to do is make an Ajax callback every few minutes a user has been on the page.
I don't need to do any DOM updates before, after, or during the callbacks.
I don't need any information from the page, just from a site cookie which should always be sent with requests anyway, and an ID value.
What I'm curious to find out, is if there is any clean and simple way to make a JavaScript Ajax callback to an ASP.NET page without posting back the rest of the information on the page. I'd like to not have to do this if it is possible.
I really just want to be able to call a single method on the page, nothing else.
Also, I'm restricted to ASP.NET 2.0 so I can't use any of the new 3.5 framework ASP AJAX features, although I can use the ASP AJAX extensions for the 2.0 framework.
UPDATE
I've decided to accept DanP's answer as it seems to be exactly what I'm looking for. Our site already uses jQuery for some things so I'll probably use jQuery for making requests since in my experience it seems to perform much better than ASP's AJAX framework does.
What do you think would be the best method of transferring data to the IHttpHandler? Should I add variables to the query string or POST the data I need to send?
The only thing I think I have to send is a single ID, but I can't decide what the best method is to send the ID and have the IHttpHandler handle it. I'd like to come up with a solution that would prevent a person with basic computer skills from accidentally or intentionally accessing the page directly or repeating requests. Is this possible?
If you don't want to create a blank page, you could call a IHttpHandler (ashx) file:
public class RSSHandler : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
context.Response.ContentType = "text/xml";
string sXml = BuildXMLString(); //not showing this function,
//but it creates the XML string
context.Response.Write( sXml );
}
public bool IsReusable
{
get { return true; }
}
}
You should use ASP.Net Callbacks which were introduced in Asp.Net 2.0. Here is an article that should get you set to go:
Implementing Client Callbacks Programmatically Without Postbacks in ASP.NET Web Pages
Edit: Also look at this:
ICallback & JSON Based JavaScript Serialization
What do you think would be the best method of transferring data to the IHttpHandler? Should I added variables to the query string or POST the data I need to send? The only thing I think I have to send is a single ID, but I can't decide what the best method is to send the ID and have the IHttpHandler handle it. I'd like to come up with a solution that would prevent a person with basic computer skills from accidentally or intentionally accessing the page directly
Considering the callback is buried in the client code, it would take someone with equal determination to get either the querystring or the POST request. IE, if they have firebug, your equally screwed.
So, in that case, do whatever is easiest to you (Hint: I'd just use the querystring).
To handle repeating requests/direct access, I'd generate a key that is sent with each request. Perhaps a hash of the current time (Fuzzy, I'd go down to minutes, but not seconds due to network latency) + the client IP.
Then in the HTTPHandler, perform the same hash, and only run if they match.
You are not just restricted to ASP.NET AJAX but can use any 3rd party library like jQuery, YUI etc to do the same thing. You can then just make a request to a blank page on your site which should return the headers that contain the cookies.
My vote is with the HTTPHandler suggestion as well. I utilize this often. Because it does not invoke an instance of the page class, it is very lightweight.
All of the ASP.NET AJAX framework tricks actually instantiate and create the entire page again on the backend per call, so they are huge resource hogs.
Hence, my typical style of XmlHttpRequest back to a HttpHandler.
Since you are using only ASP.NET 2.0 I would recommend AjaxPro will which create the .ashx file. All you have to do is to pull the AjaxPro.dll into your web site. I developed an entire application with AjaxPro and found it worked very well. It uses serialization to pass objects back and forth.
This is just a sample on how to simply use it.
namespace MyDemo
{
public class Default
{
protected void Page_Load(object sender, EventArgs e)
{
AjaxPro.Utility.RegisterTypeForAjax(typeof(Default));
}
[AjaxPro.AjaxMethod]
public DateTime GetServerTime()
{
return DateTime.Now;
}
}
}
To call it via JavaScript it is as simple as
function getServerTime()
{
MyDemo._Default.GetServerTime(getServerTime_callback); // asynchronous call
}
// This method will be called after the method has been executed
// and the result has been sent to the client.
function getServerTime_callback(res)
{
alert(res.value);
}
EDIT
You also have to add
To the config. AjaxPro also works well side by side with APS.NET Ajax and you can pass C# objects from Client to Sever if the class is marked as [Serializable]
Just to offer a different perspective, you could also use a PageMethod on your main page. Dave Ward has a nice post that illustrates this. Essentially you use jQuery ajax post to call the method, as illustrated in Dave's post:
$.ajax({
type: "POST",
url: "Default.aspx/GetFeedburnerItems",
// Pass the "Count" parameter, via JSON object.
data: "{'Count':'7'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
BuildTable(msg.d);
}
});
No need for Asp.Net Ajax extensions at all.
You should use a web service (.asmx). With Microsoft's ASP.NET AJAX you can even auto-generate the stubs.
You can also use WebMethods which are built into the asp.net ajax library. You simply create a static method on the page's codebehind and call that from your Ajax.
There's a pretty basic example of how to do it here

Resources