ASP.NET AJAX LIKE Fileupload using IOFRAME and Javascript Callback

As of now there are no direct way to make ASP.NET File-uploading work in partial page update manner. This was due to protocol and security constraint in file-uploads.

Many techniques out there to make ASP.NET File Uploading without full page post back, one such technique is using hidden Iframe. Here I am going to walk you through to develop an AJAX like partial page update file upload with other common controls such as text box in a ASP.NET page using IOFrame, the hidden IFRAME is often called as IOFrame by AJAX library authors. This IOFrame technique is slightly different from the other iframe techniques out there in the Internet.

Before I delve in to the technique, I would like to give a quick brief on How I found this technique. I got to know about ASP.NET free webgrid control through dotnetslackers newsletter and then I explored their online samples, one of their samples has got asynchronous file-uploading, I was curious and fired my firebug to profile the embedded javascript codes in it, yeah great I found the technique how they achieved out of the box, yes it was ANTHEM.NET framework that supports asynchronous file upload. After studying anthem.net java-script codes I am able to develop this ASP.NET asynchronous file upload sample.

TECHNIQUE:

IOFRAME

1. Create an usual asp.net form with file-upload control in it

2.Name the form as you like [name=”aspNetForm”]

3.On submit buttom click, call custom javascript and return false to avoid postback

4. In the custom javascript code, create an iframe and set its key properties

5. Attach the iframe in the body of the parent window

6. Get the form object of the parent window and assign it to the just created iframe’s form object

7. Set other key properties of iframe [refer source code] i.e name, id, target, action

8.Attach a callback function in iframe’s onload event[ i.e. iframe.onload = function (){ callback(“ifra”); } ]. The callback is implemented in the parent window/form i.e. the code for the callback is at parent form

9. submit form [iframe’s form] and return false to avoid postback

CALLBACK:

2. The just submitted iframe gets processed

2.Upon completion [success/error] set the values of the result in an hidden variable [or] any other mechanism of your convenience in the iframe.

3. After the server side processing completes, the iframes javascript onload gets triggered while rendering processed HTML output.

4. In the onload event, it executes the function referred in the parent window [call back], equivalent of delegates in .Net. This is the key thing to grasp this technique.

5. From iframe the parent windows function gets executed with out referening parent.<functionname>

6. In the callback function [parent form], get the reference of the iframe object

7. From the iframe object, get the reference of the iframe’s contentDocument [Netscape] / contentWindow[IE]

8.From the contentDocument [Netscape] / contentWindow[IE] now we have access to its DOM elements i.e. document.getElementByTagId(“hidden/…”)

9. Get the response of the upload we assigned in the hidden field [any other variable] in the iframe and process the parent window [put your business logic]

10. finally remove the iframe

Live Demo

Download ASP.NET Project [Also included HTML version of the sample to demonstrate client callback]

Note:

In my live Demo, fileupload opens a new window in Internet Explorer & this was because the way I am attaching the IO frame in to the DOM. Please download the updated javascript file to get away opening up new IE window. Also included the entire javascript inline here

//Note: The logic behind this code are used from ANTHEM.JS [ANTHEM.NET] and some of the JS methods used here are copied from anthem.js
//http://www.koders.com/javascript/fidDEA7EA7869F327B1610632C5A89D895B726DB8AC.aspx

//--------------------------------------------------------------------------
//                      MAIN FUNCTION
//Post() gets called upon Submit button's click [Button2]
//--------------------------------------------------------------------------

    function post(){
    //initialize the display
    document.getElementById("Button2").disabled=true;
    document.getElementById("lblResponse").className="Hidden";
    document.getElementById("photo").src='#';
    document.getElementById("photo").alt='No Image';

    //create iframe and set its core properties

    action = "?ifra=1";

    var id='ifra';
     // Create a new, invisible iframe to handle the io.
 var ioframe = null;
 if (window.ActiveXObject) {
 ioframe = document.createElement("");
 } else {
    ioframe = document.createElement("iframe");
    ioframe.id = "ifra";
    ioframe.name = "ifra";
    ioframe.onload = function (){ Anthem_HandleIOFrameResponse("ifra"); } //Attach Callback function
 }

        ioframe.style.visibility = "hidden";
        ioframe.style.height = "1px";
        document.body.appendChild(ioframe);
         var theForm = Anthem_GetForm();
        var tempActionUri = theForm.action;
        theForm.action = tempActionUri + action;
        theForm.target =id;

        try {
theForm.submit();
 } catch (e) {
}

        theForm.target = "";
        theForm.action = tempActionUri;
    return false;
    }

//--------------------------------------------------------------------------
//                      UTILITY FUNCTION
//--------------------------------------------------------------------------

// Returns form object
    function Anthem_GetForm() {
    var form = document.getElementById("aspnetForm");
    return form;
}    

// Returns the iframe document
function Anthem_ExtractIFrameDocument(iFrameEl) {
  var doc = null;
  if (iFrameEl.contentDocument) { // For NS6
    doc = iFrameEl.contentDocument;
  } else if (iFrameEl.contentWindow) { // For IE5.5 and IE6
    doc = iFrameEl.contentWindow.document;
  } else if (iFrameEl.document) { // For IE5
    doc = iFrameEl.document;
  } else {
    //alert("Error: could not find iFrame document");
    return null;
  }
  return doc;
}

//--------------------------------------------------------------------------
//                      CALLBACK FUNCTION
//--------------------------------------------------------------------------

// This function is called by the onload event of the IOFrame after the
// callback response is received. The function parses the response, updates
// the page, and invokes the clientCallBack function.
function Anthem_HandleIOFrameResponse(frameid) {

    alert('ererer');
    var iframe = document.getElementById(frameid);
    if (iframe != null) {

        var doc = Anthem_ExtractIFrameDocument(iframe);
         document.getElementById("lblResponse").innerHTML=doc.getElementById("HiddenField1").value;
         alert(doc.getElementById("HiddenField1").value);
         document.getElementById("lblResponse").className="Visible";
         document.getElementById("Button2").disabled=false;

        if(doc.getElementById("HiddenField2").value !=""){
            document.getElementById("photo").src='u/' + doc.getElementById("HiddenField2").value;
            document.getElementById("photo").alt=doc.getElementById("HiddenField2").value;
        }
       setTimeout("document.body.removeChild(document.getElementById(\"" + frameid + "\"))", 10);
    }
}

18 thoughts on “ASP.NET AJAX LIKE Fileupload using IOFRAME and Javascript Callback

  1. Hi,

    Its simply superb.. i have no words to explain when i saw it working fine.. what i expected…..:-)

    But at lost it failed to work for me…:-(
    It throws me error, ERROR LOADING WHILE POSTBACK..
    I am totally stucked..

    I am using callbacks in my application..

    I don’t know which is problem..

    Can u help me..

    Thanks

    Like

  2. Hi,
    Hope you cracked the problem or else send me the code, let me check it up.

    Note:
    Appreciate if you can eloborate the issues facing.

    Like

  3. I dea seems simply amazing.

    but I am getting JAVA script Access Denied Error.
    in the line where it says
    theForm.submit();

    Can you help me with it?

    Thanks in advance.

    Like

  4. Hi,
    I tried your demo project with modified javascript which is given. But still postback is happening.
    Please let me know if there is any way to avoid postback.

    Thanks,
    Nagaraju.K

    Like

  5. IE7 flawless.. However, I’m having a tough time get this to work with Firefox. It opens with a new browser window with no postback.

    I think this idea could ultimately replace all of the asp.net ajax file upload controls out there. But it definitely needs cross browser support.

    Like

  6. Scratch my last comment, it seems I failed to replace the js file with the one listed on the site.

    Simply amazing…
    Anyone looking for a asp.net Upload control… This is it.

    Just change your FileUpload control to have a javascript postback.

    Cheers!

    Like

  7. Dear Senthil,

    Thank you for the such good article. However it doesn’t work correctly with Firefox 3.0. . Here it opens a new window and also doesn’t update the response.

    Regards,
    Sachin

    Like

  8. hi, really amazing code works fine. but for me it is not working….
    i took form inside one folder and need to save image in another folder. while script executing the image is not displaying. eventhough i changed the path in script file( u/”) to (../u/) . please help me inthis regard how to specify the path in script…..

    i also tried to server map path in code behind file ….to that hidencontrol2. even though it is not showing the image. but i am getting full path of that image as alternat text.

    Like

  9. Hi,
    I tried your demo project with modified javascript which is given. But still postback is happening.
    Please let me know if there is any way to avoid postback.

    Regards
    Mohammad Javed

    Like

  10. hi,
    I wrote the following function and call this body onunload event.Then parent page refresh.

    function Self()
    {
    window.opener.parent.location=’Home.aspx’;
    self.close();
    }

    Regards
    Mohammad Javed

    Like

  11. using System;
    using System.Configuration;
    using System.Data;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml;

    public partial class _Default : System.Web.UI.Page
    {
    string XPath = System.Configuration.ConfigurationSettings.AppSettings[“XMLPath”].ToString();
    DALContactDetails ObjContactDetils;
    protected void Page_Load(object sender, EventArgs e)
    {

    if (Session[“ApplicationID”] == null)
    {
    Response.Redirect(“InformationPage.aspx”,false);
    }
    int AppID=0;
    if (Session[“ApplicationID”] != null)
    {
    AppID = int.Parse(Session[“ApplicationID”].ToString());
    Image ImG = (Image)this.FindControl(“Head1”).FindControl(“imgHome”);
    ImG.Attributes.Add(“onclick”, “return Redirect(‘” + AppID + “‘);”);
    if (!IsPostBack)
    {
    FillPermanent_Country();
    FillPresent_Country();
    FillContactDetails(int.Parse(Session[“ApplicationID”].ToString()));
    }
    }
    btnNext.Attributes.Add(“onclick”,”return ContactDetails()”);
    chkCopy.Attributes.Add(“onclick”, “CopyContactInfo();”);
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
    int error=INSERTUPDATE();
    if (error == 0)
    {

    }
    }

    private void FillPresent_Country()
    {
    string arr = “”;
    string arr1 = “”;
    int count = 0;
    XmlDocument objXmlDoc = null;
    try
    {
    objXmlDoc = new XmlDocument();
    objXmlDoc.Load(XPath + “Country.xml”);

    XmlNodeList objNodes = objXmlDoc.GetElementsByTagName(“Country”);

    if (ddlCountry.Items.Count != 0)
    {
    }
    else
    {
    foreach (XmlNode objNode in objNodes)
    {
    arr = objNode.Attributes[“Text”].Value.ToString().Trim();
    arr1 = objNode.Attributes[“Value”].Value.ToString().Trim();
    ddlCountry.Items.Insert(count, arr);
    ddlCountry.Items[count].Value = arr1;
    count += 1;
    }
    }
    }
    catch (System.Threading.ThreadAbortException)
    {

    }
    catch (Exception ex)
    {
    Session[“ErrorMessage”] = ex.Message.ToString();
    Response.Redirect(“Error.aspx”, false);
    }
    finally
    {
    objXmlDoc = null;
    }
    }
    private void FillPermanent_Country()
    {
    //Load XML for Levels
    string arr = “”;
    string arr1 = “”;
    int count = 0;
    XmlDocument objXmlDoc = null;
    try
    {
    objXmlDoc = new XmlDocument();
    objXmlDoc.Load(XPath + “Country.xml”);

    XmlNodeList objNodes = objXmlDoc.GetElementsByTagName(“Country”);

    if (ddlPCountry.Items.Count != 0)
    {
    }
    else
    {
    foreach (XmlNode objNode in objNodes)
    {
    arr = objNode.Attributes[“Text”].Value.ToString().Trim();
    arr1 = objNode.Attributes[“Value”].Value.ToString().Trim();
    ddlPCountry.Items.Insert(count, arr);
    ddlPCountry.Items[count].Value = arr1;
    count += 1;
    }
    }
    }
    catch (System.Threading.ThreadAbortException)
    {

    }
    catch (Exception ex)
    {
    Session[“ErrorMessage”] = ex.Message;
    Response.Redirect(“Error.aspx”, false);
    }
    finally
    {
    objXmlDoc = null;
    }
    }

    private int INSERTUPDATE()
    {
    ObjContactDetils=new DALContactDetails();
    int _err = 1;
    try
    {
    string PAdd, PAdd1, CAdd, CAdd1, CCITY, PCITY, CSTATE, PSTATE, PDIST, CDIST, CCOUNTRY;
    string CPCODE, PPCODE, CPHONE = “”, PPHONE = “”, CMOBILE = “”, PMOBILE = “”, CEMAIL = “”, PEMAIL = “”, PCOUNTRY;
    int CAddID = 0,PAddID=0, AID=0;
    string ErrorMASG = “”;
    CAdd = txtStreetNo.Text.ToString().Trim();
    PAdd = txtPStreet.Text.ToString().Trim();
    CAdd1 = txtSecondAddressLine.Text.ToString().Trim();
    PAdd1 = txtPAddressLine.Text.ToString().Trim();
    CCITY = txtCity.Text.ToString().Trim();
    PCITY = txtPCity.Text.ToString().Trim();
    CDIST = txtDistrict.Text.ToString().Trim();
    PDIST = txtPDistrict.Text.ToString().Trim();
    CSTATE = txtState.Text.ToString().Trim();
    PSTATE = txtPState.Text.ToString().Trim();
    CPCODE = txtPostalCode.Text.ToString().Trim();
    PPCODE = txtPPostalcode.Text.ToString().Trim();
    CCOUNTRY = ddlCountry.SelectedItem.Text.ToString().Trim();
    PCOUNTRY = ddlPCountry.SelectedItem.Text.ToString().Trim();
    CPHONE = txtStdCode.Text.ToString().Trim()+”-“+txtphone.Text.ToString().Trim();
    PPHONE = txtPstdCode.Text.ToString().Trim()+”-“+txtPPhoneNo.Text.ToString().Trim();
    CMOBILE = txtMobileNo.Text.ToString().Trim();
    PMOBILE = txtPMobileNo.Text.ToString().Trim();
    CEMAIL = txtEmail.Text.ToString().Trim();
    PEMAIL = txtPEmail.Text.ToString().Trim();
    AID = int.Parse(Session[“ApplicationID”].ToString().Trim());
    CAddID = int.Parse(Session[“CurrentAddID”].ToString().Trim());
    PAddID = int.Parse(Session[“PermanentAddID”].ToString().Trim());
    ErrorMASG = ObjContactDetils.ContactDetails(AID, CAddID, PAddID, CAdd, CAdd1, CCITY, CDIST, CSTATE, CPCODE, CCOUNTRY, CPHONE, CMOBILE, CEMAIL, PAdd, PAdd1, PCITY, PDIST, PSTATE, PPCODE, PCOUNTRY, PPHONE, PMOBILE, PEMAIL, Session[“LoginId”].ToString());
    _err = int.Parse(ErrorMASG.Split(‘,’)[0].Trim());
    string _errmsg = ErrorMASG.Split(‘,’)[1].Trim().ToString();
    if (_err == 0)
    {

    }
    }
    catch(Exception EX)
    {
    Session[“ErrorMessage”] = EX.Message.ToString();
    Response.Redirect(“Error.aspx”, false);
    }
    finally
    {
    ObjContactDetils = null;
    }
    return _err;
    }

    private void FillContactDetails(int AppId)
    {
    DataSet DS = null;
    ObjContactDetils = new DALContactDetails();
    string AddressTypeC = “”,AddressTypeP=””;
    try
    {
    DS = new DataSet();
    DS = ObjContactDetils.FetchContactDetils(AppId);
    if (DS.Tables[0].Rows.Count > 0)
    {
    if (DS.Tables[0].Rows.Count == 2)
    {
    AddressTypeC = DS.Tables[0].Rows[0][“AddressType”].ToString().Trim();

    if (AddressTypeC == “C”)
    {
    Session[“CurrentAddID”] = DS.Tables[0].Rows[0][“AddressId”].ToString().Trim();
    txtStreetNo.Text = DS.Tables[0].Rows[0][“AddressLine1”].ToString().Trim();
    txtSecondAddressLine.Text = DS.Tables[0].Rows[0][“AddressLine2”].ToString().Trim();
    txtCity.Text = DS.Tables[0].Rows[0][“City”].ToString().Trim();
    txtDistrict.Text = DS.Tables[0].Rows[0][“District”].ToString().Trim();
    txtState.Text = DS.Tables[0].Rows[0][“State”].ToString().Trim();
    txtPostalCode.Text = DS.Tables[0].Rows[0][“PostalCode”].ToString().Trim();
    string Country = DS.Tables[0].Rows[0][“Country”].ToString().Trim();
    ddlCountry.ClearSelection();
    ddlCountry.Items.FindByText(Country).Selected = true;
    string CPhoneNumber=DS.Tables[0].Rows[0][“TelephoneWSTD”].ToString().Trim();
    string CSTDCODE = CPhoneNumber.Split(‘-‘)[0].Trim().ToString();
    string CPhone = CPhoneNumber.Split(‘-‘)[1].Trim().ToString();
    txtphone.Text = CPhone.ToString();
    txtStdCode.Text = CSTDCODE.ToString();
    txtMobileNo.Text = DS.Tables[0].Rows[0][“MobileNo”].ToString().Trim();
    txtEmail.Text = DS.Tables[0].Rows[0][“Email”].ToString().Trim();
    }
    AddressTypeP = DS.Tables[0].Rows[1][“AddressType”].ToString().Trim();
    if (AddressTypeP == “P”)
    {
    Session[“PermanentAddID”] = DS.Tables[0].Rows[1][“AddressId”].ToString().Trim();
    txtPStreet.Text = DS.Tables[0].Rows[1][“AddressLine1”].ToString().Trim();
    txtPAddressLine.Text = DS.Tables[0].Rows[1][“AddressLine2”].ToString().Trim();
    txtPCity.Text = DS.Tables[0].Rows[1][“City”].ToString().Trim();
    txtPDistrict.Text = DS.Tables[0].Rows[1][“District”].ToString().Trim();
    txtPState.Text = DS.Tables[0].Rows[1][“State”].ToString().Trim();
    txtPPostalcode.Text = DS.Tables[0].Rows[1][“PostalCode”].ToString().Trim();
    string Contry = DS.Tables[0].Rows[1][“Country”].ToString().Trim();
    ddlPCountry.ClearSelection();
    ddlPCountry.Items.FindByText(Contry).Selected = true;
    string PPhoneNumber = DS.Tables[0].Rows[1][“TelephoneWSTD”].ToString().Trim();
    string PSTDCODE = PPhoneNumber.Split(‘-‘)[0].Trim().ToString();
    string PPhone = PPhoneNumber.Split(‘-‘)[1].Trim().ToString();
    txtPPhoneNo.Text = PPhone.ToString();
    txtPstdCode.Text = PSTDCODE.ToString();
    txtPMobileNo.Text = DS.Tables[0].Rows[1][“MobileNo”].ToString().Trim();
    txtPEmail.Text = DS.Tables[0].Rows[1][“Email”].ToString().Trim();
    }
    }
    else { Session[“PermanentAddID”] = 0; Session[“CurrentAddID”] = 0;}

    }
    else{ Session[“PermanentAddID”] = 0;Session[“CurrentAddID”]=0; }

    }
    catch (Exception ex)
    {
    Session[“ErrorMessage”] = ex.Message.ToString();
    Response.Redirect(“Error.aspx”, false);
    }
    finally
    {
    DS.Dispose();
    ObjContactDetils = null;
    }
    }

    protected void btnBack_Click(object sender, EventArgs e)
    {
    Response.Redirect(“PersonalProfile.aspx”,false);
    }
    }

    Like

  12. Hi,
    Can you please make the link to download the project available again. I get a 404 when I click on the link to download.

    Thanks!

    -L

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s