Showing posts with label Asp.Net AJAX. Show all posts
Showing posts with label Asp.Net AJAX. Show all posts

Saturday, March 5, 2011

File uploading in chunks using HttpHandler and HttpWebRequest

How Do I? File uploading in chunks using HttpHandler and HttpWebRequest


This is a sample code that shows how to upload file using HttpHandler in chunks. This may not seems like a very good idea in isolation but this could help when creating a file upload control in Silverlight. I already have an article that shows how to upload file using web service in chunk. You can read this article here. When talk about file uploading using web service, it has many disadvantages like 1- it has a limit of sending and receiving data and 2- it pads data that increase the sending data, to name a few problems.

HttpHandlers are better in many ways; this technique could be used to enable huge files. It will understand the entire authentication and authorization constrains already implemented in your web application.
This article has two distinct parts
1- How to send data in chunks using HttpWebRequest
2- How to receive and save data in HttpHandler

Sending data in chunks
The implementation of HttpWebRequest is very simple. It has the following steps
1- Open a file
2- Start reading a chunk
3- Convert the chunk in Base64 String
4- Send the chunk to HttpHandler along with some basic file information e.g. file name

HttpWebRequest will post data to HttpHandler because of data limitation and sercurity of data in a Key-Value pair.

And here is the code
Function that will convert the file into chunk requests

private void ConvertToChunks()
{
 //Open file
 string file = MapPath("~/temp/1.xps");
 FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
 //Chunk size that will be sent to Server
 int chunkSize = 1024;
 // Unique file name
 string fileName = Guid.NewGuid() + Path.GetExtension(file);
 int totalChunks = (int)Math.Ceiling((double)fileStream.Length / chunkSize);
 // Loop through the whole stream and send it chunk by chunk;
  for (int i = 0; i < totalChunks; i++)
  {
    int startIndex = i * chunkSize;
    int endIndex = (int)(startIndex + chunkSize > fileStream.Length ?   fileStream.Length : startIndex + chunkSize);
    int length = endIndex - startIndex;

    byte[] bytes = new byte[length];
    fileStream.Read(bytes, 0, bytes.Length);
    ChunkRequest(fileName, bytes);
  }
}

Function that will send the chunk to httpHandler
private void ChunkRequest(string fileName,byte[] buffer)
{
 //Request url, Method=post Length and data.
 string requestURL = "http://localhost:63654/hello.ashx";
 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestURL);
 request.Method = "POST";
 request.ContentType = "application/x-www-form-urlencoded";

 // Chunk(buffer) is converted to Base64 string that will be convert to Bytes on  the handler.
 string requestParameters = @"fileName=" + fileName +
"&data=" + HttpUtility.UrlEncode( Convert.ToBase64String(buffer) );

 // finally whole request will be converted to bytes that will be transferred to HttpHandler
 byte[] byteData = Encoding.UTF8.GetBytes(requestParameters);

 request.ContentLength = byteData.Length;

 Stream writer = request.GetRequestStream();
 writer.Write(byteData, 0, byteData.Length);
 writer.Close();
// here we will receive the response from HttpHandler
 StreamReader stIn = new StreamReader(request.GetResponse().GetResponseStream());
 string strResponse = stIn.ReadToEnd();
 stIn.Close();
}

Receiving and saving Chunk data in HttpHandler
It will
1- Receive the chunk and file information
2- Convert back the chunk to byte[] from Base64 string
3- Save the chunk by
a. Creating a new file if file not existed
b. Opening the existing file

Here is the Code

Function that will receive the request in HttpHandler
public void ProcessRequest(HttpContext context)
{
 //write your handler implementation here.

 string fileName = context.Request.Params["fileName"].ToString();
 byte[] buffer = Convert.FromBase64String ( context.Request.Form["data"]);
 SaveFile(fileName, buffer);
}
Function that will Save the file

public void SaveFile(string fileName, byte[] buffer)
{
 string Path = HttpContext.Current.Server.MapPath("~/upload") +"\\"+ fileName;
 FileStream writer = new FileStream(Path,File.Exists(Path)?FileMode.Append:FileMode.Create, FileAccess.Write);

 writer.Write(buffer, 0, buffer.Length);
 writer.Close();
}

To use HttpHandler, it must be configured in web.conf like shown below
<add verb="*" path="*.ashx" type="handlertest.IISHandler1, handlertest"/>

Hope this will help , Please click here to download the sample application. Please see the Default.aspx.cs for HttpWebRequest section and IISHandler1.cs for HttpHandler section.

Monday, October 5, 2009

Asp.Net Ajax PageMethods

How Do I? use PageMethods in Asp.Net


PageMethods are asp.net way of light weight Ajax communication. Update panels are known for rapid development and ease of use but they have worst performance and speed issues. AJAX is associated with performance and update panel is performance killer. It lacks speed and heavy on the wire.

Let’s face it; Update panel is designed to follow the normal asp.net page life cycle. This makes sure ease of use but not performance and speed.

But there is a way of performance and speed in asp.net Ajax we just need to learn living without update panels and start doing some manual work.

PageMethods are designed in such a way, we can easily start using them by following simple steps but there are also some things developers should know before using them.

PageMethods are static

that implies

1- They don’t follow asp.net life cycle

2- They can’t use global variables other than static variables

ALERT

Don’t use static variable, they are shared among all users and have the scope of application variables.

Why PageMethods are static?

1- Static methods can be called without initializing the class they are in that’s why they don’t require to follow the asp.net page life cycle

2- To overcome the update panel and callback way of communication; both these methods sends all the viewstate in request and follows the normal page life cycle that starts from page load method not from the calling functions.

How to implement PageMethods

Now you just require following step by step guide to start using page methods. In this tutorial, I will show you how you can wrote a simple PageMethod, use it efficiently in your code and in next tutorial, I will show you how you can send more complex data in page methods.

So let’s begin this journey;

Step 1:

Create a new project in either visual web developer or visual studio

Step 2:

Add the assembly to use with page method


Step 3:

Write the method. This method as shown in the below image will take the first name as the argument and will greet the user if name present of throw and exception if null or empty.

Step 4:

Add script manager with EnablePageMethods=”true”


Step 5:

Add html text box and button to take user input of first name and then call server with this value


Step 6:

Write java script to call the page methods.


As you can see in this picture, I have a method callPageMethods and this method takes the value from text box and call server with this. Calling PageMethods requires 3 parameters

1- Argument that will be passed to PageMethods on the server

2- A function name that will receive the result when this call will executed successfully

3- A function name that will receive the error in case of unexpected happen or you program your exceptions to throw, in this example I have thrown the exception if I used didn’t input his/her name in text box.

Results:


As you can see, first time I did enter my first name and it throws the exception and javascript function onFail cached this error and alert the error.

In this picture you can see the successfully hello world method is executed and I have received the message in alert box.

I have these screen shots of firebug to show you how much data is transferred.

1- Post


Only few Bytes

This picture also highlited the error as shown in firebug. This is not an error. This was the exception thrown by the server when i didnt enter the first name and hit the submit button. This is a handled exception and handled exceptions are GOOD ONES.

2- Response


Only few Bytes as well

That’s the benefit of PageMethods we are not sending receiving too much data as in case of update panel or call back when whole viewstate along with other fields post to server and user has to wait for longer time as request will go through whole asp.net page life cycle and then results will be sent back to client.

In next tutorial, I will show you how you can send more complex data using PageMethods and I will discuss the JSON as the whole communication of PageMethods is done through JSON format.