Twitter Feed Popout byInfofru

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

Send Welcome email to user using Membership API

While using Membership API, It is a very normal task to send user a registration or verification email. We can achieve that using two ways one is using the default email setting of Create User Control and other is by implementing CreateUserWizard.CreatedUser event

Method 1:

Drag and Drop the create user control, right click then properties and find MailDefination and set appropriate values for each property.

membership_sc1

BodyFileName is basically the location of the file which contains the body of the email. It can be text file or html file.

HTML file which I am using is a very simple html file which can be found in the project source specified at the end of this post.

Create User Control uses the SMTP settings in web.config to send the email that is why before checking it you need to make sure that you have specify the correct settings in configuration file. For example

   1: <system.net>
   2:     <mailSettings>
   3:         <smtp deliveryMethod="Network">
   4:             <network defaultCredentials="true" host="localhost" port="25"/>
   5:             <!--userName="" password="" if required specify after port-->
   6:         </smtp>
   7:     </mailSettings>
   8: </system.net>

That's it your control is now ready to send emails.

Method 2:

In this method, we will manually shoot an email when the user get registered successfully. For that we need to implement our logic in CreatedUser event of this control.

Following is the screen shot of different events provided by CreateUserControl

image

As you can see I have generated a method against CreatedUser and here is the code for that

   1: Protected Sub CreateUserWizard1_CreatedUser(ByVal sender As Object, ByVal e As EventArgs) Handles CreateUserWizard1.CreatedUser
   2:     Dim ToAddress As String = CreateUserWizard1.Email
   3:     Dim mm As New MailMessage("Support@mysite.com", ToAddress)
   4:     Using objSr As New StreamReader(Server.MapPath("MailTemplate\\welcome_ver.htm"), FileMode.Open)
   5:         With mm
   6:             .Subject = "Welcome to my site"
   7:             .Body = objSr.ReadToEnd()
   8:             .Body = .Body.Replace("{verification_code}", New Random().Next()) 'Any Random number you can put your logic here...
   9:             .IsBodyHtml = True
  10:         End With
  11:         Dim smtp As New SmtpClient
  12:  
  13:         smtp.Send(mm)
  14:     End Using
  15: End Sub

In this method I am also using the SMTP Settings specified in web.config however, you can change that according to your own need.

In line no 10, I have put a token which will replace the string which I have in my source html file with a random number. For those who are facing difficulty in understanding the token stuff, please see the following html

   1: <html>
   2:  
   3: <body>
   4: Hi, 
   5:  
   6: Thank you for the registration and welcome to my site
   7: Your verification code : {verification_code}
   8: </body>
   9: </html>

That is very simple and very easy. I personally recommend the Method 2 as it can give you some extra control over the process.

Here is the VS 2008 code

Event Bubbling in Javascript

Today, while creating some javascript popup I had a condition in which I place onclick function on body tag. I had an other button which also implement onclick. So the code looks like as follows

   1: <body onclick="disappearPopup()">
   2: <a href="#" onclick="ShowPopup()">Show me</a>
   3: </body>

So, what happen is whenever link is click the body clicked even called automatically. Practically speaking, we need to cancel the body onclick even each time we click the link click.

And for that I write the following code on click of the link

   1: if (window.event) {
   2:     window.event.cancelBubble = true;
   3: }
   4: else {
   5:     e.stopPropagation();
   6: }

And it works ....

My Love &hellip;&hellip; My Vitz

I spent quit much time in maintaing of vehicle. I tell you I am freaking crazy about my wheels. This weekend, I keep busy in the stuff like Oil Change, I  usually change all the oils including Engine /  Break / Transmission with oil and air filter after every six months. So I dedicated my this weekend to my vehicle and here are some image and videos which I captured today just after I realize that the maintenance is complete.

 

Vitz Interior

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.

Different Style for IE7 and Firefox in CSS

Well, I with my designer Atiq was trying to set the a div which is working fine in IE7 but when it comes to Firefox, it was asking us to give the margin-top:10px. when we put that, the div comes down in IE7. So, in this situation we need to specify two different styles for these two browsers.

I don't want to use that, which can also be done using the following HTML.

   1: <!--[if IE 7]><link rel="stylesheet" type="text/css" href="IE7styles.css" /><![endif]--> 

But I don't want to create two css files for this work. Somehow, I want to mage it in the name same CSS. So what I did is so I use Child Selector Command and Star HTML Hack.

Child Selector Command is not understandable by IE, hence whenever it gets something like this .... IE Ignores the style. So I decided to specify Firefox stuff here. it looks like as follows

   1: html>body #ContainerCodeQuestionAnser
   2: {
   3:     position:absolute; z-index:50;background-color:#FFFFFF;width:auto;
   4:     height:20px;margin-left:10px;overflow:hidden;top:10px; /*top is for firefox*/
   5:     }

In contrast, Star HTML Hack is not understandable by any other browser except IE. So IE Stuff Goes here.

   1: * #ContainerCodeQuestionAnser
   2: {
   3:     position:absolute; z-index:50;background-color:#FFFFFF;width:auto;
   4:     height:20px;margin-left:10px;overflow:hidden;
   5:     }

That's it ... the design looks really good.......

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>

Validate username using custom validation (AJAX)

In this post, I will explain you how to have an ajax call on custom validator control and check for the username in the database. This task will include two pages one is the form page (default.aspx in our case) in which we have the custom validator and the other one is the page which we call through AJAX to give us the result (validateUser.aspx). You can also have a web service instead of that page but in my scenario , I am using ASPX page.

So, the form will look like as following.

 

   1: <form id="form1" runat="server">
   2: <div>
   3: <asp:Panel ID="pnl1" runat="server" DefaultButton="Button1">
   4:     <asp:TextBox ID="TextBox1" runat="server">
   5:     </asp:TextBox>
   6:     <asp:Button ID="Button1" runat="server" Text="Submit" />
   7:     <asp:HiddenField ID="hfOutput" runat="server" />
   8: </asp:Panel>
   9:     <asp:customvalidator ID="Customvalidator1" runat="server" errormessage="Enter Valid User" ControlToValidate="TextBox1" ClientValidationFunction="ValidMe"></asp:customvalidator>    
  10: </div>
  11: </form>

Default.aspx (Form)

Notice, the hiddent field called hfOutput which we will use to store the output of the AJAX call.

Where as the page which we call through AJAX will look like as follows

   1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="validateUser.aspx.cs" Inherits="LearnWebApp.validateUser" %>

validateUser.aspx

In short, we have deleted every thing from this page except page directive. Now if we call this page we will see the simple output without having any HTML tag. we did it because we want to get rid from all the html tags so that we can have a neat and clean output at the time we call this page from Javascript (AJAX). What we want this page to return us is either "True" or "False". If you look at the code behind file of this page you will have a good idea of what we actually upto. Here is the code for that.

   1: protected void Page_Load(object sender, EventArgs e)
   2:         {
   3:             // We can also use a database call here ... right now we are compairing string.
   4:             if (Request.QueryString["username"] == "username")
   5:             {
   6:                 Response.Write("true");
   7:             }
   8:             else 
   9:             {
  10:                 Response.Write("false");
  11:             }
  12:         }

validateUser.aspx.cs

As it is there on comments, here we are only comparing string. You can have a database call and return the result accordingly.

To call the validateUser.aspx from validMe function which we have defined in ClientValidationFunction property of custom validator, we need to write the following javascript on default.aspx

   1: <script type="text/javascript">
   2:         var ajaxCalled = false;
   3:         
   4:         function ValidMe(source, args) {
   5:            callPage(args.Value)
   6:            while (document.getElementById("hfOutput").value != ""){
   7:                 if (document.getElementById("hfOutput").value == "true") {
   8:                     args.IsValid = true;
   9:                 }
  10:                 else {
  11:                     args.IsValid = false;
  12:                 }
  13:                 document.getElementById("hfOutput").value = "";
  14:                 return;
  15:             }
  16:         }
  17:  
  18:         function callPage(strName) {
  19:             var rnd = Math.random() * 1000000;
  20:  
  21:             if (window.XMLHttpRequest) { // Mozilla, Safari, IE7...
  22:                 request = new XMLHttpRequest();
  23:             } else if (window.ActiveXObject) { // IE6 and older
  24:                 request = new ActiveXObject("Microsoft.XMLHTTP");
  25:             }
  26:             var url = 'validateUser.aspx?username=' + strName + '&R=' + rnd;
  27:             request.open("GET", url, true);
  28:             request.onreadystatechange = SetPage;
  29:             request.send(null);
  30:             
  31:         }
  32:  
  33:  
  34:         function SetPage() {
  35:             if (request.readyState == 4) {
  36:                 var objHf = document.getElementById("hfOutput");
  37:                 if (request.status == 200) {
  38:                     if (objHf) {
  39:                         objHf.value = request.responseText;
  40:                     }
  41:                 }
  42:             }
  43:             
  44:         }
  45:     </script>

 

Let me describe what we have done here, I am calling CallPage function from ValidMe which will call from the asp.net validation mechanism. CallPage function is an AJAX call which will call validateUser.aspx and SetPage function will be called once the AJAX call is finish and we have output ready to use.

And on that SetPage function we are setting the Hidden field  called hfOutput to get used by ValidMe function.

That's it ..... :) . You can also download the complete project give below.

Get Current Time Using JavaScript

Here is the quick code to get the current time in 12 hours format using JavaScript.

   1: <script language="javascript">
   2: function getTime() {
   3:     var dTime = new Date();
   4:     var hours = dTime.getHours();
   5:     var minute = dTime.getMinutes();
   6:     var period = "AM";
   7:     if (hours > 12) {
   8:         period = "PM"
   9:     }
  10:     else {
  11:         period = "AM";
  12:     }
  13:     hours = ((hours > 12) ? hours - 12 : hours)
  14:     return hours + ":" + minute + " " + period
  15: }
  16: </script>