30 April 2004

Microsoft CMS2002 installation notes

Install on Windows 2000 with .Net Framework 1.1 and VS.Net 2003

• To install CMS2002 SP1A you need to install CMS2002.
• If CMS dev tool (VS.NET client) is desired, you cannot just install CMS2002 on top of VS.NET 2003. It complains ‘VS.NET is not found’, you need to install VS.NET, including ‘Windows Component Update’.
• Followed the CMS2002 installation guide.
• Apply SP1A.

Install on Windows 2003 Server
• Remember to check IIS and Server side includes have been installed.
• Apply high security template if you haven’t have .Net Framework or VS.NET install. This is the best opportunities to do so.
• No need for IIS LockDown, that is build-in to IIS 6 on Win2k3.
• Install VS.Net(2002) including ‘Windows Component Update’, if CMS 2002 DEV tool is desired. The dev plug-in only workes on VS.Net 2002.
There is a known issue that you need to enable ASP and FPSE on IIS. Follow this:
• Framework 1.1 is installed when installing Win2k3.

If loop-back adapter is used and MCMS SCA, Public, Authoring sites are configured to use a non-default IP address,i.e. localhost, remember to update your DNS host file, and set internet connection option to bypass local address.

Install sample site Woodgrove Bank
Installation gone through OK but I have problems on hitting the site.


The first problem is about running ASP.NET on a Domain Controller
The server I use is configured as a Domain Controller (with Active Directory) -- Windows 2000 Advanced Server, .NET 1.1. Error page like this:


Access to the path "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files\Woodgrove\9c4ac7bd\97d3c1c0\global.asax.xml" is denied.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.


This doc offers a solution:
FIX: ASP.NET Does Not Work with the Default ASPNET Account on a Domain Controller

In practice, I use IWAM_(MachineName), instead of ASPNET. All security policies (Domain Controller Security Policy, Domain Security Policy, Local Security Policy) needed to be update to include IWAM_(MachineName) for Log on as a batch job as pointed out in the above.
Then add IWAM_(MachineName) with full control to physical directory C:\WINNT\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files

Run iisreset.

Now I am getting a different error: missing SeImpersonatePrivilege

[COMException (0x80041b58)]
Microsoft.ContentManagement.Interop.Publishing.CmsHttpContextClass.Initialize(String currentUrl, String httpHostName, Int32 serverPort, Boolean isSecureServer, Int32 iisInstanceId, String remoteMachineAddress, String authenticationType, String authenticationToken, Int32 windowsUserHandle, String ClientAccountName) +0
Microsoft.ContentManagement.Publishing.CmsHttpContext.initialize(IntPtr windowsToken, String cmsAuthToken, String clientUserName, String clientAccountType) +297
Microsoft.ContentManagement.Publishing.CmsHttpContext.getCmsHttpContextFromIdentity(HttpContext httpContext) +1088
Microsoft.ContentManagement.Publishing.CmsHttpContext.get_Current() +57

As documented in CMS2002 SP1 MCMS 2002 - Debugging FAQ

The Account (IWAM_(MachineName) running the ASPNET_WP worker process is missing the SeImpersonatePrivilege privilege when Windows 2000 SP4 is installed.
There are two steps to resolve this problem:
1) Adding impersonation privileges to IWAM_(MachineName) or any account (such like ASPNET) that runs ASPNET_WP worker process. This can be done by adding ‘Impersonate a client after authentication’ to the account in Local Security Settings. Check Microsoft Content Management Server 2002 Service Pack 1 Documentation.

2) Update Machine.config and/or web.config
(c:\WINNT\Microsoft.NET\Framework\{version number}\CONFIG\Machine.config)
As I am running .NET Framework 1.1 for this, I use version v1.1.4322.
Find the ProcessModel node and update the username, password attribute to be
<processModel [other attributes] userName="<domain Name>\IWAM_(machineName)" password="(actual password)"

Wahoo, this problem gone. Now I can see the Woodgrove initial login page, which prompts me for login credentials-a bit strange. It says:
You are using an insecure connection. If you click Continue it will be possible for others to view information you send or receive.

I try to login using a few different identity CMS_SYSTEM, NT accounts that has been grant Author role. I also use IIS console manager to check the properties- directory security to be anonymous/window authentication--seemed fine.
Then I look up the Web.config – notice the authentication mode has been set to ‘forms’ like this:

<authentication mode="Forms">
<forms name="WoodgroveNet" path="/" loginUrl="/WoodgroveNet/Templates/ManualLogin.aspx"
protection="All" timeout="30" >
</forms>
</authentication>
<authorization>
<allow users="*" />
</authorization>

I quickly comment out this and uncomment the Windows authentication mode
<authentication mode="Windows">

Finally got the site working!

19 April 2004

Code optimization

Newcomer has a very good essay on code optimization
In short:
1) The only valid path to optimization is by measuring the performance.
2) Be pragmatic, trivial performance gain doesn’t worth the risk of months work on complicated algorithm, danger of introducing new bugs and code maintenance difficulty.
3) Some looked ‘poor’ algorithm may have magnitude faster than ‘superior’ algorithm, depends on how a particular kernel works (memory paging, allocation method etc). Again, this will only known by benchmark.
4) Don’t bother with GUI code optimisation.

Executive summary: forget performance & optimisation as a developer.

13 April 2004

what does it try to authenticate?

It is a common practice to send user an email containing links to a dynamic generated page which challenges user for credentials. However, it becomes suspicious when the job only done half-way.

MPS online is a nice public service that enables one to register not to receive unsolicited posts. At the end of the registration, it asks for an email address which contains a link that will be required. I click the link; a page opens and acknowledges me registration completed.

All look fine. Wait a minute, what is the purpose of asking user to submit an email address? It only validates 'I' own the email account. If I want to, I can deregister my neighbour John Smith with my email, which may upset him if he loves those ‘bargain hunt’ kind of thing.

A second thought over it, I reckon, MPS probably just want to snap my email address as well -on top of the postal address I surrender for deregister. Ouch!

07 April 2004

Why we need test first development

Here is an other classic example. I bet it will be used in some book sooner or later, like Test Driven Development. Here is the story:
...
"The Chinook helicopters could be a risk to fly in cloudy weather because the software which enables them to do this cannot be properly tested.
Fixing the problem will cost an estimated �£127m and the Chinooks will remain grounded until at least 2007. "Read more...

02 April 2004

Convert a string into an enum

The problem was raised in a project about use type code.

There are numerous type tables in Party etc DB schemas. Many of them used Meaningful VARCHAR2 or number as primary key, such like ECAR, BANK, FIXE or 01, 02 etc.

To use these type codes, the obvious non-brainer way is to hardcode them directly.

Or the political correct yet unpractical way: to access the type table whenever needed.

A better hardcode way is to define them in Enum type and combined with client side type tables. But in this scenario we have a problem: PKs are not natural sequential numbers and we rely on the assigned Enum value. Like this:


enum Colour
{
Red = 100,
Green =103,
Blue =140,
}

The problem arise when serialize the enum type across the wire. Client deserialisation (dominanted by MS WSDL tool) engine will construct a

enum Colour
{
Red,
Green,
Blue,
}

Hence we loss the value.

We did come up with type class idea, but it was quite verbose and boring to implement.

Tim Sneath demonstrates a handy way
to convert string to Enum by using Enum.Prase(…)

Memo: Transforming Dataset to Presentation

In a recent ASP.NET project, I need to retrieve a large blocks of relational data from backend present them in a 2D table. Issue here is data relation are multi-dimensional, involving more than 5 tables. And UI got some fancy buttons kinda thing as well. Data grid is not a viable solution.

Current implementation deploys XmlReader to build the table on the fly. Don't really like it, due to the fact logic code and presentation markup are mixed to produce a massive codebehind.

I am planning to shift this into a nice xml doc and transform it using xslt.

These stuff seemed quite useful:
The initiativesBest Practices for Representing XML in the .NET Framework

CreateNavigator Method

And XSLT Transformations with the XslTransform Class

01 April 2004

use NDoc for .net project documentation

NDoc, another powerful software engineering tool in the N* series. Use the command line tool should make it really easy to integrate with Nant for web base documetation publishing.