戰地連結︰ Home My Flickr NBA.com About

2008年12月11日星期四

Understanding ASP.NET Page Life Cycle and TRULY understanding ViewState

Overview

I once thought that writing an ASP.NET page is like writing a Form in a Desktop Application, all I have to take care are just about event handlers likes "Page_Load", "Button_Click". There is no concept of persisting states in page or controls in my mind ( I am just a Noob...)

Actually I have heard of "ViewState" and used it a few times, but without understanding what a creature it is. It was until I accidentally found that one of my pages had a ViewState of 10+ KB, that I started learning about ViewState.

In order to understand ViewState, one must first have an understanding of ASP.NET Page Life Cycle. Besides, there are two excellent posts by Dave Reed and Milan Negovan that will make you TRULY Understand ViewState.

Reference

  1. ASP.NET Page Life Cycle Overview - MSDN
  2. TRULY Understanding ViewState - Dave Reed
  3. ASP.NET State Management: ViewState - Milan Negovan
  4. Understanding ASP.NET View State - MSDN

Using custom workflow for SharePoint page approval (web content management)

Overview

SharePoint provides a out-of-the-box mechanism for Web Content Management (WCM) in document library (for example: a page author must seek web master approval before his page can be viewed by publish). But sometimes we may want to use our custom workflow for the approval process, and indeed it is possible to do so with SharePoint "workflow settings".

Reference

  1. Content Approval Workflow in MOSS 2007
  2. Customizing the pages approval for MOSS 2007 web content management

Terminal Service Gateway in Windows Server 2008

Overview

Terminal Service & Remote Desktop allow you to access your computer/server virtually anywhere with Internet access. They are very useful and commonly used. However, there is no way to pre-authenticate client or have centralized Authorization Policy settings. Now, with Windows Server 2008 Terminal Service Gateway, we can make use of all this features.

Reference

Configuring the Windows Server 2008 Terminal Services Gateway (Part 1)

Dmitrii blog: Windows Terminal Services Gateway

Steps (Outline only, refer to reference links for Detailed Steps)

Setup the TS Gateway Server

  1. On a server with Windows Server 2008 installed
  2. Add "Terminal Services" role, select "TS Gateway" as Role services
  3. Create a Certificate for SSL connection (Common name must be pointing to the TS Gateway Server IP)
  4. At "TS Gateway Manager", configure the following:
    • Install the Cert created at Step 2 to the TS Gateway Server
    • Configure the "Connection Authorization Policies (CAP)"
    • Configure the "Resource Authorization Policies (RAP)"

Connect to Remote Desktop/Terminal Services thru TS Gateway

  1. For Windows XP / Windows Server 2003 (Not needed for Vista)
    • Download and Install "Remote Desktop Connection 6.0 Terminal Services Client" by this Link
  2. Open "Remote Desktop Connection", click "Options >>"
  3. Go to "Advanced" Tab, "Settings"
  4. Select "Use these TS Gateway server settings" and input the Server name (Common name of the SSL Certificate) and Logon method.
  5. Press "OK" to exit and enter the IP of the computer you want to connect. Beware that the IP here is for the TS Gateway, so it should be IP within the TS Gateway's local network.
  6. Click "Connect" to start the connection.

2008年12月3日星期三

Add validation function to ASP.NET AJAX Tab control

Overview

In my previous post, I talked about how to make AJAX Tab control panel to load on-demand. Now I would like to extend that sample and implement validation function to each tab, so that user cannot change tab if the information they enter is not valid.

I am going to use the out-of-the-box ASP.NET Validator to do the validation, as they provide many useful client-side properties and methods:

  • Page_IsValid - By MSDN it indicates whether the page is currently valid and it is kept up to date at ALL TIMES. it is not very true though... because it need time to update.
  • Page_Validators - An array containing all of the validators on page.
  • Page_ValidationActive - Indicates whether validation should take place, can be turned off at run time.
  • ValidatorValidate(val) - Takes a validator as input and make the validator start validation on its target.
  • isvalid - Very useful property of a validator, it shows that whether a particular validator's state is valid.

For other properties or functions related to validators, please refer to Reference section.

Reference

ASP.NET Validation in Depth

Validator Control Samples

Steps

Modify the AJAX Tab Container in previous example

I will build on the example code in my previous post, here is the modified Tab Container (For "TabPanel1" only):

Code Snippet:

<ajaxToolKit:TabPanel runat="server" ID="TabPanel1">

 

    <ContentTemplate>

        <asp:TextBox ID="TextBox1" runat="server" />

        <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="TextBox1" ErrorMessage="Please enter something!" />

    </ContentTemplate>

 

</ajaxToolKit:TabPanel>

The only thing that I've added is the "RequiredFieldValidator", which will ensure that "TextBox1" has something entered, otherwise displaying the error message "Please enter something!"

 

Modify the Javascript function "ActiveTabChanged()"

Next and the final thing to do is to modify the "ActiveTabChanged()" function to do validation on Tab changed and return to previous Tab if the input is invalid.

Code Snippet:

<script type="text/javascript">

 

        var preActiveTabIndex = 0;

 

        function ActiveTabChanged(sender, e)

        {

            if (sender.get_activeTabIndex() != preActiveTabIndex) // This line is important, otherwise: Infinite Loop!!!

            {

                var valid = true;

 

                // Validate current tab before switching tab

                switch(preActiveTabIndex)

                {

                    case 0:

                        ValidatorValidate($get('<%=RequiredFieldValidator1.ClientID%>'));

                        valid = $get('<%=RequiredFieldValidator1.ClientID%>').isvalid;

                        break;

                }

 

                if (!valid)

                {

                    // Invalid, return to previous tab

                    sender.set_activeTabIndex(preActiveTabIndex);

                }

                else

                {

                    // Change Tab

                    preActiveTabIndex = sender.get_activeTabIndex();

 

                    switch(sender.get_activeTabIndex())

                    {

                        case 1:

                            // Reload "UpdatePanel1"

                            __doPostBack('<%=UpdatePanel1.ClientID%>','');

                            break;

                    }

                }

            }

        }

 

    </script>

As the "TabContainer" object don't store previous active tab index, we have to store it with a variable "preActiveTabIndex".

So the algorithm is to validate the Tab based on "preActiveTabIndex". If the result is valid, then go ahead and change tab, otherwise force the Tab Container to previous tab.

Done!!!

Make ASP.NET AJAX Tab control panel load 'on-demand'

Overview

ASP.NET AJAX Control Toolkit is surely a very useful toolbox for ASP.NET web developer. However, some of the Toolkit's controls are not fully "AJAX" enabled in my point of view.

"AJAX Tabs" is one of the controls that I like the most but also want it to be better. One of the feature I want to (must) have is to make a control panel load 'on-demand' in order to reflect changes made on previous control panels.

Shawn Burke have a post showing a implementation on this feature. I copy it and change it a bit, mainly because I don't need a button to reload the panel. Instead I can just call "__doPostBack('<%=UpdatePanelControl.ClientID%>','')" to reload the update panel.

Reference

How To: Make Tab control panels load "on-demand"

Steps

Build the "AJAX Tab Control"

Building the Tab Control is pretty easy, provided that you have your AJAX Control Toolkit setup properly. (If you don't please go to Here to download the components need to setup ASP.NET AJAX and Here to download the AJAX Control Toolkit)

Code Snippet:

<ajaxToolKit:TabContainer ID="TabContainer" runat="server" OnClientActiveTabChanged="ActiveTabChanged">

 

    <ajaxToolKit:TabPanel runat="server" ID="TabPanel1">

        <ContentTemplate>

            <asp:TextBox ID="TextBox1" runat="server" />

        </ContentTemplate>

    </ajaxToolKit:TabPanel>

 

    <ajaxToolKit:TabPanel runat="server" ID="TabPanel2">

        <ContentTemplate>

 

            <asp:UpdatePanel ID="UpdatePanel1" runat="server" OnLoad="UpdatePanel1_Load" UpdateMode="Conditional">

                <ContentTemplate>

 

                    <asp:Label ID="Label1" runat="server" />

 

                </ContentTemplate>

            </asp:UpdatePanel>

 

        </ContentTemplate>

    </ajaxToolKit:TabPanel>

 

</ajaxToolKit:TabContainer>

 

There are several things that make it works:

  1. First of all, an "Update Panel" inside the Tap Panel you want to load on-demand. Set the "UpdateMode" attribute to "Conditional" is the key to make it reload only when it is supposed to.
  2. A Javascript function which tell server side to load the Update Panel. In this example the function is "ActiveTabChanged" and it is set to "OnClientActiveTabChanged" attribute of the Tab Container, so that it is fired whenever active tab is changed.
  3. A server-side on-load event handler "UpdatePanel1_Load" for the Update Panel in step 1.

Javascript function "ActiveTabChagned" to load the Update Panel

As stated above, a Javascript function attached to "OnClientActiveTabChanged" event of the Tab Container is used to load the Update Panel. Basically it will check the active tab index and do postback of the corresponding Update Panel.

 Code Snippet:

function ActiveTabChanged(sender, e)

        {

            // Change Tab

            switch(sender.get_activeTabIndex())

            {

                case 1:

                    // Reload "UpdatePanel1"

                    __doPostBack('<%=UpdatePanel1.ClientID%>','');

                    break;

            }

        }

In the function I use get_activeTabIndex() method provided by the AJAX Tab Container (the sender) to get the active tab index. On the other hand you may use set_activeTabIndex() method to change active tab at client side.

Update Panel on-load event handler

At this time I have successfully make the Update Panel to load on-demand. Now in order to make sure that it actually reloaded, let's write an on-load event handler to change the text of the Label inside it.

 Code Snippet:

protected void UpdatePanel1_Load(object sender, EventArgs e)

        {

            if (Page.IsPostBack)

            {

                Label1.Text = "On".Equals(Label1.Text) ? "Off" : "On";

            }

        }

 

That's it, Happy Coding ;-)

2008年12月2日星期二

AJAX Control Toolkit - Tab Control Themes

Overview

Damien White have a post discussing how to customize theme in a ASP.NET AJAX Control Toolkit Tab Control.

Reference

AJAX Control Toolkit - Tab Control - Themes