Saturday, July 30, 2005

Session Cookies blocked when Server Name is NOT DNS compliant

While I was trying to tackle the problem of blocked session cookies in our Web_Test server, I found something very important and very few people know so far:

According to Microsoft, after the latest patch of the Servers (or the Browsers):

Cookies on ASP pages are blocked if the server name contains characters that are not supported by Domain Name System (DNS). For example, you cannot use underscore characters (_) in the server name. This behavior is by design.

This fact happens to match our case on Web_Test, because we have ’_’ in server name! So no matter where you are, as long as you use http://Web_Test, or http://Web_Test.MyDomain.com, you will NOT be able to send the session cookies to the client to maintain the session (You still have other way to maintain session in ASP.NET, described later.) But if you use, say, http://192.168.1.77, or, if you are at the server. http://localhost, http://127.0.0.1, you will be OK.

This is NEW to me. I believe also new to many people who get confused why suddenly the session is not working any more!

Why do we have this rule, and when did this start to happen ? Microsoft just mentioned it is security related, and it is already happening.

So how do we solve our own problem with Web_Test ?

Well, the straightforward way is to rename it to, say, WebTest, or Web-Test. Actually, I added the following entry:

192.168.1.77 WebTest

to the hosts file of the machine where browser is at (I did that on MyServer.MyDomain-test.com), then browsed the web server by doing http://WebTest. it worked.

Another way, which is only available to ASP.NET, is to set cookieless = "true" in the following section of the web.config file:

<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;user id=sa;password="
cookieless="true"
timeout="20"
/>

This is ASP.NET’s way to maintain session without cookies. It is quite useful, as more and more people turning off cookies because of security concern.

So, in the future, what kind of server name should we use, to comply with DNS naming convention ?

According to DNS, the characters should supports RFC 1123, which permits "A" to "Z", "a" to "z", "0" to "9", and the hyphen (-). The fully qualified domain name length should be no more than 63 bytes per label and 255 bytes total for an FQDN (Fully Qualified Domain Name)

For details, please refer to:

http://support.microsoft.com/default.aspx?scid=kb;en-us;325192

and

http://www.microsoft.com/resources/documentation/Windows/2000/server/reskit/en-us/cnet/cncf_imp_xvxz.asp

Friday, July 22, 2005

Simulate the Excel Freeze Pane Effect on Web Pages

There are times when people need to enter a long row of information on the web. When scrolling to the right to keep on entering, the user will lose sight of the content of the left. It is needed to overcome this kind of problem for the user by using Javascript/DHTML.

Attached please find the solution with one ASP page and one Javascript. Since most of the work is done at the client side, it works on both ASP and ASP.NET environment with little or no modifications.

Here is the demo:

http://gate.ebizts.com/demo/hscroll2.asp

How to expose COM objects to .NET Framework

To expose COM to NET, we will make a "Wrapper", or "Proxy Assembly", which plays the role of the bridge between the COM object and the .NET applications. This assembly will be put into the /bin sub folder once generated.

To generate this Wrapper Assembly, we will need to run a program called tlbimp.exe, which comes with the .NET Framework. The command line takes a Type Library as the parameter and optionally a output assembly name as another parameter:

tlbimp foo.tbl /out:myfoo.dll

Once the assembly myfoo.dll is generated, it will be placed in the /bin sub folder.
After this, using COM is just like using any other assembly. For example, in VB.NET, the code is like:

Import myfoo

Dim foo as new myfooClass

foo.method1.....
foo.method2....
foo.method3....

The next issue is how to get the type library. Type Library can be a standalone file with the extension of .tlb, or is embedded in the COM dll files, or in ocx, or olb files. If it is embedded into a dll, then the tlbimp command line will be like:

tlbimp foo.dll /out:myfoo.dll (please be careful not to override the original dll, by specifying a different sub folder in /out:, if you want to use the same name as the output.)

If you are using VS.NET, then creating the COM wrapper is as easy as adding an reference. No TlbImp command needed:

To add a reference to a type library

Install the COM DLL or EXE file on your computer, unless a Windows Setup.exe performs the installation for you.
From the Project menu, select References.
Select the COM tab.
Select the type library from the Available References list, or browse for the TLB file.
Click OK.

How to upload file(s) bigger than 4 MB in ASP.NET

The maximum file size you can upload by default is 4 MB. This can be increased in the web.config file by adding the following configuration setting:

<httpRuntime maxRequestLength="4096" />

1,024 Kiliobytes = 1 Megabyte
4096 is the default in Kilobytes. Hence; 4,096 KB is equal to 4 MB. If you want to allow files bigger than 4 MB simply add the above setting so your web.config file looks like this.


<configuration>
<system.web>
<httpRuntime maxRequestLength="4096" />
</system.web>
</configuration>

Converting Java Applications to C#

It is easy to convert a Java project to C# by using VS.NET. Below is the procedure:
Java-Language Projects
To convert a Java-language project

Start Visual Studio .NET
On the File menu, point to Open, and click Convert.
Select Java Language Conversion Assistant, and click OK.
On the Source Files page, click A directory containing the project's files.
On the Select source directory page, click Browse.
Browse to the correct project, and select it.
Note You will not see the files in the directory you select, but all .jav and .java files in it will be converted. All other files in the directory are ignored.
On the Configure your new project page, specify the following:
Name of the project to be created.
Directory in which the any additional files for your project are located.
Note You will not see the files in the directory you select, but all .jav and .java files in it will be converted. All other files in the directory are ignored.
Output type of the project.
On the Specify a directory for your new project page, specify the name and directory of the new project to be created.
On the Begin your conversion page, click Next.
Fix code that could not be converted automatically. For more information, see Manually Upgrading Unconverted Code.

Package Java into COM Object for ASP/ASP.NET

We have discussed how to convert the Java Source code to C# in order to run under the .NET Framework. If we just want to use the Java Classes under ASP/ASP.NET, then there is an alternative. The alternative is to package the Java Class(es) into the ActiveX/COM object by using the Visual J++ development environment.

Please note that Visual J++ is not a language. It is a development environment for Java Developer to develop applications for Microsoft Windows easily. With Visual J++ development environment, it is relatively easy to package Java Classes into COM/ActiveX to be used by ASP/ASP.NET and other languages.

If you already have the Java Class source code, you can follow the steps described below to make it a COM/ActiveX. But before you do this, there are issues to consider:

1. The Windows platform needs to have Windows JVM installed to run this COM/ActiveX. (It is supposed to be the case. But today's Windows Server 2003 does not seem to have it natively)

2. The speed of this ActiveX/COM is some what slower than the native COM/ActiveX developed by C++.

Below is the link to demonstrate the step by step procedures.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnjpp/html/msdn_vjfaq.asp

How to create multiple Virtual Sites in Windows XP Professional

Windows XP Professional does allow you to host web applications, but it only officially allows one web site. That is, no virtual sites allowed like we can do with Windows 2000/2003 Server. This problem can be overcame by editing the metabase, but there are still limitations: you can have only one web site active at a time, other sites have to be stopped.

The procedure(s) to add the 2nd Web Site:

1. Open a command prompt, C:\windows>.

2. cd \inetpub\adminscripts

3. run adsutil.vbs create_vserv w3svc/2 (this command creates the 2nd instance of the web site).

4. run adsutil.vbs copy w3svc/1 w3svc/2 (this command copies the data from virtual site 1 to virtual site 2).

5. Open IIS by using ISM(Internet Services Manager), you will see the 2nd Web Site with the identical name as the first one, because you just copied it. Just change name and other settings to the one you want.

6. Re-register ASP.NET to all the sites:

cd c:\windows\Microsoft.net\Framework\v1.1.4322

aspnet_regiis /i

How to implement Tables in ASP.NET

When it comes to the repetitive items, Microsoft’s ASP.NET encourages you to use one of the followings controls: DataGrids, DataLists, or Repeaters. While DataGrid and DataList Controls are the easiest for displaying/editing database tables, the Repeater Controls provide the best flexibility among the three. All three of them needs to use Data Binding to bind with the database or the data source. They are all powerful, but they are not as flexible as it used to be when we were using tables in ASP.

What if we want to use the good old ASP ways to present a table under ASP.NET. The good old way is to use a While Loop to draw one cell, and then one row at a time, until the whole table is drawn. Yes, ASP.NET does include a server control called Table to allow us to add one cell, then one row at a time in a while loop.

Below is the code segment to show you how to add one row of data to the ASP.NET Table control with the ID of Table1:

private void Page_Load(object sender, System.EventArgs e)

{

// Put user code to initialize the page here

TableRow r = new TableRow();

// build the title row

TableCell c = new TableCell();

c.CssClass = "ItemSubHead";

c.BackColor = Color.BurlyWood;

c.Text="League";

c.Width = 225;

r.Cells.Add(c);

c = new TableCell();

c.CssClass = "ItemSubHead";

c.BackColor = Color.BurlyWood;

c.Text="Date";

c.Width = 180;

r.Cells.Add(c);

c = new TableCell();

c.CssClass = "ItemSubHead";

c.BackColor = Color.BurlyWood;

c.Text="Time";

c.Width = 180;

r.Cells.Add(c);

Table1.Rows.Add(r);

}

Make use of URL Rewriting in ASP.NET

URL rewriting is used to allow the Web users to access many URL’s which does not really exist in the Web Server’s file system. The benefit of that are at least the followings:

1. Use part of URL’s as the parameter (query string) to the application. For example, a Canadian web site which supports both French and English language can use the URL’s to decide what kind of messages the Web Application should show:

http://www.domain.com/en-CA/login.aspx will show an English Login Screen

http://www.domain.com/fr-CA/login.aspx will show a French Login Screen

Inside the server, there is only one URL: http://www.domain.com/login.aspx

2. Hide the aspx extension, and the actual file system structure from Web Site, such that people may not know this is a ASP.NET site,a nd the hacker may not be able to hack the site by playing around the URL’s.

Before ASP.NET, it is hard to achieve this, other than writing a custom ISAPI dll, which is hard. With ASP.NET, we can easily intercept the requester’s URL, parse and rearrange to the real internal URL with the parameters.

To implement URL rewrite, we will need to develop a HTTPModule and include that Module into the web.config file. Like:

<system.web>
<httpModules>

<add name="Localization" type="Localization.LocalizationHttpModule, Localization" />

</httpModules>

</system.web>

The Module itself we intercept each URL request, parse and redirect to the real URL. Please note this Redirect is not the HTTP browser redirect, so it does not take additional round trip between the browser and the server. It redirect internally. It is faster and secure.

Public Sub Init(ByVal context As HttpApplication) Implements IHttpModule.Init

AddHandler context.BeginRequest, AddressOf context_BeginRequest

End Sub

Private Sub context_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)

Dim request As HttpRequest = CType(sender, HttpApplication).Request

Dim context As HttpContext = CType(sender, HttpApplication).Context

Dim applicationPath As String = request.ApplicationPath

If applicationPath = "/" Then

applicationPath = String.Empty

End If

Dim requestPath As String = request.Url.AbsolutePath.Substring(applicationPath.Length)

LoadCulture(requestPath)

context.RewritePath(applicationPath + requestPath)

End Sub

For detals, please refer to the following URL:


http://www.codeproject.com/aspnet/LocalizedSamplePart2.asp

SQL Server Database Maintenance: File Size

To Shrink the size of the database data file or the transaction Log by using Query Analyzer. Let’s say The database name is called BNET.

Use BNET

DBCC ShrinkFile (BNET_Data)

DBCC ShrinkFile(BNET_Log, 2)

The parameter 2 means you hope you can shrink the Translation Log to 2 MB.

The transaction log can grow very big, and the DBCC ShrinkFile will not be able to Shrink, if the system thinks there are incomplete Transactions in the Transactions Log. If you don’t not care about the pending transactions, or if you think all the transactions you need is already in BNET_Data, you can use the following command:

Backup LOG BNET with Truncate_Only

After this is done, run:

DBCC ShrinkFile(BNET_Log, 2)

again to make sure the size shrinks to 2 MB.

SQL Server maintenance: Indexes Tuning

Microsoft SQL Server has the capability to help you decide which index(es) to add after monitoring your "typical" database access activities for long enough time. To do this, Start Profiler in Microsoft SQL Server, then New a Trace and Run. After you have collected enough "Typical" database activities, you can stop and save the trace, then use the Tools -> Index Tuning Wizard to let the wizard analyze your trace and made suggestions on you. If the suggestions make senses to you, you can just accept it and the wizard will automatically add/modify the indexes for you.

MS SQL Server DBCC CheckDB command

DBCC CheckDB (’dbname’) is used to check and optionally repair the Database Allocation Consistency and the Index Pointer Correctness of the Database. It is the combination of DBCC CheckAlloc and DBCC CheckTable commands.

DBCC CheckDB can run when the system is running, but it is not recommended to run when Intensive Transactions are in progress, or when the database backup is running. DBCC CheckDB is using tempdb to sort and store working data, so it is recommended to make tempdb big enough to speed up the Check/Repair Process.

If the database only reports allocation error, we can just run DBCC CheckAlloc to check and repair, save time and resources. If we just want to check/repair the data, index, and field type text, ntext, and image fields of certain table, we can just run DBCC CheckTable (’tablename’).

Below are the command syntax and the examples of DBCC CheckDB:

Syntax
DBCC CHECKDB
( ’database_name’
[ , NOINDEX
| { REPAIR_ALLOW_DATA_LOSS
| REPAIR_FAST
| REPAIR_REBUILD
} ]
) [ WITH { [ ALL_ERRORMSGS ]
[ , [ NO_INFOMSGS ] ]
[ , [ TABLOCK ] ]
[ , [ ESTIMATEONLY ] ]
[ , [ PHYSICAL_ONLY ] ]
}
]

Examples
A. Check both the current and the pubs database
This example executes DBCC CHECKDB for the current database and for the pubs database.

-- Check the current database. DBCC CHECKDB GO -- Check the pubs database without nonclustered indexes. DBCC CHECKDB (’pubs’, NOINDEX) GO
B. Check the current database, suppressing informational messages
This example checks the current database and suppresses all informational messages.

DBCC CHECKDB WITH NO_INFOMSGS GO

MS SQL Database Backup and Restore

We can make MS SQL server backup a scheduled activity or a one-time manual process. The simplest way to do the backup is going to the Enterprise Manager, right click on that database, pick All Tasks, and pick Backup Database. Over there you can choose the devices or files you want to backup your Data and/or Log file of the database to. You can also decide whether this is going to be a scheduled task to one-time task. The backuped files can be appended to the backup media, or overwrote to the backup media.

To Restore the database(s), go to the same place to restore from your backup device(s). At some point we will need to overwrite the data and the log when needed, if we really want to restore. To make it 100% safe just in case restoration fails, you can backup data and log files to some other place first. To know where the data and the log files are, right click on the database in enterprise manager, click properties, the click on Data Files for the location and the Transaction Log for the location.

If the Master Database is damaged, then it is a different story: The SQL server will not run at all!

Let’s assume we already have a backup master, then all we need to do are the following steps:

1. Build The Master Database from scratch by a command line utility rebuildm.exe.

2. Start the SQL server in single user mode (sqlserver.exe -c -m)

3. Restore Master database from the backup device.

4. Restore msdb database from the backup device.

5. Restore other databases, if applicable.

For details, please go to:

http://www.dbarecovery.com/restoremasterdb.html#T-SQL

Commonly used SQL Server 2000 Performance Monitors

The following items are common used "Health Meter" for SQL Server 2000:

SQL Server/NT Server Performance Monitor. (Displaying a wide range of system parameters. Activated by: Start->Run->PerfMon)
Current Activity Window. (Showing SQL Server Current Processes and Locks. Activated by: Start -> Programs -> MS SQL Server -> Enterprise Manager->Select a server->Management->Current Activity)
SQL Server Profiler. (Trace and Fine Tuning SQL Server Activities and Indexing. Activated by: Start -> Programs -> MS SQL Server -> Profiler.)
sp_monitor (Show how busy the SQL server has been. Activated by Start -> Programs -> MS SQL Server -> Query Analyzer -> sp_monitor)
sp_spaceused (Show how much disk space the table or database has used. Activated by Start -> Programs -> MS SQL Server -> Query Analyzer -> sp_spaceused)
sp_who (Show current users and status. Activated by Start -> Programs -> MS SQL Server -> Query Analyzer -> sp_who)
sp_lock (Show current lock and block information. Activated by Start -> Programs -> MS SQL Server -> Query Analyzer -> sp_lock)
DBCC commands (Database consistency checker. Activated by Start -> Programs -> MS SQL Server -> Query Analyzer -> DBCC .......)

Web Programming Security: SQL Injection

SQL Injection is a way the web hackers taking advantages of the programming habit of the common web developers to gain access to the protected system. It will allow the hackers break into the Login/Password screen without even knowing the login name and/or the password.

In many web login pages, the typical user interface has a field called, say Login, and a fields called, say Password. When the users enter the login and the password, the program will check if this user is authenticated by running the SQL like:

Select * from Users Where Login = ’" & Login & "’ and Password = ’" & Password & """

If the record exists (not EOF), this person is authenticated. If not (EOF), not authenticated.

It looks correct, but from hacker’s eye, it is not. The hackers will be able to enter the system by filling the Login box with:

’ or 1 = 1 --

and leave blank to the Password.

It will effectively make the SQL statement become:

Select * from Users where Login = ’’ or 1 = 1 --’ and Password = ’’

This is effectively equal to

Select * from User Login = ’’ or 1 = 1

Since -- makes the statement after it irrelevant.

At this point, this hacker is authenticated. It is scary.

How to prevent this from happening ? First of all, check the input box to see if there is anything unusual, like symbol ’ or =. Secondly, make SQL statement harder to guess. For example, if you make a SQL statement check the User Name first. If the user exist then check the Password of that record against the password entered.

SQL1: Select * from Users where Login = ’" & Login & "’"

if SQL1 is not EOF then compare the Password from that record to the Password Entered.

SQL Injection can be applied to many places, not just Login Screen. The Hackers can alter the path of your program by predicting how you write the code and the SQL and "HiJack" your code to do the things they want to do. Please be careful.

Additional Network Troublshooting Methods

To verify or check TCP/IP routing table, you can use route print command. To add a route until next reboot, use route add command. To add a route permanently, use route add -p command.

To check local computer’s IP related settings, type ipconfig /all. This will show all related IP information including IP address for each interface, Mac(LAN card) address, default Gateway, Subnet Mask, DHCP server IP address, and DNS server names.

To release an DHCP assigned IP address, do ipconfig /release. To renew an DHCP assigned IP address do ipconfig /renew. For many Wireless Bridges/Routers, they will need you to enter Mac address into the bridge/router to enforce the security. ipconfig /all is the command to find out Mac address.

Just as DNS maps from DNS name to IP address, ARP, or Address Resolution Protocol, maps from IP address to Mac address. To check the current ARP table of this host, use arp -a, to add an ARP entry, do arp -s. we will need to use ARP to make sure the IP we are pinging is the host we intend to ping.

Common Network Troubleshooting Methods

There are DOS prompt commands helping you to conduct the TCP/IP network troubleshoot: ping, tracert, nslookup, route, telnet.

Ping is used to test point to point connection. If ping an IP is successful, it means the TCP/IP network between them is OK, but not sure abut DNS; if ping an DNS name is successful, that means DNS is OK too.

If ping an IP is not OK (time out, or unreachable), we can use tracert to know which routing segment of the whole path has problem.

If ping an DNS name is not OK, then we can use nslookup to test if your DNS is in good condition. You can either host DNS yourself, or ask your ISP to host your DNS.

There is a web site called http://www.dnsstuff.com. This site has lots of tools to help you to make sure you DNS and SMTP e-mail server are correct.

If you can ping the other site by DNS name, but still can not access that site via HTTP or FTP or SMTP or POP3, then you can use telnet thatsite portnumber to diagnose the problem. For example, telnet bnet.thesite.com 80 will be able to communicate that site using HTTP. You will need to be familiar with HTTP to continue the test. For example, the first command after this line can be:

get /

to get then home page displayed.

TCP/IP Network Settings and Terms

If a host is NOT using DHCP, then there are at least the following settings need to be filled by yourself manually:

IP Address: 192.168.1.101

Subnet Mask: 255.255.255.0

Default Gateway: 192.168.1.1

DNS Server IP: 206.13.28.12

(The numbers above are just examples.)

IP Address, or IPv4, is a 32-bit representation of a unique ID in the TCP/IP network. It has to be unique, such that the world will reach you when sending information to this IP address. Since most of the corporate TCP/IP networks are behind the firewalls, so the corporates can define their own TCP/IP addresses. Most commonly used ones are 192.168.1.x for Class C network, and 10.10.x.x for Class B network. In general, there is no way to reach the host behind the firewall with the IP address like 192.168.1.101, since there is no public host assigned to this kind of non-routable IP addresses.

When the web browser of this host 192.168.1.101 tries to send an http request to, say, www.yahoo.com, it will do the followings:

1. The browser tries to contact the DNS server, in this case 206.13.28.12, to know what the IP of www.yahoo.com is. (But how does 192.168.1.101 know how to reach 206.13.28.12 in the first place ?)

2. The host will apply the "Mask" operation, which actually is the bit-by-bit AND operation, between the destination, which is 206.13.28.12, and the subnet mask, which is 255.255.255.0. The result is not zero. So the host knows there is no direct link between itself and the DNS Server.

3. The host will have to go to the routing table to find the best route. Eventually it finds the default route, the default gateway. The IP of the default is 192.168.1.1. Please note that the "Mask" result between the Host and the default route has to be zero.

4. The host sends a DNS query regarding "what is the IP address of www.yahoo.com" to the default gateway.

5. The default gateway eventually send the DNS query to the DNS server and get back the answer to the host. The answer is: 66.94.230.36.

6. Finally, the browser goes through step 2, 3, and 4 again to send the http Get request to www.yahoo.com, and gets the response back.

The whole process takes two round trips to the Internet just to get one home page of www.yahoo.com. In the subsequent requests to www.yahoo.com, the first round trip can be saved as the browser may use the cache value 66.94.230.36 to try first.

If you are using DHCP, you still need to have IP address, Subnet mask, Default Gateway and DNS server on the host. The difference is you don’t need to manually setup them yourself, you get them automatically when your system boots up and requests them from the DHCP Server.

Tuesday, July 19, 2005

How to convert the Numeric Unicde to Real Unicode

Below is the VB code segment to convert the numeric unicode &#.....; to Real Unicode in KnownAs field of a table X:

Private Sub Command1_Click()
Dim Conn As New ADODB.Connection
Dim RS01 As New ADODB.Recordset
Dim ConnStr As String

'Set Conn = Server.CreateObject("ADODB.Connection")
ConnStr = "Provider=SQLOLEDB;Server=someserver;Database=somedb;Uid=someuser;Password=password;"
Conn.Open ConnStr

SSQL = "select * from userlistcsv_unicode2"
RS01.Open SSQL, Conn, adOpenDynamic, adLockPessimistic

Do While Not RS01.EOF
KAStr = RS01("KnownAs")
RS01("KnownAs") = UniConvert(KAStr)
RS01.Update
DoEvents
RS01.MoveNext
Loop
RS01.Close
Set RS01 = Nothing
End Sub
Function UniConvert(Str)
' 陈舵蛻
parts = Split(Str, ";")
xx = ""
For Each part In parts
pos = InStr(1, part, "#")
If pos > 0 Then
xx = xx & Left(part, pos - 2) & ChrW(CLng(Mid(part, pos + 1)))
Else
xx = xx & part
End If
Next
UniConvert = xx
End Function

How to convert big-5 tables to Unicode tables

If a Table X in a database contains the following codes (other than ASCII):
1. Big-5
2. Encoded Unicode. Like 陈
Our goal is to convert the Big-5 ones to Unicode and leave the Encoded Unicode alone. As long as we can achieve this, we will be able to display Unicode from any country correctly from the Web Browser. As to how to convert the Encoded Unicode into "Internal" Unicode, we can use a one-shot VB program to convert, and we can discuss this later.
Step 1: Export X table to ANSI CSV Text file on a English Windows Platform.
Use DTS Import/Export Wizard.
Source is X table
Destination is a CSV Text file. ANSI encoding. First Row contains Field Name.
Step 2: Convert this Text file to Unicode.
Copy this file to a Big-5 Win2000 platform.
Open this file by NotePad.
Save As Unicode.
Copy this file back to the place ready to import to SQL server.
Step 3: Import this Unicode Text file to X table.
Use DTS Import/Export Wizard.
Source is this Text File
Destination is X Table (I suggest we backup the old first just in case).
Choose Delimited, Unicode, First Row contains Field Name.
Once imported. You can use the attached asp code to verify the correctness of the code. This simple unicode ASP file only display one field: KnownAs.
Database Application Test: Simplified + Traditional Chinese + Japanese + Korean
©P¤pµX
¥Ó¯À±ö
³¢­ì§Á
ªL±ê¶Ô
¤ý¦æ°·
±d»ï¤å
马畅
¤ýܦ­d
¤ý½U
©s¥çÚ|
­S¬üªÚ
°ª®Ú伟
刘华
§õµq
¸â¦i®p

How to use COM object in .Net Code

There has been a lot of investment in COM/MTS/COM+/Win32 DLLs, and it will not be feasible to migrate that entire code base to .NET. But you don't have to worry about it because you can access your legacy code from .NET code and vice versa.

The steps:

1. Create a "Wrapper DLL" by doing: tlbimp OriginalCOM.dll OriginalCOM_net_wrapper.dll

2. Compile your code which uses this COMObject (sample below) by using the following switch:
csc /reference:OriginalCOM_net_wrapper.dll /out:ManagedClient.exe ManagedClient.cs
3. Sample Source code of ManagedClient.cs:


1 using System;
2 using OriginalCOM;
3
4 class ManagedClient
5 {
6 public static void Main()
7 {
8 CTest objTest ;
9 objTest = new CTest() ;
10 string strMessage = "15Seconds reader" ;
11 strMessage = objTest.SayHello(strMessage) ;
12 Console.WriteLine(strMessage) ;
13 Console.WriteLine("\nPress any key to exit") ;
14 Console.Read() ;
15 }
16 }


For complete details, please go to:

http://www.15seconds.com/Issue/010129.htm

Null value in Database

Null can be inserted, updated, and searched in SQL:

If you have a table T1(F1, F2, F3, F4) where F1 is Text, F2 is Date/Time, F3 is Long Integer and F4 is Currency, then you can insert Null:

Insert Into T1(F1, F2, F3, F4) values(null, null, 100, 101)

You can Select based on Null

Select * from T1 Where F1 is Null

You can update a field to Null:

Update T1 set F4 = Null where F1 = Null

You can Insert part of all the Fields and leave all the other Fields Null

Insert Into T1 (F2, F3) Values (#2/3/03#, 100)

(F1 and F4 will be Null)

I have tested all of them on MS Access 2000 database.

How to prevent too frequent refreshes from Web Broswers

No matter we are using ASP or ASP.NET, each time we post back, we refresh the whole screen, or whole frame. The reason is that the client almost always use the "submit" way (ASP way), or click buttons running at Server (ASP.NET way) to communicate with Server. These will eventually trigger the "Post Back" effect to refresh the whole screen. ASP.NET is handling it better with the View State, but still not prefect. There are still too many unnecessary refreshes. Below is a method, which uses Client Side Script with XMLHTTP, and the DIV tags to reduce the number of refreshes.This idea can be applied to both ASP and ASP.NET.

We know by making DIV display or not display, we can change the content of the client without refresh. We also know that using XMLHTTP object from client, we can send and receive XML data to and from server without postback. Combining these two, below is an example for your reference. (doubleclick the orders for the order details without refresh.)

http://gate.ebizts.com/orders/stores.asp

The source code is attached. for further information, you can go to:

http://www.aspalliance.com/das/xmlhttp.aspx

RTE control for ASP

The RTE we have so far is a framework which consists of a bunch of Javascript files scattered around a web page. The major disadvantages of this RTE are:

Not easy to use. The programmers have to know where to put which files at the right sequence.
Not possible to have more than one RTE in a page.
No undo, redo, save to file functions.
To overcome these drawbacks, I developed a new version of RTE, which is based on the RTE for ASP.NET I mentioned before, to make it work for ASP. It is not as flexible as The Custom Server Control in ASP.NET (ASP does not have the concept of Server Control), but it is a COM object fairly easy to use. Please take a look at the demo at:

http://gate.ebiztscom/RTFBox/asp/RTETest.asp

The RTETest.asp is attached:

RTETest

A ready to use SepllChecker with RTFBox for .NET

I just integrated the NetSpell Open Source Spell Checker with our RTFBox. Please take a look at:

http://gate.ebizts.com/netspell/sample1.aspx

The sample RTF code which includes Spell Checker code is here.

An Open Source Spell Checker Written in C# for Dot Net

NetSpell is a open source spelling checker written in C# under Dot Net environment. It uses the dictionary from OpenOffice.Org. The English version has 162,573 words. It has sophisticated Words Suggestion Algorithm and Near Miss Strategy, Phonetic Strategy. To gain the performance, the word list, or dictionary are compressed using Affix Compression.

I have already installed and did some evaluation. To see the demo, go to:

http://gate.ebizts.com/netspell

The user interface is not as slick as other commercial product, but that is something we can improve. It is pretty easy to plug into our Dot Net based Web server.

The NetSpell open source URL:

http://sourceforge.net/project/showfiles.php?group_id=76171

Use MSMQ to communicate between COM and NET

There are times when two processes will need to talk to each other. Besides the simplest ShellExec way, there are many other Process Synchronization and Synchronization methods provided by the specific language. But to make two or more loosely coupled processes written in different languages to communicate, MSMQ (Microsoft Message Queue) is one of the best methods: you create a queue and others join the queue. You put whatever messages into the queue, and others consume the elements in the queue. It provides both Process Communication and Process Synchronization between EXE/DLL written in, say, VB, and EXE/DLL written in, say, C#. Below is an example from MSDN:

http://msdn.microsoft.com/msdnmag/issues/03/12/MSMQandNET/

How to use Win2000 Server CDOSYS Event Sink to Process e-Mails

It is possible to register a DLL or VBScript to the Windows 2000 SMTP Event Sink, such that when E-mails arrives, or posted, will trigger the DLL or the VBScript to do certain process like Spam Block or E-Mail Redirect.

To accomplish this, we will need to download a vbscript called smtpreg.vbs from the Windows 2003 Platform 2003. The purpose of this this smtpreg.vbs is to register and to unregister the DLL’s and the VBScripts on certain events like "onarrival", "onpost" etc.

For example, if you have a DLL used to log the incoming e-mail. The registered PROGID of this DLL is called CDOTest.Class1. Now, to register this DLL to the Windows 2000 CDOSYS, type the command line:

cscript smtpreg /add 1 onarrival CDOTest.Class1 "mail from=*"

This means, on all the incoming e-mails (mail from=*), please call the class in a DLL who is registered to the registry as CDOTest.Class1.

The VB source code of this DLL is like:

Implements CDO.ISMTPOnArrival
Implements IEventIsCacheable

Private Sub IEventIsCacheable_IsCacheable()
’ just returns S_OK
End Sub

Private Sub ISMTPOnArrival_OnArrival(ByVal Msg As CDO.Message, EventStatus As CDO.CdoEventStatus)

Dim fs As New Scripting.FileSystemObject
Dim file As Scripting.TextStream
Set file = fs.OpenTextFile("c:\yamabay\test.log", ForAppending, True)
file.Write "From: " & Msg.From & vbCrLf
file.Write "To: " & Msg.To & vbCrLf
file.Write "Subject: " & Msg.Subject & vbCrLf & vbCrLf
file.Write Msg.TextBody & vbCrLf & vbCrLf
file.Close
EventStatus = cdoRunNextSink
End Sub


After you have made the DLL, registered it, and type the smtpreg.vbs command, the incoming mails will be recorded in c:\yamabay\test.log.

Click here to find the VB Project and smtpreg.vbs

Monday, July 18, 2005

How to use Perl/PHP in .NET Environment

Perl is a popular scripting language on Unix/Linux based system, and PHP is a Web computing platform using Perl as the programming language. To convert Perl/PHP based code/components to Microsoft ASP/ASP.NET platform, there are at least two approaches:

1. Package the Perl code into an ActiveX component and used it by various languages. For details, please see:

http://www.extropia.com/tutorials/misc/perl_com.html

2. Manually convert PHP code to VB.NET. For details, please read:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/aspnet-migratingphp-aspnet.asp

Approach 1 is easier, but you have to have someone who knows perl for future maintenance.

Approach 2 may take more efforts, but once converted to VB.NET, it is native .NET language. No Perl/PHP expertise needed any more.

Upload File in ASP environment without using Post Acceptor

Using Post Acceptor has always be a problem, because of the following drawbacks:

1. Session will be disconnected. That is, session variable will not be available.
2. Need to install CPSHOST.DLL on the IIS server and change the Registry entry. This is not portable and not easy to deploy the Web applications.
3. Not Reliable.

Click here to get the FilePost.htm and FilePost.asp which does the File Post job by the ASP code itself, so the above problems are automatically resolved.

The way to use FilePost.asp is very similar to the way we use PostAcceptor. It takes TargetURL as the file upload URL (default is the current virtual dir). Multiple files uploads are allowed.

How to Pass Client Time (and time zone) to Server with different locale id

As we know, different locale has different way of describing Date, Time, Currency, etc. For example, French (Belgium) can describe their date in dd.mm.yyyy format. If you need to pass the client timezone information and date time information to server for logging or performance measurement purpose. You will need to use client site script(s) to accomplish these.

Here is the javascript code to get the client time zone information:

function TimezoneOffset() {

var ldNow = new Date();

var lnOffset = ldNow.getTimezoneOffset()/60; // time zone in hour

lnOffset = -lnOffset; // make it Negative. For example, PST is -8, EST is -5.

FRMLGN.tz.value = lnOffset; // assume the form name is FRMLGN and the control name is tz

}

Here is the vbscript (Javascript similar) to pass the date/time information to server in U.S. ("en-us") locale.

Original = SetLocale("en-us")

FRMLGN.ltime.value = FormatDateTime(Now()) ’the form name is FRMLGN and the control name is ltime

Something = SetLocale(Original)

The once the server receives ltime value in Request("ltime"), it is easy to process by using CDate() or other functions suitable for the current locale, which I assume is "en-us".

Using Visio to generate .NET Code Skeleton, etc.

There is a version of Visio, Visio for Enterprise Architect, sold with Visual Studio.net 2003 System Architect. This version of Visio can help to generate the class skeleton once the UML is drawn, or to reverse engineer a Visual Studio project from code to the class diagram components of the UML.

To reverse engineer from code to UML, in VS.NET do Project --> Visio UML --> Reverse Engineer.

To do code gen, from Visio for Enterprise Architect, open the UML vsd, then do UML --> Code --> Generate.

Events and Delegates in .NET environment

Events and Delegates are a pair of terms Microsoft used to deal with the event handlers (function pointers) and events in .NET environment. It is very important to learn Events and Delegates if a develop wants to move beyond just the application development into system/component development.

In short, Delegate is just a function pointer. Any function which has the same signature as the delegate can be passed into the constructor of this delegate and becomes a registered function.

An Event a just a variable with the type of a specific delegate. Once declared as a Event, this event can add these registered function(s) (can be more than one) to become the event handlers.

For example, OnClick is a event for a Button. If we have added some functions (through the Delegate mechanism) to this event, then when this Button gets clicked, ALL the registered functions will be called.

Please note that there is no such concept called Delegate in Java, even though Java does support event handlers. For the complete explanation, please refer to:

http://www.codeproject.com/csharp/events.asp

Call WebServices from ASP using Classes

Calling Web Service from ASP.NET is quite easy. To call Web Services from ASP, we sued to use SOAP SDK. But that is not necessary.

Actually, we can develop a class called, say, WebService, in a ASP page, and use that class to call Web Services. Inside this class, we use:

Set xmlhttp = CreateObject("Microsoft.XMLHTTP")

to communicate between the Web Service and the ASP,a nd then use

Set mCol = CreateObject("Scripting.Dictionary")

to manage the web service parameters in a form.

Once we have the class ready, the caller code is as simple as below (assuming you have already included the webservice class in your page:

dim ws

set ws = new webservice
ws.url = "http://localhost/yourwebservice.asmx"
ws.method = "MethodName"
ws.parameters.Add "ParamName1",1
ws.parameters.Add "ParamName2",300
ws.parameters.Add "ParamNameN",500

ws.execute
response.Write ws.response

set ws = nothing

For details, you can go to: http://www.codeproject.com/asp/aspcallwebservice.asp

The source code of the WebService Page can be downloaded here:

http://www.codeproject.com/asp/aspcallwebservice/aspcallwebservice_src.zip

How to make HTML E-Mail with embedded images

Many HTML based e-mails have images linked to the world wide web. While the size is compact, but there are the following drawbacks:

1. The linked object/image may be deleted in the future, such that the the content of the e-mail will not be archived.
2. The E-Mail reader may not have Internet access at the time reading the e-mail (off-line reading case.)

If we can make the images embedded into this HTML file and make this HTML file self-contained, then we will not need to worry about the availability of the image and the availability of the Internet. This is particular important if you want to keep a news story happened two years ago with pictures .

You can implement this by using CDONTS (NT/2000) or CDOSYS(2000/2003 Server).

In CDONTS:
If we have a image source = logo.gif, then we will need to use the following code to include this Logo to our e-mail:
Set eMailObj = Server.CreateObject("CDONTS.NewMail")
eMailObj.BodyFormat = 0
eMailObj.MailFormat = 0
eMailObj.Body = ......... 'html code with Img Src of Logo.gif
eMailObj.AttachURL MapPath("Logo.Gif"), "Logo.gif"
eMail.Obj.Send

In CDOSYS:

Set iMsg = Server.CreateObject("CDOSYS.Message")
'prepare strHTML and make Img Src Login.gif
iMsg.HTMLBody = strHTML

iMsg.AddRelatedBodyPart MapPath("Logo.gif"), "Logo.gif", cdoRefTypeId 'cdoRefTypeID = 0

iMsg.Send

Disable AutoComplete for Login Forms

The AutoComplete feature of the Internet Explorer is convenient, but it is insecure if you use a shared computer to login, or some people comes to your computer to login as you. They even don't need the user name and the password. The browser will autocomplete for them.

There is a way to turn off AutoComplete from the IE browser (Tools->Inter Options->Content->Auto Complete), but in many cases you either forgot to turn off or your are using shared computers which has the settings you can't change. Even you turn off to make it safe, you still want to turn it on for some Web applications.

Autocomplete=off is an attribute you can add in the login form tag to disable the autocomplete for that form, regardless of the IE settings. I suggest we add that for all the Web Login applications. After the implementation, please test it comprehensively too.

How to Integrate CHAP Login Autehntication with the encrypted passwords in database

We have talked about the Yahoo Mail Compatible CHAP login in my last message, we also have talked about MD5 encrypted password in the database back the while ago. Now, how do we integrate them to make the passwords secure for both Internet Users and the Database Users.

When the users create/assign the password on the password creation/modification screen, at the Javascript/client side, we send back the followings to the Server:

X = MD5(password)

When server receive this MD5(password), it just save it to the password database field, so the database users will not be able to view the clear text password.

When this user logs in, the server sends the Challenge, and he/she types user and and password. The client side Javascript will do:
X = MD5(password)
Y = X + Challenge
Z = MD5(Y)
and send back Z and Challenge to the Server. (This is the standard client side CHAP we discussed last time)

Now, the server will use W= MD5(password) from the database. Then do a
V = W + Challenge
U = MD5(V)

If U and Z are equal, then password is correct. Otherwise not correct.

Please note that:
1. Password never travels across the Internet.
2. Dataset does not store the clear text password.

This concludes the integration of CHAP Login and encrypted password in database.

CHAP Login Security Implementation

"How secure is your system ?" is always the question any potential customers will ask. If we only have password protection for our sites, it is not enough and people may reluctant to use this product.

I recently developed a "CHAP Login" mechanism which will make our Web Server more secure. The term "more secure" here means harder to intercept the password, and/or harder to break in without the password.

First of all, CHAP is one of the industry recognized authentication protocol, it stands for "Challenge/Handshake Authentication Protocol". The benefits of this protocol are:

1. Password never travel across the Internet, only the generated Digest, or Hash, does.

2. The Server Challenges the Browser with a random number, called Challenge, each time when it presents the Login Screen. The Challenge will be used, together with the password, to generate the Hash/Digest. The will prevent from the so called "Replay Attack", which intercepts a successful login session and break in.

I have implemented it on one of my Web system and test it successfully. It is located at:

http://www.yamabay.com/NTPortal/webMail/inbox/loginy.asp

You can use the user test and password test to try it out.

It takes a Server Site COM Object and the Client Site JavaScript to accomplish this. Source code are attached.

By the way, Yahoo! Mail is using exactly the same login mechanism as I mentioned here.

How to configure MSDE (Microsoft Database Engine) without using SQL Server 2000

MSDE is a limited version of the Microsoft SQL Server. In short, it is the Microsoft SQL Server 2000 database engine without any of the fancy UI tools, and with some limitations in the database size and the number of connections. The MSDE database is free, and can be distributed embedded in your own applications or as a small stand alone SQL server. It is ideal for small websites and small businesses with less than 25 simultaneous users. The database is limited to 2 GB of data storage space, but you can easily upgrade it to a full Microsoft SQL Server without any limitations.

The problem of using MSDE is you do not have any fancy UI tools to do the followings:

Manage MSDE Server instances and System Administrator Passwords
Manage Database Users
Manage Database (Create Database, Delete Database)
To install MSDE from command line:

C:\...MSDE\>Setup.exe DISABLENETWORKPROTOCOLS=0 SAPWD="password "INSTANCENAME="myinstance"

To create Login Users:

1> use master
2> go
1> EXEC sp_addlogin ’lars’, ’pass45’, ’larsinge’
2> go
New login created.

To grant Access to the databases:

1> use larsinge
2> go
1> EXEC sp_grantdbaccess ’lars’
2> go
Granted database access to ’lars’.
1> grant all on table_name to lars
2> go

To Create database

C:\> osql –E –S localhost\myinstance

1> use master
2:> go
1> CREATE DATABASE Books
2> go
The CREATE DATABASE process is allocating 0.63 MB on disk ’Books’.
The CREATE DATABASE process is allocating 0.49 MB on disk ’Books_log’.

Other Utilities:

Server Configuration Tool: C:\> svrnetcn.exe

Client Configuration Tool: C:\> cliconfg.exe

For further information:

http://www.codeproject.com/database/ConfigureMSDE.asp

VB to VB.NET and then to C# conversion

There is no 100% automatic conversion tool to let you convert the old VB code to VB.NET/C# with no effort. The tools can help you to convert the syntactic parts and the basic parts, while leaving the more sophisticate part to you and list them in a report as your ToDo list.

To convert from VB to VB.NET, Microsoft VS.NET has a conversion tool for you. When you open a project, choose convert, and choose Visual Basic.NET Upgrade Wizard, you will be asked to pick a VB project file (.VBP) to convert to a "unfinished" VB.Net project.

From my experience, the conversion are pretty good, except for the Screen drawing part. In VB, you can draw a line, a circle, or paint a circle on a PictureBox pic (or a form Form1) by doing things like below:

Me.DrawWidth = 3
pic.FillColor = vbBlue
pic.FillStyle = vbDownwardDiagonal
pic.Circle (ScaleWidth / 2, ScaleHeight / 2), _
pic.ScaleWidth * 0.45, vbRed, , , _
pic.ScaleHeight / pic.ScaleWidth

But in VB.NET, you need 3-4 objects to accomplish this. You will need to have a Graphics object gr as the place to draw; a Pen object ellipse_pen for drawing lines; and a Brush object ellipse_brush for painting colors. If you want to write some text on the form/picturebox, you will have to have a Font object too.

Dim gr As Graphics = Me.CreateGraphics()
Dim ellipse_brush As New HatchBrush( _
HatchStyle.BackwardDiagonal, _
Color.Blue, Me.BackColor)
gr.FillEllipse(ellipse_brush, 0, 0, _
Me.ClientSize.Width, Me.ClientSize.Height)
Dim ellipse_pen As New Pen(Color.Red, 5)
gr.DrawEllipse(ellipse_pen, 0, 0, _
Me.ClientSize.Width, Me.ClientSize.Height)

Not only that, in VB, you can draw under Form_Load event, and the system will take care of re-paint for you. But in VB.NET, all the drawing/painting part has to be in Paint Event Handler. Otherwise, the run time environment will not repaint for you like in VB. This can be a big confusion for most of the new VB.NET Developers.

Once you have a VB.NET program up and running, you are already in .NET domain. If you need to convert it to C#, there is another web based tool which can help:

http://www.carlosag.net/Tools/CodeTranslator/Default.aspx

Run CDONTS on Windows XP and Windows 2003

CDONTS provides ASP developers easy way to send e-mails from the ASP web pages. While convenient, CDONT is only available on Windows NT and Windows 2000. The DLL to succeed CDONT is called CDOSYS, which resides on Window 2000, XP and 2003. Unfortunately, CDOSYS API is not compatible with CDONTS. The programmer who used to program CDONTS will need to learn how to program CDOSYS.

If you just want to use CDONT API on Windows XP/2003, you can copy cdonts.dll from c:\winnt\system32 of the Windows 2000 server, to c:\windows\system32 of the XP/2003 machine, and register it by running regsvr32. That will make your program. which is using CDONT, running without any change.

Use Win2000 Server CDOSYS Event Sink to Process e-Mails: C# and VB.NET ways

CDOSYS is COM based. It may become part of the .NET Framework in the future version of Windows. At this point, if we want to develop CDOSYS Event Sink by using C# or VB.NET, we will need to add .NET Wrappers to the CDOSYS COM object, to let the .NET world access CDOSYS.

Before we start to do this, we will need to download some code from Microsoft. Please click here to download.

Once we download the code and extracted them into, say, c:\ManagedSinkWP, we can start to do the followings:

To build the interop

From a command prompt, run \Program Files\Microsoft Visual Studio .NET\Common7\Tools\vsvars32.bat.
Run nmake.exe from the directory of the interop (\ManagedSinksWP\Interop).
To build the wrappers

Copy the interop DLL (Microsoft.Exchange.Transport.EventInterop.dll) to the wrappers directory (\ManagedSinksWP\Wrappers).
In the same environment as the interop, run the following from the wrappers directory:
Note The following code has a carriage return inserted for readability. When implementing this code, do not include the carriage return.

csc /t:library /out:Microsoft.Exchange.Transport.EventWrappers.dll /r:Microsoft.Exchange.Transport.EventInterop.dll *.cs /unsafe
To write the event sink

Click here to get the working sample project I provided.

Now, assume we have already built the COM called ManagedSinks.ShieldsUp from my sample code , then you can do (from command line):

cscript smtpreg.vbs /add 1 OnInboundCommand "Sample managed sink" ManagedSinks.ShieldsUp EHLO
This will send a reject message to the sender if EHLO command is received.
You can test this by doing (from command line):
telnet localhost 25
EHLO
To uninstall the Event Sink, you can do:
cscript smtpreg.vbs /remove 1 OnInboundCommand "Sample managed sink"
For detailed information, please go to:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsmtps/html/writingmngsinks.asp?frame=true#writingmngsinks_topic2

DBCC CheckTable Syntax and Examples

Syntax
DBCC CHECKTABLE
( ’table_name’ | ’view_name’
[ , NOINDEX
| index_id
| { REPAIR_ALLOW_DATA_LOSS
| REPAIR_FAST
| REPAIR_REBUILD }
]
) [ WITH { [ ALL_ERRORMSGS | NO_INFOMSGS ]
[ , [ TABLOCK ] ]
[ , [ ESTIMATEONLY ] ]
[ , [ PHYSICAL_ONLY ] ]
}
]


Examples
A. Check a specific table
This example checks the data page integrity of the authors table.

DBCC CHECKTABLE (’authors’) GO
B. Check the table without checking nonclustered indexes
This example checks the data page integrity of the authors table without checking nonclustered indexes.

DBCC CHECKTABLE (’authors’) WITH PHYSICAL_ONLY GO
C. Check a specific index
This example checks a specific index, obtained by accessing sysindexes.

USE pubs DECLARE @indid int SELECT @indid = indid FROM sysindexes WHERE id = OBJECT_ID(’authors’) AND name = ’aunmind’ DBCC CHECKTABLE (’authors’, @indid) GO

Change Collation of MS SQL Server 2000

Collation is used to define the sort sequence and is specific for char/varchar/text column types only. A Database Server has its default collation, and when the database is newly created, it has its default collation inherited from the server. Similarly, when a text related field (text/varchar/char) field is created, it has the default collation inherited from the database.

To change the default database collation, do the following in the query analyzer:

Alter Database myDatabase Collate SQL_LATIN1_CP1_CI_AS

Please note that it just changes the default database collation for the fields you are going to create in the future, it does not change the existing collation in each text related field. To change the collation of a certain column, you can just pick up the collation you want from the design view of the table, or use the following SQL statement in Query Analyzer:

ALTER TABLE MyTable ALTER COLUMN CharCol
varchar(10)COLLATE Latin1_General_CI_AS NOT NULL