Twitter Feed Popout byInfofru

Authenticated File Access using HTTP Handler.

In this post I will explain you how authenticate the request directly coming to access a file that is downloadable. some thing like *.pdf or *.zip.

Mostly, people make it working by creating an *.aspx page and then write binary of that file in Response.WriteFile. So, user will have no idea where the file is coming from. now this is the fair approach but what if somebody, somehow know the path of downloadable files.

So, to stop the un authenticated access to our files, we will first create a session enable HTTP handler.

public class MyHttpHandler : IHttpHandler, IReadOnlySessionState
{
 
    public void ProcessRequest(HttpContext context)
    {
        if (context.Session["userId"] == null)
        // I am using a session variable you can also use context.User.Identity.IsAuthenticated
        {
            context.Response.Redirect("/login.aspx?retUrl=" + context.Request.RawUrl);
            //Redirecting to the login page ... alternatively you can also set context.Response.StatusCode 
        }
    }
 
    public bool IsReusable
    {
 
        get { return false; }
    }
}

Now, once we have created that. Let me register my newly creater handler for *.zip and *.pdf files in web.config.

 

<httpHandlers>
  <add verb="*" path="*.zip" type="LearningApp.MyHttpHandler, LearningApp"/>
  <add verb="*" path="*.pdf" type="LearningApp.MyHttpHandler, LearningApp"/>
</httpHandlers>

That’s it. If you want more file types to be authenticated add more verbs in handler section of HttpHandler.

Don’t try to put *.* : That can create some serious problem because then each of your *.aspx, *asmx and all your logic stuff will need authentication.

How to pass parameters to the dynamically added user control

In this post, I will explain how you can pass parameter to the dynamically added (from code behind) User Control. Most of you might aware of how we can achieve this in web application project. Following is the code for that

   1: Dim objCon As Control = Page.LoadControl("~/Controls/MyControl.ascx")
   2: Ctype(objCon,MyControl).PropertyOne = "Test"
   3: Ctype(objCon,MyControl).PropertyTwo = "USAM"
   4: MyPanel.Controls.add(objCon)

Now what if you have a web site project which does not have the pre-compiled assemblies and you are no more able to access the class of your user control. That is what the sum of last two ays.

Here is how you can do that by using System.reflection.

   1: Dim objCon As Control = Page.LoadControl("~/Controls/MyControl.ascx")
   2: 'Creating Dynamic Assmebly which holds control
   3: Dim objAssembly As Assembly = Compilation.BuildManager.GetCompiledAssembly("~/Controls/MyControl.ascx")
   4: 'You should definately know the name of your user control class
   5: Dim objType As Type = objAssembly.GetType("Controls_MyControl")
   6:  
   7: 'Properties
   8: Dim objPropOne As PropertyInfo = objType.GetProperty("PropertyOne")
   9: Dim objPropTwo As PropertyInfo = objType.GetProperty("PropertyTwo")
  10:  
  11: 'Setting Value of Properties
  12: bjPropOne.SetValue(objCon, 1, Nothing)
  13: objPropTwo.SetValue(objCon, 13, Nothing)
  14:  
  15: 'Finally placing control on the page
  16: pnlCommentsCon.Controls.Add(objCon)

So in this way you can pass parameters to the dynamically added user control.  

Get Repeater Control Output in String

In this post I will share with you a small code snippet which will help you to get the repeater control output in string variable.

   1: Dim sb As New StringBuilder()
   2: Dim objHtml As New HtmlTextWriter(New System.IO.StringWriter(sb))
   3:  
   4: If dt.Rows.Count > 0 Then
   5:     Repeater1.DataSource = dt
   6:     Repeater1.DataBind()
   7: End If
   8:  
   9: Repeater1.RenderControl(objHtml)
  10: Return sb.ToString() 

 

Well, I have used a little trick here. The RenderControl method of repeater control can put all the HTML in HtmlTextWriter Object and from HtmlTextWriter Object we have simply dump the output the to the string builder. That’s it ….

Integrating CSS Control Adapter With Menu Control

This is on the request of some of my readers to show how effective Asp.net menu control is by using CSS Control Adapter. Most of the folks either have no idea of what CSS Adapter is or have some problem in integrating that with their applications.

So, In this post I will brief you guys how can we use CSS Adapter to format the design of Asp.net Menu Control. Before we start, let me dig out why would somebody use CSS Adapter and what does that do ?

Have you ever notice by viewing the source of your page what asp.net runtime engine generate when you use any Data list, or in our case Menu Control.
It generates Table based layout, which is of course really difficult to design and not consider a good practice in the new web standards. To overcome that issue CSS Control Adapter is the answer. It will rendered div and unorderlist (UL) instead of table which can easily be redesign using CSS. It means, you can now have standardized approach to create web based controls. If you want to see what CSS Control Adapter provide you, Click Here and notice the HTML Snippet given at bottom. 

Ok, to start off lets download the source code and open the project. By the time I am writing this post only VS 2005 version of CSS Control Adapter is available. But that is  not an issue, If you are using VS 2008, simply convert the project. Even if you don’t want to open the project it still have no problem as we only need to copy paste some stuff from here.

Create A Web Application or Web Site Project in which you want to implement Menu Control. right click on your project and add special folder called App_Browser. Now Right Click on the newly created folder and Add Browser File and Name it “CSSFriendlyAdapters.browser”.

You can either write the following stuff in it or Just Copy / Paste this from CSS Control Adapter Project which you have downloaded before.

   1: <browsers>
   2:   <browser refID="Default">
   3:     <controlAdapters>
   4:       <adapter controlType="System.Web.UI.WebControls.Menu"
   5:                adapterType="CSSFriendly.MenuAdapter" />
   6:   
   7:     </controlAdapters>
   8:   </browser>
   9:  
  10:   <browser id="W3C_Validator" parentID="default">
  11:     <identification>
  12:       <userAgent match="^W3C_Validator" />
  13:     </identification>
  14:     <capabilities>
  15:       <capability name="browser"              value="W3C Validator" />
  16:       <capability name="ecmaScriptVersion"    value="1.2" />
  17:       <capability name="javascript"           value="true" />
  18:       <capability name="supportsCss"          value="true" />
  19:       <capability name="supportsCallback"     value="true" />
  20:       <capability name="tables"               value="true" />
  21:       <capability name="tagWriter"            value="System.Web.UI.HtmlTextWriter" />
  22:       <capability name="w3cdomversion"        value="1.0" />
  23:     </capabilities>
  24:   </browser>
  25: </browsers>

If you see the browser file available in CSS Control Adapter project you will realize that under ControlAdapter tag there are several other ControlType specified. But in our case as we are only using Menu Control so we have removed the un wanted stuff.

Now once you have done this, you need to add reference to the CSS Adapter. You can find the assembly in CSS Control Adapter Project.

Lets create a page and drop and Menu control. See the following snippet.

 

   1: <asp:Menu ID="Menu1" runat="server" Orientation="Horizontal" CssSelectorClass="SimpleEntertainmentMenu">
   2:      <Items>
   3:          <asp:MenuItem Text="Item 1" Value="Item 1">
   4:              <asp:MenuItem Text="Item a" Value="Item a">
   5:                  <asp:MenuItem Text="Item a - a" Value="Item a - a"></asp:MenuItem>
   6:              </asp:MenuItem>
   7:              <asp:MenuItem Text="Item B" Value="Item B"></asp:MenuItem>
   8:          </asp:MenuItem>
   9:          <asp:MenuItem Text="Item 2" Value="Item 2">
  10:              <asp:MenuItem Text="Item a" Value="Item a"></asp:MenuItem>
  11:          </asp:MenuItem>
  12:      </Items>
  13:  </asp:Menu>


Now we need to create a CSS file and linked that with the page we have created. The CSS File should like as below

   1: .SimpleEntertainmentMenu ul.AspNet-Menu /* Tier 1 */
   2: {
   3:     width: 13em; /* This is more than (6em x 2) because we want to leave room for borders around the <li> elements that are selected */
   4: }
   5:  
   6: .SimpleEntertainmentMenu ul.AspNet-Menu ul  /* Tier 2 */
   7: {
   8:     width: 6em;
   9:     top: 100%;
  10:     left: 0;
  11:     font-weight:bold;
  12: }
  13:  
  14: .SimpleEntertainmentMenu ul.AspNet-Menu ul ul  /* Tier 3+ */
  15: {
  16:     top: 0%;
  17:     left: 6em;
  18:     font-weight:normal;
  19: }
  20:  
  21: .SimpleEntertainmentMenu li /* all list items */
  22: {
  23:     width: 6em;
  24:     background: #efefef;
  25: }
  26:  
  27: .SimpleEntertainmentMenu li:hover, /* list items being hovered over */
  28: .SimpleEntertainmentMenu li.AspNet-Menu-Hover
  29: {
  30:     background: Black;
  31: }
  32:  
  33: .SimpleEntertainmentMenu a, /* all anchors and spans (nodes with no link) */
  34: .SimpleEntertainmentMenu span
  35: {
  36:     color: Black;
  37:     padding: 4px 2px 4px 8px;
  38:     border:1px solid #cccccc;
  39:     background: transparent url(arrowRight.gif) right center no-repeat;
  40: }
  41:  
  42: .SimpleEntertainmentMenu li.AspNet-Menu-Leaf a, /* leaves */
  43: .SimpleEntertainmentMenu li.AspNet-Menu-Leaf span
  44: {
  45:     background-image: none !important;
  46: }
  47:  
  48: .SimpleEntertainmentMenu li:hover a, /* hovered text */
  49: .SimpleEntertainmentMenu li:hover span,
  50: .SimpleEntertainmentMenu li.AspNet-Menu-Hover a,
  51: .SimpleEntertainmentMenu li.AspNet-Menu-Hover span,
  52: .SimpleEntertainmentMenu li:hover li:hover a,
  53: .SimpleEntertainmentMenu li:hover li:hover span,
  54: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover a,
  55: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover span,
  56: .SimpleEntertainmentMenu li:hover li:hover li:hover a,
  57: .SimpleEntertainmentMenu li:hover li:hover li:hover span,
  58: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover li.AspNet-Menu-Hover a,
  59: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover li.AspNet-Menu-Hover span
  60: {
  61:     color: White;
  62:     background: transparent url(activeArrowRight.gif) right center no-repeat;
  63: }
  64:  
  65: .SimpleEntertainmentMenu li:hover li a, /* the tier above this one is hovered */
  66: .SimpleEntertainmentMenu li:hover li span,
  67: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li a,
  68: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li span,
  69: .SimpleEntertainmentMenu li:hover li:hover li a,
  70: .SimpleEntertainmentMenu li:hover li:hover li span,
  71: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover li a,
  72: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover li span
  73: {
  74:     color: Black;
  75:     background: transparent url(arrowRight.gif) right center no-repeat;
  76: }
  77:  
  78: .SimpleEntertainmentMenu .AspNet-Menu-Selected /* this tier is selected */
  79: {
  80:     border: solid 1px #00ff00 !important;
  81: }
  82:  
  83: .SimpleEntertainmentMenu .AspNet-Menu-ChildSelected /* a tier below this one is selected */
  84: {
  85:     border: solid 1px #ff0000 !important;
  86: }
  87:  
  88: .SimpleEntertainmentMenu .AspNet-Menu-ParentSelected /* a tier above this one is selected */
  89: {
  90:     border: solid 1px #0000ff !important;
  91: }
  92:  
  93: #EntertainmentMessage
  94: {
  95:     padding-top: 2em;
  96:     clear: both;
  97: }

 

Well that is pretty self describing, as I have already mention that the CSS Control adapter will rendered Divs and Unorder lists instead of table for Menu Control. Here we are simply specifying the style for Menu element on different level.

Once you have complete with the creation of CSS file, you need to link this with your page and for that

   1: <link rel="stylesheet" href="/CSS/SimpleMenu.css" type="text/css" />

I have created the CSS File under CSS folder, which can be some thing else in your case.

That is it, it is pretty simple yet effective to use CSS Control Adapter with your asp.net application because it can give standardized HTML as output which is easy to design.
You can download the VS 2008 project file.

Prevent Request Timeout in Asp.net

In one of our application we want our user to upload data up to 1GB and the most interesting part is we want this uploading via HTTP. I mean, we have plan to use FTP but that is for future. For now we need to make it with HTTP.

Off course, uploading data in GB's requires much extra time then the default configuration and same problem with the request size. So, to make it done we need to change the configuration of following items.

  1. executionTimeOut : Default value is 110 seconds, we need to make it for at least 12 hours.
  2. maxRequestLength : Default value is 4096 KB (4 MB), we want it to accommodate 1 GB size of data.
  3. Session Timeout : Default value is 20 minutes, we need to make it according to the executionTimeOut.

The above two are the configuration of httpRuntime attribute, but along with that why do we need to change the session timeout. Because, if session timeout is less then execution timeout it means when the request finishes its processing meanwhile, the session get's end which can raise an error.

So, here is the configuration which we need to make in web.config.

   1: <httpRuntime executionTimeout="43200" maxRequestLength="104856"  />
   2: <sessionState mode="InProc" cookieless="false" timeout="720"/>

Notice, executionTimeout needs to be filled in seconds where as timeout of sessionstate needs minutes as input.

But that doesn't work in my case. I spent many hours replacing the configuration settings and no results.

Finally, I get to know that Application Pool also have idle timeout settings which can be useful.


To get application pool in Windows 2003  :

  1. Right click on your website and click properties
  2. Then Home Directory Tab and notice the last most drop down of  screen. Application Pool
  3. Notice the name, and close screen.
  4. Then go to Application Pools right click the application name which you have in our website and then properties. You will see the following Screen.

 

idle

The default value of idle timeout is 20 minutes. I have changed this to 720 (same as of session) minutes and every thing start working.

I did never even hear of this idle timeout before neither I think that while uploading the file connection thread is idle but now this is for sure, if you are increasing the session timeout greater then 20 you must need to configure the same amount in your Application Pool Settings.

Passing Parameter To User Control On A Modal Popup

This is the most demanded scenario for the one who are using Asp.net AJAX Control Toolkit, I mean I have seen most of the people asking for this feature on asp.net forum.

Unfortunately, we have no such functionality provided in Modal Popup because the control get rendered once the page is loaded and the Modal Popup is just a JavaScript which work is just to display a div which is hidden.

Here is a little work around for those who wants to pass parameter to user control using Modal Popup. Basically, the idea is to keep the user control in a separate page and call that page using JavaScript and put the response on the a Modal Popup Div.

Remember, as this is only a JavaScript we need to set the parameter using JavaScript or we need to save the parameters on Page_Load in any Hidden field and access that later from JavaScript.

To start, I have created two pages and a user control following is the naming stuff for them

  1. Default.aspx (Contains Modal Popup)
  2. ControlCaller.aspx  (Contains User Control)
  3. Controls.ascx (User Control)

Default.aspx page html will look like as follows

   1: <form id="form1" runat="server">
   2:     <div>
   3:     
   4:         <asp:ScriptManager ID="ScriptManager1" runat="server">
   5:         </asp:ScriptManager>
   6:         <asp:Button ID="Button1" runat="server" Text="Show Popup" OnClientClick="setupParam()" />
   7:     
   8:     </div>
   9:     <cc1:ModalPopupExtender ID="ModalPopupExtender1" runat="server" PopupControlID="pnlControl" TargetControlID="Button1">
  10:     </cc1:ModalPopupExtender>
  11:     <asp:Panel ID="pnlControl" runat="server">
  12:             
  13:     </asp:Panel>
  14:     
  15:     <asp:HiddenField ID="hf_username" runat="server" />
  16:     <asp:HiddenField ID="hf_password" runat="server" />
  17:     <asp:HiddenField ID="hf_registredDate" runat="server" />
  18:     
  19:     </form>

Keep in mind that the three hidden fields I have taken here are for the Parameters.

Now Let's see what we have in ControlCaller.aspx

   1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ControlCaller.aspx.cs" Inherits="LearnWebApp.ControlCaller" %>
   2: <%@ Register src="Controls/Control.ascx" tagname="Control" tagprefix="uc1" %>
   3:     <uc1:Control ID="Control1" runat="server" />

Just user control implementation and nothing else. Please make sure to remove all the head, html and form tags.

Following is the html of Control.ascx

   1: <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Control.ascx.cs" Inherits="LearnWebApp.Controls.Control" %>
   2: User Name :
   3: <asp:Label ID="lblUserID" runat="server" Text="Label"></asp:Label>
   4: <br />
   5: Registered Date :
   6: <asp:Label ID="lblDate" runat="server" Text="Label"></asp:Label>
   7: <br />
   8: Password:
   9: <asp:Label ID="lblPassword" runat="server" Text="Label"></asp:Label>

And here is the code behind of the Control

   1: private string _userName;
   2:         private string _RegisteredDate;
   3:         private string _Password;
   4:  
   5:         public string userName
   6:         {
   7:             get { return _userName; }
   8:             set { _userName = value; }
   9:         }
  10:         public string RegisteredDate
  11:         {
  12:             get { return _RegisteredDate; }
  13:             set { _RegisteredDate = value; }
  14:         }
  15:         public string Password
  16:         {
  17:             get { return _Password; }
  18:             set { _Password = value; }
  19:         }
  20:         protected void Page_Load(object sender, EventArgs e)
  21:         {
  22:             if (!Page.IsPostBack) 
  23:             {
  24:                 lblDate.Text = _RegisteredDate;
  25:                 lblPassword.Text = _Password;
  26:                 lblUserID.Text = _userName;
  27:             }
  28:         }

Please bear in mind, that the properties we have taken here are for the parameters as you can see I am also setting these properties on label at Page_Load.

and here we have the script which we need to add on the default.aspx head section

   1: <script language="javascript">
   2:     var request = false;
   3:        try {
   4:          request = new XMLHttpRequest();
   5:        } catch (trymicrosoft) {
   6:          try {
   7:            request = new ActiveXObject("Msxml2.XMLHTTP");
   8:          } catch (othermicrosoft) {
   9:            try {
  10:              request = new ActiveXObject("Microsoft.XMLHTTP");
  11:            } catch (failed) {
  12:              request = false;
  13:            }  
  14:          }
  15:        }
  16:        
  17:       function GetResult() {
  18:         var divComm = document.getElementById('pnlControl');
  19:         divComm.innerHTML = "Please wait processing your request!!!";
  20:         var rnd = Math.random() * 1000000;
  21:         var url = 'ControlCaller.aspx?userName=' +document.getElementById("hf_username").value + "&password=" + document.getElementById("hf_password").value  + "&Date="+ document.getElementById("hf_registredDate").value  +'&rnd=' + rnd;
  22:         request.open("GET", url, true);
  23:         request.onreadystatechange = GetResultComplete;
  24:         request.send(null);
  25:     }
  26:     function GetResultComplete() {
  27:         if (request.readyState == 4) {
  28:             //alert(request.responseText);
  29:             if (request.status == 200) {
  30:                 var divComm = document.getElementById('pnlControl');
  31:                 if (divComm) {
  32:                     divComm.innerHTML = request.responseText;
  33:                 }
  34:             }
  35:         }
  36:     }
  37:     function setupParam()
  38:         {
  39:             document.getElementById("hf_username").value = "User is for test !!!";
  40:             document.getElementById("hf_password").value  = "testing.....";
  41:             document.getElementById("hf_registredDate").value  = "10/04/84";
  42:             GetResult();
  43:             
  44:         }
  45:     </script>

Notice the setupParam() function, we are setting our parameter here and then call the GetResult function which is making an AJAX call to the page we have created. That's it by using this method we can have parameterized user control inside Modal Popup.

You can download the full Visual Studio 2008 Project from here.

Disable Control When Asp.net AJAX is in progress

If the AJAX call to the server take too much time, then there is a possibility that user might press some other buttons or some other event occurred which will cause your AJAX call to stop and make a new request.

To overcome this situation, I decided to have div on the top of the page so that while AJAX call is in progress user cannot do any thing else.

So I simply Drag and Drop a Update Progress Control and write the following stuff.

<asp:UpdateProgress ID="UpdateProgress1" runat="server">
    <ProgressTemplate>
        <div id="Progress">Please wait ......</div>
       <div id="bgDiv"></div> 
    </ProgressTemplate>
</asp:UpdateProgress>

And add the following style on head section of the page.

   1: <style>
   2:     #bgDiv {
   3:       position:absolute;
   4:       top:0px;
   5:       bottom:0px;
   6:       left:0px;
   7:       right:0px;
   8:       overflow:hidden;
   9:       padding:0;
  10:       margin:0;
  11:       background-color:black; 
  12:       filter:alpha(opacity=50);
  13:       opacity:0.5;
  14:       z-index:500;
  15:     }
  16:     #Progress
  17:     {
  18:         position: absolute;
  19:         background-color:Red;
  20:         width: 300px;
  21:         z-index: 600;
  22:     }
  23:  
  24:  
  25:     </style>

There we go whenever AJAX call made, a background div will appear and on top of that we have our message "Please wait"

Here is the snapshot

image

Long Waited Task in Asp.net

Yesterday, one my my friend ask me a query about sending some 500+ emails using an asp.net page. Sending bulk email using asp.net is obviously an issue. I mean, You cannot keep the page on the post back state for the five minutes. Your page will get expired and even if you increase the Request Timeout period it is still not a good approach.So for that, There are couple of approaches like1. You can have a table in which you store all the emails and create a Windows Service or Schedule Task to read tables of send emails accordingly.2. Open a thread on the server side using delegate and return the page to the browser and show the progress using Asynchronous operation. As We were operating on shared hosting first approach doesn't seem fruitful for us. So, we decided to go with the second approach and for that we use delegates. Let me show you step by step.
1: Public Delegate Sub LongTimeTask_Delegate()2: Private fileName as String
Here I have declared a delegate and a global variable called filename which I will use for getting the status of the process.Now on the click event of my button which start the process. I have write the following code
1: Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click2: Dim rnd As Double = New Random().Next()3: fileName = Session.SessionID & "_" & rnd & ".txt"4: Dim d As LongTimeTask_Delegate5: d = New LongTimeTask_Delegate(AddressOf LongTimeTask)6:  7: Dim R As IAsyncResult8: 9: R = d.BeginInvoke(New AsyncCallback(AddressOf TaskCompleted),nothing)10: Dim strScript As String = "<script language='javascript'> setInterval('GetResult(""" + fileName + """)',2000); </script>"11:  12: Button1.Enabled= False13: Response.Write(strScript) 'TODO : Can take write on literal14: End Sub
On line no 3, I am setting filename variable to the session id and a random numberOn line no 4, Declare and Initialize Delegate and passed a function that will be executed by DelegateOn line no 7 and on, We invoke the delegate and store the result in IAsyncResult and also specify the function that will execute once the delegate is complete.On line no 10, we are writing a script on the page which is there to show us the status of process timely.Now, lets come LongTimeTask function, in which we have the whole stuff.
1: Public Sub LongTimeTask()2: Dim totCount As Integer = 5003: For a As Integer = 1 to totCount4: Try5: If Not File.Exists(fileName)6: File.Create(fileName)7: End If8: using sw As StreamWriter = New StreamWriter(Server.MapPath(fileName))9: sw.WriteLine("Processing " + a.ToString() + " of " + totCount.ToString() + " emails")10: End Using11: Catch 12:  13: End Try14: System.Threading.Thread.Sleep(2000)15: Next16: End Sub
Notice that, system will be in the loop for 500 times and each time before start processing it will update the status which will display to the browser. The Try/Catch block is updating the status where as notice the line no 14 in which I pause the thread. You can add your email sending or other long process stuff here but for me it is enough to sleep the thread for twenty seconds.Let me show you what happen when the task gets finished.
1: Public Sub TaskCompleted(ByVal R As IAsyncResult)2: Try3: using sw As StreamWriter = New StreamWriter(Server.MapPath(fileName))4: sw.WriteLine("Process has been completed successfully <a href='default.aspx'>Click here </a> to go back") 'You might shoot an email or some thing else here5: End Using6: If File.Exists(fileName)7: File.Delete(fileName)8: End If9: Catch 10:  11: End Try12: End Sub
This time, we have updated the status with some other text and a hyper link. You can also have any kind of alert here. This is just the part of the code behind stuff. ASPX file contain the actual Asynchronous logic here is the HTML
1: <form id="form1" runat="server">2: <div>3:  4: <asp:Button ID="Button1" runat="server" Text="Start IAsync" />5: <div id="resultDiv"></div>6: </div>7: </form>
The resultDiv is responsible of showing the status. Now to get the status following Javscript will do the complete magic
1: <script language="javascript">2: var request = false;3: try {4: request = new XMLHttpRequest();5: } catch (trymicrosoft) {6: try {7: request = new ActiveXObject("Msxml2.XMLHTTP");8: } catch (othermicrosoft) {9: try {10: request = new ActiveXObject("Microsoft.XMLHTTP");11: } catch (failed) {12: request = false;13: } 14: }15: }16: 17: function GetResult(filename) {18: var rnd = Math.random() * 1000000;19: var url = filename + '?rnd=' + rnd;20: request.open("GET", url, true);21: request.onreadystatechange = GetResultComplete;22: request.send(null);23: }24: function GetResultComplete() {25: if (request.readyState == 4) {26: 27: if (request.status == 200) {28: var divComm = document.getElementById('resultDiv');29: if (divComm) {30: divComm.innerHTML = request.responseText;31: }32: }33: }34: }35: </script>
There it is ... we are all done. Following is the snapshot of the working long waited task in asp.netasyncYou can find the complete code for Visual Studio 2008 ... cheers

Prevent .js caching in asp.net

This is like a very common issue, specially for those who are working on public site which is live and they have to release the builds every week or month and if the new build contain JS files then your change will not reflect on the client browser until someone there presses ctrl + F5.So, after googling this issue. I came to know it is possible to prevent the browser from accessing the cache copy by writing the script tag as below
   1: <script type="text/javascript" src="../Includes/main.js?random=556"></script>
 It is good, when I have a single or some number of pages to change. Unfortunately, That is not the case I have hundreds of pages and that will be hassle to make those changes again and again for every build. So, I try to make this thing happen using Response Filter.

Create Response Filter:

So, to write the Response Filter we need to create a class and which is extended from Stream (System.IO.Stream) and I named it BuildTokenFilter.
   1: Imports Microsoft.VisualBasic
   2: Imports System.IO
   3: Imports System.Text.RegularExpressions
   4: Imports System.Configuration
   5: 
   6: 
   7: Public Class BuildTokenFilter
   8:     Inherits Stream
   9:     Private _responseStream As Stream
  10:     Public Sub New(ByVal responseStream As Stream)
  11:         _responseStream = responseStream
  12:     End Sub
  13:     Public Overrides ReadOnly Property CanRead() As Boolean
  14:         Get
  15:             Return _responseStream.CanRead
  16:         End Get
  17:     End Property
  18:     Public Overrides ReadOnly Property CanSeek() As Boolean
  19:         Get
  20:             Return _responseStream.CanSeek
  21:         End Get
  22:     End Property
  23: 
  24:     Public Overrides ReadOnly Property CanWrite() As Boolean
  25:         Get
  26:             Return _responseStream.CanWrite
  27:         End Get
  28:     End Property
  29: 
  30:     Public Overrides Sub Flush()
  31:         _responseStream.Flush()
  32:     End Sub
  33: 
  34:     Public Overrides ReadOnly Property Length() As Long
  35:         Get
  36:             Return _responseStream.Length
  37:         End Get
  38:     End Property
  39: 
  40:     Public Overrides Property Position() As Long
  41:         Get
  42:             Return _responseStream.Position
  43:         End Get
  44:         Set(ByVal value As Long)
  45:             _responseStream.Position = value
  46:         End Set
  47:     End Property
  48: 
  49:     Public Overrides Function Read(ByVal buffer() As Byte, ByVal offset As Integer, ByVal count As Integer) As Integer
  50:         Return _responseStream.Read(buffer, offset, count)
  51:     End Function
  52:     Public Overrides Function Seek(ByVal offset As Long, ByVal origin As System.IO.SeekOrigin) As Long
  53:         _responseStream.Seek(offset, origin)
  54:     End Function
  55: 
  56:     Public Overrides Sub SetLength(ByVal value As Long)
  57:         _responseStream.SetLength(value)
  58:     End Sub
  59:     Public Overrides Sub Write(ByVal buffer() As Byte, ByVal offset As Integer, ByVal count As Integer)
  60:         Dim strRegex As String = "src=(?<Link>.*js)"
  61:         Dim BuildTokenString As String = "?token=" & IIf(ConfigurationManager.AppSettings("BuildToken") = Nothing, "1.0", ConfigurationManager.AppSettings("BuildToken"))
  62:         Dim objRegex As New Regex(strRegex)
  63:         Dim html As String = System.Text.Encoding.UTF8.GetString(buffer)
  64:         Dim extCharCount As Integer = 0
  65: 
  66:         Dim objCol As MatchCollection = objRegex.Matches(html)
  67:         For Each m As Match In objCol
  68:             extCharCount += BuildTokenString.Length
  69:             Dim newJSValue As String = m.Value & BuildTokenString
  70:             html = html.Replace(m.Value, newJSValue)
  71:         Next
  72:         buffer = System.Text.Encoding.UTF8.GetBytes(html)
  73:         _responseStream.Write(buffer, offset, count + extCharCount)
  74:     End Sub
  75: End Class
"Write" is the function which is doing the whole stuff. It is really simple to understand. Let me go linewise.
60. Create a string variable and assign and regular expression which will search all the js files tags in html61. Create a string which will append to the JS file. Checking the App key in web.config So that the token can be extended in future.62. Create a Regex Object63. Get the html from Buffer64. Create an integer variable which will keep track of the characters that are added to the html variable. 66. Save the matches in a collection67. Get each mach object from Match Collection68. Add the character count which will added to the html variable69. Create a variable and assign value of match and concatenated with build token70. Replace the old value with the new with build token in html variable72. Encode the html variable back to the buffer73. Write the buffer to the stream by adding count with build token character count.
Now lets create a HttpModule which will responsible of attaching this response filter with every request.

Create HttpModule:

Now to write HttpModule, I will create a class which will Implements IHttpModule (interface) and I name it "BuildToken"/
   1: Imports Microsoft.VisualBasic
   2: Imports System.Web
   3: Public Class BuildToken
   4:     Implements IHttpModule
   5:     Public Sub Dispose() Implements System.Web.IHttpModule.Dispose
   6: 
   7:     End Sub
   8:     Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
   9:         AddHandler context.BeginRequest, AddressOf Application_BeginRequest
  10:     End Sub
  11:     Private Sub Application_BeginRequest(ByVal source As Object, ByVal e As EventArgs)
  12:         Dim context As HttpApplication = CType(source, HttpApplication)
  13:         If context.Request.RawUrl.Contains(".aspx") = True Then
  14:             context.Response.Filter = New BuildTokenFilter(context.Response.Filter)
  15:         End If
  16:     End Sub
  17: End Class
 In this case the magical function is Application_BeginRequest which can easily be understand but the question might arises why I have put the If condition on line number 13. Well, I don't want my module to attach response filter against all the files. Keep in mind, HttpModule is always called no matter what content type are you requesting. when somebody write http://www.sitename.net/images/border2.jpg it will still process through HttpModule and that is what I don't want.

Configuration Setting:

We are almost done, just a web.config entry is left which we keep for the modification of token string.
   1: <appSettings>
   2:     <add key="BuildToken" value="7.0"/>
   3: </appSettings>
 

Test the filter:

Now to check the the response filter create a page that is called default.aspx and paste the following markup
   1: <html xmlns="http://www.w3.org/1999/xhtml" >
   2: <head runat="server">
   3:     <title>Untitled Page</title>
   4:     <script type="text/javascript" src="../Script/samain.js"></script>
   1: 
   2:     <script type="text/javascript" src="../ControlsScripts/preloadshare.js">
   1: </script>
   2:     <script type="text/javascript" src="../Script/mainview.js">
</script>
   5: </head>
   6: <body>
   7:     <form id="form1" runat="server">
   8:     <div>
   9:     <p>
  10:     Right click and view source you will find JS files with query string</p>
  11:     </div>
  12:     </form>
  13: </body>
  14: </html>
Now Run the application and view source the page you will notice some thing like give below.sc_responsefiltercacheEach time, when you made some changes in JS file just change Build Token entry in the web.config file and your visitors will get the updated copy of JS. You can also download the project files.

How to change default button of a form

Often, we have condition when we have multiple forms on a page which have multiple submit buttons as well. Whenever, you press enter on any text box it will call the command button which is at top most sequence of command buttons.

So, to overcome this problem here is the little code. Take your each set of fields and button in a panel and specify the default Button Property. In the example below I have a form which have two buttons one is command button and another is an image button and I am setting the second button of the sequence to get called each time enter key press on the panel. (rather then the top most)

   1: <asp:Panel ID="pnl1" runat="server" DefaultButton="ImageButton1">
   2:         <asp:TextBox ID="TextBox1" runat="server">
   3:         </asp:TextBox>
   4:         <asp:Button ID="Button1" runat="server" Text="Submit" />
   5:         <asp:ImageButton ID="ImageButton1" runat="server" />
   6:     </asp:Panel>