Monday, November 27, 2006

MOSS 2007 and WSS3 Functional Architecture Diagram

Here is the colourful and comprehennsive diagram illustrating the functional architecture of the most latest of Microsoft Office Sharepoint Server 2007 and Windows Sharepoint Services 3.0.

Saturday, November 25, 2006

Release of WSS RTW and MOSS Standard and Enterprise Edition

YOu can download the Release-To-Web version of WSS (Windows SharePoint Services) and Microsoft Office SharePoint Server 2007 Evaluation version at

1. Microsoft Office SharePoint Server 2007 x86 English Evaluation
2. Windows SharePoint Services 3.0

CD Keys available for standard and enterprise edition are

SharePoint Server Standard Trial: XJMKW-8T7PR-76XT6-RTC8G-VVWCQ
SharePoint Server Enterprise Trial: F2JBW-4PDJC-HKXTJ-YCKRP-T2J9D

For more resources about installation, upgrade, versioning, check this link, from Microsoft SharePoint Products and Technologies Team Blog

Thursday, November 23, 2006

Efficient String Concatenation in JS

In .NET, we use StringBuilder if we need to concatenate strings for better string manipulation performance. For instance,

StringBuilder builder = new StringBuilder();
builder.append("This");
builder.append("is");
builder.append("really");
builder.append("good");
builder.append("for");
builder.append("performance");

string str = builder.ToString();

In JS, we can also do the same thing for better memory allocation in string concatenation too.

var builder = new Array();
builder.push("This");
builder.push("is");
builder.push("really");
builder.push("good");
builder.push("for");
builder.push("performance");

var str = builder.join("");


This method will perform faster if the number of string concatenation is huge. THe normal += operator will win, otherwise.

Check Efficient JavaScript for more information on optimizing JS code

Tuesday, November 21, 2006

Invoking Executeable File from ASP.NET Web Services

Below is the code snippet on how to invoke the executable file (exe) from the cmd.exew being executed.

// Execute the Command Prompt
ProcessStartInfo psi = new ProcessStartInfo("cmd.exe");

// Indicating the input read from the process's standard input
psi.RedirectStandardInput = true;
psi.UseShellExecute = false;

// Do not show the GUI of the running app
psi.CreateNoWindow = true;

Process process = null;
try
{
// Execute the cmd.exe
process = Process.Start(psi);

StreamWriter writer = process.StandardInput;

// Write the command to the command prompt
writer.WriteLine("notepad");

}
catch (Exception ex)
{
// do something here
}
finally
{
if (process != null)
{
process.Close();
}
}


The code will simply run the notepad from the cmd.exe. You can just call "notepad" from at line the of ProcessStartInfo psi = new ProcessStartInfo("notepad");, but I am showing how are you going to write the command to the cmd using the StandardInput of Process object.

Similarly, you can call batch file from the cmd to execute command in the batch file too, or store those static command in the resource files (resx) inside the app_GlobalResources folder and get from the key by

Resources.<Resource file name>.<key name>

MSDN Magazine - HTML Help Downloads

If you want to read MSDN Magazine contents wherever you are, you can download the dozens of MSDN Magazine in portable chm format at http://msdn.microsoft.com/msdnmag/htmlhelp.aspx

Use of ResolveClientUrl() method in getting browser-acceptable relative URL

In .NET, we always use tilde (~) to refer to root virtual directory of the web application. For instance,

<asp:Image runat="server" ImageUrl="~/images/mypic.gif" />

However, in order to generate a URL that can be used by client-side browser, the URL is actually resolved in the AddAttributesToRender() of the Image server control.

writer.AddAttribute(HtmlTextWriterAttribute.Src, ResolveUrl(ImageUrl));

That is the reason why you can use "~" in the ImageUrl property. But I afraid this might be the case if you do the same thing upon the normal HTML elements or HtmlGenericControl, such as :

<img src="~/images/mypic.gif" alt="" />

because the browser does not recognise what the "~" symbol stands for. In order to workaround with that, this is where the ResolveClientUrl() method comes into place.

<img src='<%= ResolveClientUrl("~/images/mypic.gif") %>' />

Apart from using it in HTML, it can also be used in code-behind that involves in getting the relative path for the URL. For instance, ResolveClientUrl() method is handy when we are trying to register the javascript reference in code-behind,

this.Page.ClientScript.RegisterClientScriptInclude(this.GetType(),"MyScript", this.ResolveClientUrl("~/images/myscript.js"));

Not only that, you will always need this method in your custom server control development.

Thursday, November 02, 2006

Debugging JS in VS 2005 using Script Explorer

Breakpoint is one of the useful features available in Visual Studio 2003/2005 to allow developers to trace the current value of variable at the location where the debugger is currently running at. Nevertheless, you can set any breakpoint in the code-behind of the aspx page, but not in declaractive page. No particular client-side javascript function codes can simply be set as breakpoint in Visual Studio.

I rarely debug the client-side JS codes, or I can say NEVER! I have tried to debug it using Script Explorer today and it impressed me. To debug the client-side JavaScript functions, you can use the only-visible-in-debugging-environment Script Explorer in Visual Studio 2003/2005. There are few steps need to be followed:

1. Enable Client-side Script Debugging

IE -> Tools Menu -> Options Menu -> Advanced Tab -> Untick " Disable script debugging check box" in Browsing category.



2. In VS environment, write a simple JS function in external functions.js

function MyLoad(name)
{
var message = "Welcome, " + name;
alert(message);
}

Then, invoke the function in body's load() event in ASPX page.

window.onload = MyLoad("Alvin");

3. Press F5 to debug the page. In debug mode, go to Debug Menu->Windows-> Script Explorer (this option only appears in debug mode). The window of Script Explorer will be shown.



4. Once you debugging the page, you will see list of JS files/resources shown in Script Explorer in tree view.



Double click the "functions.js" and set the breakpoint at particular line. The debugger will stop at that line when it passing through it.




Additionals
If your javascript functions are in the aspx page, you can add breakpoint by

Debug Menu -> "Add Breakpoint" -> "Break At Function" -> type your method name there and choose right language.




Read more in MSDN
1. How to: Debug a Client-Side Script from Microsoft Internet Explorer
2. How to: Enable Client-Side Script Debugging
3. How to: Set a Function Breakpoint


I need a break....

Tuesday, October 31, 2006

Accessing GridView's DataControlFieldCell Programmatically

How would you access the auto-generated control in the HyperLinkField (HyperLink control) and ButtonField (LinkButton or Button control) in RowDataBound event ? You will find out that FindControl() method would no longer be working since there is no concrete ID is assigned to the control, and you are not intelligent enough to know what ID will be assigned automatically by the compiler. There are two workarounds, in which the second one is new in ASP.NET 2.0.

Assuming that the HyperLinkField is at 4th column.

First Workaround

protected void GridView1_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hl = e.Row.Cells[3].Controls[0] as HyperLink;
hl.Text = "Changing Text here";
}
}

This workaround is pretty straightward. Cells[3] refers to 4th column (index starting from 0) ; Controls[0] means the first control in that column, which is HyperLink control.

The first workaround is apparently classic way that we used in DataGrid control. But here is the another workaround, which works in different way !


Second Workaround

protected void GridView1_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataControlFieldCell dField = e.Row.Cells[3] as
DataControlFieldCell;
HyperLinkField hlf = dField.ContainingField as HyperLinkField;
hlf.Text = "Changing Text here";
hlf.DataNavigateUrlFormatString = "nextpage.aspx?id={0}";
}
}

As you can see, I am accessing the HyperLinkField itself, and I am able to assign the DataNavigateUrlFormatString property in the RowDataBound event too. Of course, if you would like to access the control in that field, it can be done by

HyperLink hl = dField.Controls[0] as HyperLink;



Hope this helps...

SQL Server Connection Timeout !

Frustrated ! I was given an error message of "Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding." when I was trying to connect to SQL Server 2000 with VS 2005. The connection string was correct and I tried several connection strings :

1. Server=ALVIN;Initial Catalog=pubs;UID=sa;
2. Server=ALVIN;uid=sa; database=pubs";
3. packet size=4096;user id=sa;data source=ALVIN;persist security info=False;database=pubs

(I used sa account for simplication, don't use it in your production site)

But none of them worked for me. I tried it in VS 2003 and unbelievably it worked! (Don't say there is any discrimination) What the heck.. Without any patience left, I saught the answer from Google and I got this link at http://msdn2.microsoft.com/en-gb/library/ms190181.aspx. It explains several causes of the problem, but one of them seemingly is the cause of my problem, which is :

"Database Engine is not listening on port 1433 because it has been changed, or because it is not the default instance, and the SQL Server Browser service is not running."

I tried to go to Client Network Utility and Server Network Utility to change my port number of TCP/IP to 1433 AND reorder it to be the first before the "Named Pipes".




After restarting the SQL Server, it eventually went fine for me. :)

Monday, October 30, 2006

New Features of my Blog

I have implemented my blogger with new Blogger Beta, and it is pretty amazing. The template in HTML is different from the classic template style. There are some new features added in this blog, such as post count in the right-hand-side sidebar, new widgets, new navigation bar. Other features such as blogs searching will be added soon. Although it is not completely nice, it nears to perfection.

For those users who use this blogger, you can visit http://beta.blogger.com/ for the version switching, or visit these sites for helps.

1. http://betabloggerfordummies.blogspot.com/index.html
2. http://groups.google.com/group/blogger-help
3. http://betabloggerfordummies.blogspot.com/


Still figuring out its features and specialities....

Saturday, October 28, 2006

Changes on my ValidTextBox Server Control

I have made some changes to my ValidTextBox server control. The changes are:

1. Supports to display error image instead of text error message when the control is invalid.
2. Supports Tooltips for error image.
3. Fixed bug of email address expression, which allows symbols.

Screenshots:






Please check http://mind.com.my/forums/1018/ShowThread.aspx#1018 for more details...

Sample Programming Interview Questions

I have found there are a set of interview books, relating to Programming - ".NET Interview Questions", "Java Interview Questions", "SQL Server Interview Questions" and so on. These questions are commonly asked by companies during their interview/recruitment process. You may take a look on sample questions at http://www.questpond.com/ , which has a lot of sample questions to be downloaded in zip format.

Some questions are tough!

[ASP.NET] Building Tag Cloud in ASP.NET

What is Tag Cloud. A tag cloud is a way to display a weighted list such that the weight of each item is reflected by the size of the item's text. Tag clouds provide a quick way for one to eyeball a list and ascertain what items are more prevalent.

Scott Mitchell has just written an article of Creating a Tag Cloud in ASP.NET. That is very cool especially you are dealing with blogging or tagging-related sites. I have tested it, and that's nothing but COOL !

Wednesday, October 25, 2006

[ASP.NET] Basic of Custom Server Control Development Part II - ParseChildren(), PersistChildren() and PersistenceMode()

Let us boils down to the three attributes that important in implementing simple properties and subproperties in the custom control development - ParseChildrenAttribute, PersistChildrenAttribute and PersistenceModeAttribute.

Default and Inner Property Persistence
Default persistence is in constrast to Inner persistence, but they are identically same for its functionality. In our control development, we may have complex properties (class). To persist them, we can use hyphenated syntax (Default Property Persistence) or nesting them within your control tags (Inner Property Persistence). Example of Inner Property Persistence,

<asp:GridView ID="GridView1" runat="server">
<HeaderStyle BorderWidth="12" />
</asp:GridView>

In the example given, the BorderWidth is the subproperties of the HeaderStyle property of GridView. To enable this inner property persistence, you need to set the ParseChildren(true) and PersistChildren(false) in your control class.

[ParseChildren(true)]
[PersistChildren(false)]
public class MyWebControl : WebControl
{
...
}


1. ParseChildrenAttribute
This attribute tells the parser to parse the parse the contents within the control tag as properties but not child controls.

To enable the inner default property persistence, you have to specify the inner default property to the second parameter of ParseChildrenAttribute.

[ParseChildren(true, "<DefaultPropertyName>")]
public class MyControl : WebControl
{
...
}


2. PersistChildrenAttribute
On the other hand, this attribute tells the designer whether the child controls of the server control should be persisted as inner child controls. Setting to false indicates inner content corresponds to properties but not to child controls.

* Therefore, the ParseChildrenAttribute and the PersistChildrenAttribute attributes use opposing conventions for the semantics of their argument. Check more difference of these two attributes at Justin Lovell's Blog - The ParseChildren and PersistChildren Attributes


3. PersistenceModeAttribute
This attribute specifies how the property of server control is persisted declaractively in ASP.NET pages. It has 3 enumerations :

EncodedInnerDefaultProperty - Specifies that the property persists as the only inner text of the ASP.NET server control. The property value is HTML encoded. Only a string can be given this designation.

InnerDefaultProperty - Specifies that the property persists in the ASP.NET server control as inner text. Also indicates that this property is defined as the element's default property. Only one property can be designated the default property.

InnerProperty - Specifies that the property persists in the ASP.NET server control as a nested tag. This is commonly used for complex objects, those that have persistable properties of their own.

Picked from http://msdn2.microsoft.com/en-us/library/system.web.ui.persistencemode.aspx

[PersistenceMode(PersistenceMode.InnerProperty)]
public virtual TableItemStyle HeaderStyle { ... }

This indicates that the designer to persist the property as inner property. By default, it is persisted by using hyphenated syntax in control tag. To persist inner default property, you need to have

[ParseChildren(true, "<DefaultPropertyName>")]
public class MyControl : WebControl
{
...
}

and

[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public virtual ListItemCollection Items { ... }



These three attributes are confusing, but are not undifferentiable.

Monday, October 23, 2006

My ValidTextBox is OUT !

After spending 3 days of custom control development, I have successfully developed the beta-period ValidTextBox server control. It basically integrates validator controls (RegularExpressionValidator and RequiredFieldValidator) and normal textbox control to reduce the developers' time and efforts. Here are some screenshots of the ValidTextBox server control.






Check more about the ValidTextBox server control at MIND Forum here

Thursday, October 19, 2006

[ASP.NET 2.0] Post-Cache Substitution

Post-Cache Substitution, a new feature that is not so eye-catching compared to the other new features introduced in ASP.NET 2.0 like Master Pages, Personalization, DataSource Control and etc. Basically, Post-Cache Substitution allows developers dynamically update the contents of output-cached portions (eg. header, footer). When a header user control (header.ascx) is given the following directive

<%@ OutputCache Duration=3600 VaryByParam=none %>

It tells the page to be partially cached for an hour (3600 seconds). If there is current date and time showing in the header section, it is unlikely that the time will be updated for every second since it is cached for an hour long.

There are common 2 ways of implementation of Post-Cache Substitution solves this problem for you - Use of Substitution Control and Substitution API.


1. Substitution Control
This control tells the page not to cache the section for its dynamic contents. Every contents in the control would not be cached.

1. To use this control, drag the Substitution Control from VS 2005's ToolBox and drop it onto your WebForm.

2. The control has a MethodName property, which is assigned to a static method. In the code-behind, define a static method that accepting a page context as parameter.

public static string GetCurrentDateTime(HttpContext context)
{
return DateTime.Now.ToLongTimeString ();
}

3. Back to Design View. In the control's property window, assign GetCurrentDateTime to MethodName property. This ascertains that subsequent requests to the page call the method again to generate dynamic content.



2. Substitution API
This implementation uses the in-lline code, by calling the Response.WriteSubstitution() method that accepting name of method as parameter. Thus, in your ASPX HTML view, add this

<% Response.WriteSubstitution(new HttpResponseSubstitutionCallback(GetCurrentTime)); %>

It would change client-side cacheability to server cacheability, which the dynamic contents are not cached on clients.

Wednesday, October 18, 2006

[ASP.NET] Specifying DefaultButton in MasterPage

In normal ASP.NET 2.0, we can easily assign the DefaultButton property in the

<form runat="server" DefaultButton="btnSearch">


But what if we would like to make two different buttons from two pages that inheriting the MasterPage to be DefaultButton? It might not be working using the way above because MasterPage because it is publicly shared by its content pages. You, however, have to programmatically assign the DefaultButton in each of the content page.

In content Page,

this.Form.DefaultButton = "MyDefaultButton";

This is not the way of assigning the ID of button to DefaultButton property. Use this way,

this.Form.DefaultButton = MyDefaultButton.UniqueID



Cheeers

[ASP.NET] Redirecting Page after Emiting JS in Code-behind

To emit the JavaScript in code-behind in ASP.NET, we use RegisterStartupScript() or RegisterClientScriptBlock() method. But when we would like to redirect user to a specified page after the JS pop-up, we probably would use this (written in VS.NET 2003, use ClientManager for VS 2005)

string strScriptName = "AlertScript";
string strMessage = "There is an error";

string strScript += strMessage + "')<"
strScript += "/"
strScript += "script>"

if(!Page.IsStartupScriptRegistered(strScriptName))
objPage.RegisterStartupScript(strScriptName, strScript)

Response.Redirect("error.aspx");

If you run the code, you will notice that you will be redirected to the error.aspx WITHOUT being prompted the error message dialog box of "This is an error" because Response.Redirect() forces the browser not to render the HTML (sending a header to client to cause client to redirect to specified URL).

To overcome this problem, replace the Response.Redirect("error.aspx"); with

Response.AppendHeader("refresh","0;Url='error.aspx'");

Instead of redirecting the page, the browser would simply refresh the page within 0 second and "redirecting" to the error.aspx, as specified in the Url parameter.

Tuesday, October 17, 2006

[ASP.NET] Basic of Custom Server Control Development Part I

Developing custom server control in ASP.NET is fun! You are flexible to develop it either inheriting the existing ASP.NET server controls like Button, HyperLink, BoundField or create you own control by inheriting Control/WebControl classes from System.Web.UI namespace. There are dozens of cool and fabulous custom server controls developed by third-parties like Metabuilder or ExcentricWorld. I like to develop the custom server control because the tailored controls can specifically accomplish some jobs that normal shipped-in ASP.NET server controls can't. It serves the purpose on your needs.

There are basic concepts/rules in custom server control development in ASP.NET like :

1. Derive your control class from System.Web.UI.Control if your control is dealing with non-visual elements or merely render as HTML output. For instance, META tag. Otherwise, your class should inherit from System.Web.UI.WebControls class if your control is built to have visual appearance to the client.

2. Do not override the Render() method of in your control if it is inheriting from System.Web.UI.WebControls class because the method is responsible in rendering the outer tag and control styling to the output stream. Override its RenderContent() method instead!

protected override void RenderContent(HtmlTextWriter writer)
{
writer.Write("Test");
}


3. When your control inherting the System.Web.UI.WebControls, its outer tag is <span> by default. You can get rid of this and render any outer tags you want by overriding its HtmlTextWriterTag.TagKey or TagName (non-standard HTML tags).

protected override HtmlTextWriterTag TagKey
{
get { return HtmlTextWriterTag.Input; }
}

or

public Button() : base(HtmlTextWriterTag.Input)
{ }



4. Check whether the control is in the <form runat="server"> by

if (Page != null)
Page.VerifyRenderingInServerForm(this);


in either AddAttributesToRender() or Render()/RenderContent() method.


5. By default, the tag prefix of your custom server control would be auto-generated. For instance, when you drag and drop your control, the tag would be something like

<cc1:CustomMeta ID="CustomMetaTag1" runat="server" />

As you see, the "cc1" gives no meaning. You can add your own tag prefix by adding TagPrefixAttribute in the assemblyinfo.cs file.

using System.Web.UI;
[assembly:TagPrefix("SimpleControl", "Alvin")]

Now, it would become like

<Alvin:CustomMeta ID="CustomMetaTag1" runat="server" />


6. Take note of rendering methods of System.Web.UI.Control class

public void RenderControl(HtmlTextWriter writer) {
if (Visible) {
Render(writer);
}
}

protected virtual void Render(HtmlTextWriter writer) {
RenderChildren(writer);
}

protected virtual void RenderChildren(HtmlTextWriter writer) {
foreach (Control c in Controls) {
c.RenderControl(writer);
}
}


It is wise to call the base class's methods if you intend to override the method like RenderChildren method to ensure its child controls are recursively rendered.

protected override void RenderChildren(HtmlTextWriter writer)
{
base.RenderChildren(writer);

// do your stuff
}



7. To restrict the control to have NO CHILD CONTROLS, you need to return EmptyControlCollection(this) to the overidden CreateControlCollection() method.

protected override ControlCollection CreateControlCollection() {
return new EmptyControlCollection(this);
}


By doing that, no child controls/tags are allowed.

// Allow
<Alvin:CustomMeta ID="CustomMetaTag1" runat="server" />

// Not allow !
<Alvin:CustomMeta ID="CustomMetaTag1" runat="server"></Alvin:CustomMeta>