Tuesday, March 3, 2009

Tip: Export a HTML table or a GridView with unicode characters such as Chinese to Excel

The ability to export data to Excel from a web page is a great ability. However, you might want to cater your web page for multi languages. Usually this is how you can export the data without the language support:

Response.Clear();
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("content-disposition", "attachment;filename=" + strFileName);
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
MyCustomControl.RenderControl(htmlWrite); //This is where we call our custom object
//to render its' HTML, it can be an ascx control.
Response.Write(stringWrite.ToString());
Response.End();

The versiont that can export to Chinese zh-CN:

byte[] leader = new byte[2]; //To tell Excel engine to interpret the content correctly.

leader[0] = 0xFF;
leader[1] = 0xFE;
Response.Clear();
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("content-disposition",
"attachment;filename=" + strFileName);

Response.ContentEncoding = Encoding.Unicode; //indicates that the content is unicode
Response.BinaryWrite(leader);
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
MyCustomControl.RenderControl(htmlWrite);
Response.Write(style);
Response.Write(stringWrite.ToString());
Response.End();

Wednesday, February 25, 2009

Tip: ASP.NET Button Post Back in a JQuery Dialog

Most of the time we want to build some ASP.NET controls inside a JQuery dialog and that when user click on the controls, they will post back to the web server. However, by nature if you put those controls inside a Jquery dialog, they will not behave as expected.

The reason is because JQuery builds the dialog outside of the "form" element in the form that you have created. Any control that is put outside the form will not post back. The following illustration shows the scenario that i am talking about.

<form id='formName'>     
</form>
<div id='dialog'>
    <input id='btnSubmit' type='button' />
</div>

In order to fix the problem we need to move the div section inside the form. In order to do that we can write something like this:

dlg.parent().parent().appendTo($("#formName"));

The code above appends the resulting dialog to the form element named 'formName'. The end result basically shows the following code structure.

<form id='formName'>
     <div id='dialog'>
         <input id='btnSubmit' type='button' />
     </div>
</form>
        

Thursday, February 12, 2009

Tip: Converting MS Ajax JSON DateTime to JS Date object

In my recent project, i have to use JSON Serialization to translate a datatable into JSON format. The table contains fields that are of DateTime data type. When the data is deserialized in the browser, the data is always represented in "/Date(1325926000000-0800)/".

I know i can use the the MS Ajax JS API "Sys.Serialization.JavaScriptSerializer.deserialize" to deserialize the data back into JS Date object but i dont want to include the immense MS JS script library into my page. So the option is to use the JS below to do the trick.

var dt    = data.updateDateTime; //assuming it's like /Date(1325926000000-0800)/
var s = eval(dt.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
dt = new Date(s);
    
var mil = Date.UTC(dt.getFullYear(),dt.getMonth(), dt.getDate(), dt.getHours(), dt.getMinutes(), dt.getSeconds(), dt.getMilliseconds()); //Miliseconds since January 1, 1970
dt      = new Date(mil); //Convert to local time
alert(dt);

Tuesday, January 13, 2009

Some thoughts on Google Chrome 1.0.154.43

This post is not meant to insult the Chrome team but instead i have to praise them to have done an excellent job in introducing a fast and different browser than the others. 

I have been using the Google Chrome browser for a few months now and i noticed the following shortcomings which i think can be further improved in future release of the Chrome.

1. I am a premium Rapidshare user and when i used Chrome to login, I tried to download files using FlashGet but FlashGet was not able to detect the Rapidshare cookies. This does not happen in IE or FireFox. In addition, Chrome could not seem to remember login cookies from some web sites that used to visit.

2. I tested a web project that i developed using the famous JQuery library with Chrome, some functions did not work as expected. What i believe is JQuery is suppose to be compatible cross browsers and should be working fine with Chrome.

3. Some existing CSSs are not working well with the Chrome. For example, some table formattings will be out of the ordinary with bad content alignment.

4. There's is no online bookmark storage available for use, therefore it's not really convenient to share the same bookmark across different PCs. In addition, if Chrome allows me to modify a bookmark icon, that will be more fancy to use.

Even though with all the temporary shortcomings, I still have high hope on getting a perfect browser in the future releases.

Tuesday, December 30, 2008

Tip: CalendarExtender In Update Panel with ReadOnly TextBox

Scenario:
From time to time we want to build a date selection in a web form using the Ajax Control Toolkit's Calender Extender and to set a text box that accepts a new date everytime a user chooses a new date to ReadOnly mode so that user cannot modify the text box with unintended date format.  Most of the time, we want to put it inside an UpdatePanel so that only partial of the page is updated. The problem is, the TextBox's TextChanged event if you enable it, it will not fire if the user makes a date selection and changes the content of the text box.

Solution:
The solution to this problem is to bind the UpdatePanel "Load" event to a function. In this case, any changes in the text box content will trigger the UpdatePanel event.
In the function what we can do is to check the "__EVENTTARGET" returned from the "Request" object. For example, the following code checks whether the postback is caused by the myTextBox text box.

        protected void UpdatePanel2_Load(object sender, EventArgs e)
        {
            if (Request.Params["__EVENTTARGET"] == myTextBox.ID)
            {
                  //DO something
            }
        }

Saturday, December 6, 2008

Tips: How to compress JSON response using GZIP

The main objective for this short article is to write out the method to compress JSON response(using Web Service) and Ajax response(using normal aspx page) using IIS6 Metabase Explorer.

I have been involving in a ASP.NET web project that makes heavy use of JSON technique and Ajax concepts. The web pools for new data from a Windows 2003 web server every 30 seconds. The size of the data can vary from 100KB to 1MB. This poses performance issue for customers that have slow Internet connection.

IIS6 provides the capability to Gzip the web content before sending to the clients. Figure 1 and Figure 2 show the typical setting that i uses in order to compress JSON and Ajax response.

Figure 1: Deflate settings

Figure 2: Gzip settings.

As you can see, the main setting that is related to the JSON and Ajax response GZIP is the HcScriptFileExtensions. I have included the "aspx" and "asmx" extensions in the "Data" column. 

Saturday, October 4, 2008

Tips: Anonymous access gets error 401.1 every time the Domain Controller pushes the domain policy to the web server.

This problem had been troubleing me for a month already. After searching through the web i've finally gotten some hints on the possibilities of what had gone wrong and was able to fix it.

The reason why i received the error 401.1 overnight after i had done an IISRESET to the web server was because of my domain controller was refreshing the web server group policy at a certain time. The refresh happened to remove the IUSR_SERVER anonymous account from the group policy, threfore any anonynmou account trying to browse the web site would get the 401.1 error. If i run the IISRESET again, the group policy will be reset to the web server's original configuration, thus allowing anonymous users to browse the web site.

The solution to the problem is to edit the Domain Controller Domain Policy. Edit the "Access this computer from the network" policy under the "Local Policies-->User Rights Assignment" section and add in the IUSR_SERVER account into the policy. The next time the DC refreshes the web server policy, the IUSR_SERVER is included in the web server policy also. THe picture below shows the actual setup panel.