Friday, May 27, 2011

ASP.NET server side handler for Valums Ajax file upload ; file uploader supports multiple file upload with progress bar , drag-and-drop

This ajax uploader uses XHR for uploading multiple files with progress-bar in FF3.6+, Safari4+, Chrome and falls back to hidden iframe based upload in other browsers, providing good user experience everywhere. You can also see php demo in Valums site http://valums.com/ajax-upload/
The current implementation has server side handler for java, php and Perl. But does not exist Asp.net handler. Here I have implemented a Asp.net handler for ajax file upload that supports  IE, Firefox and Chrome.
Problem is IE use context.Request.Files[] for sending file to server. But Firefox and Chrome use Context.Request.InputStream. So in handler you need to check both for reading stream.
For Firefox and Chrome you get fileName from header like
String filename = HttpContext.Current.Request.Headers["X-File-Name"];
Code that work in Firefox and Chrome
//This work for Firefox and Chrome.
Stream inputStream = HttpContext.Current.Request.InputStream;
FileStream fileStream = new FileStream(mapPath + "\\" + filename, FileMode.OpenOrCreate);
inputStream.CopyTo(fileStream);
fileStream.Close();
context.Response.Write("{success:true, name:\"" + filename + "\", path:\"" + path + "/" + filename + "\"}");
But for IE you need to use
HttpPostedFile uploadedfile = context.Request.Files[0];
Code that work for IE browser :
HttpPostedFile uploadedfile = context.Request.Files[0];
filename = uploadedfile.FileName;
uploadedfile.SaveAs(mapPath + "\\" + filename);
context.Response.Write("{success:true, name:\"" + filename + "\", path:\"" + path + "/" + filename + "\"}");
Here the response is send as JSON string and you will get JSON object as response. you need to send {success:true} to make ajax upload understand that file upload is successful otherwise you can send false.

Complete code is:
public void ProcessRequest(HttpContext context)
      {
          const string path = "Capture/Images";
          String filename = HttpContext.Current.Request.Headers["X-File-Name"];
          if (string.IsNullOrEmpty(filename) && HttpContext.Current.Request.Files.Count <= 0)
          {
              context.Response.Write("{success:false}");
          }
          else
          {
              string mapPath = HttpContext.Current.Server.MapPath(path);
              if (Directory.Exists(mapPath) == false)
              {
                  Directory.CreateDirectory(mapPath);
              }
              if (filename == null)
              {
                  //This work for IE
                  try
                  {
                      HttpPostedFile uploadedfile = context.Request.Files[0];
                      filename = uploadedfile.FileName;
                      uploadedfile.SaveAs(mapPath + "\\" + filename);
                      context.Response.Write("{success:true, name:\"" + filename + "\", path:\"" + path + "/" + filename + "\"}");
                  }
                  catch (Exception)
                  {
                      context.Response.Write("{success:false}");
                  }
              }
              else
              {
                  //This work for Firefox and Chrome.
                  FileStream fileStream = new FileStream(mapPath + "\\" + filename, FileMode.OpenOrCreate);
                  try
                  {
                      Stream inputStream = HttpContext.Current.Request.InputStream;
                      inputStream.CopyTo(fileStream);
                      context.Response.Write("{success:true, name:\"" + filename + "\", path:\"" + path + "/" + filename + "\"}");
                  }
                  catch (Exception)
                  {
                      context.Response.Write("{success:false}");
                  }
                  finally
                  {
                      fileStream.Close();
                  }
              }
          }
      }

Complete solution is available in codeproject http://www.codeproject.com/KB/aspnet/AspNetHandlerAjaxUpload.aspx

Saturday, May 14, 2011

JQuery context menu items active/ deactivate for .NET TreeView

I was needed to give some functionality to .NET tree view for user so that user can add, edit, activate or deactivate node. Jquery context menu is very nice and give me functionality to customize context menu according to my requirement. My requirement was to make some items active based on image of treeview. .NET treeview use table structure. if the node contain is <td> wich id is ‘xyz_01’ then image <td> id will be ‘xyz_01i’ . Based on this I find the image element and according to source of image I have changed the active menu items on mousedown event. MouseDown event work before displaying jquery context menu. The code is given here.

Context menu div is

<ul id="myMenu" class="contextMenu"> 
<li class="copy"><a href="#add">Add</a></li>
<li class="edit"><a href="#edit">Edit</a></li>
<li class="inactive"><a href="#Inactive">Inactivate</a></li>
<li class="active"><a href="#Active">Activate</a></li>
<li class="quit separator"><a href="#cancel">Cancel</a></li>
</ul>



The mouse down code for activate and deactive element according to treeview image source.




$("#MyTreeDiv A").mousedown(function () { 
var itemId = $(this).attr('id');
var imageItemId = itemId + 'i';

var img = $('#' + imageItemId).children('img').first();
var s = $(img).attr('src');
if (s.indexOf('inactive') > -1) {
$('#myMenu').enableContextMenuItems('#Active');
$('#myMenu').disableContextMenuItems('#Inactive');
$('#myMenu').disableContextMenuItems('#add');
$('#myMenu').disableContextMenuItems('#edit');
}
else if (s.indexOf('active') > -1) {

$('#myMenu').disableContextMenuItems('#Active');
$('#myMenu').enableContextMenuItems('#Inactive');
$('#myMenu').enableContextMenuItems('#add');
$('#myMenu').enableContextMenuItems('#edit');
}

});