Monday, April 4, 2005

Unit Testing the Data Access Layer

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/unit_testing_the_data_access_layer.htm]

I had the opportunity to write an article for 4guysfromrolla - "Unit Testing the Data Access Layer".

"Unit testing is becoming very popular among .NET projects, but unit testing the Data Access Layer (DAL) still remains a common obstacle. The problem stems from the very nature of databases: they are slow, common, persistent, external, and relational. This conflicts the nature of unit tests, which should be quick, independent, and repeatable..."

You can read the entire article on the 4GFR website at:

http://aspnet.4guysfromrolla.com/articles/040605-1.aspx

Sunday, April 3, 2005

Resolving Http 500 Server Errors in ASP.Net and IIS 5.1

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/resolving_http_500_server_errors_in_aspnet_and_iis_51.htm]

Every developer likes to take certain things for granted - like ASP.Net being configured correctly with IIS. However sometimes there will just be something non-obvious that is preventing ASP.Net pages from being served, returning an Http 500 error instead. The frustrating thing is that these are often caused by system configuration issues that most developers should never need to worry about. Below I offer some advice intended for IIS 5.1 on a local dev machine that resolves some of these errors. The problem is most likely:

  1. IIS or ASP.Net simply not installed correctly
  2. Security configuration

0. The Basics

First, try the classic: reboot your machine.

If that doesn't work, then turn off friendly errors in IE (tools > options > turn of friendly errors). This will give you a more helpful message like "Logon failure: user not allowed to log on to this computer." instead of just "500 Server error".

1. Check that IIS works

Be aware of the difference between ASP.Net and IIS. ASP may be installed fine, but IIS may be messed up. Some general tips:

  • See if you can view http://localhost/iishelp
  • Try viewing an HTML page through IIS. This totally bypasses any ASP.Net issues.

If you can't view IIS, then perhaps IIS is disabled or turned off.

2. Other Web Servers interfering with IIS

If this is the first time you installed IIS, perhaps there is another webserver running on your machine that is interfering with it (or if you disabled IIS and installed another Web Server). For example sometimes Java developers have another server using port 80 that blocks IIS. Try turning this other server off.

3. Uninstall and reinstall IIS and ASP.Net

Perhaps uninstalling and reinstalling will fix it.

  • Restart IIS by typing iisreset at the command line.
  • Reinstall ASP.Net by typing "aspnet_regiis.exe -i" at the command line.

If that doesn't work, you can uninstall IIS and ASP.Net, rename the inetpub directory to effectively delete it (while still saving your files), and then reinstall IIS and ASP.Net. This may reset user account systems.

4. Set ASP.Net security permissions

Make sure that the ASP.NET user has rights on Inetpub. Add the ASPNET user to INETPUB folder's users (Security tab in Properties) and granted it full control.

5. Check the Local security policy

In Admin Tools > Local Security Settings > Local Policies > Security Options > Audit Shut down system immediantly if unable to log secuiryt aufits --> should be disabled.

6. Check the Registry

In the registry editor (type regedit at the command line), check HKEY_LOCAL_MACHINE\SYSTEM\CurrentControLSet\CONTROL\LSA\CrashOnAuditFail

Set default = "0" (should not be "value not set")

7. Check the Machine.config for security settings

As a last resort, change machine.config,probably located in a directory like: C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG\machine.config

Look for  the xml tag "

Note that this is highly un-secure, but may be useful for letting you continue development while your IT staff investigates issues further.

 

Conclusion

I've had the misfortune of needing to fix this on many laptops now, and these hard-learned-tips have helped me out.

Wednesday, March 23, 2005

JavaScript URL encoding with Apostrophe

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/javascript_url_encoding_with_apostrophe.htm]

In a previous post I discussed using HttpUtility.UrlEncode to encode querystrings. While this is a great start, we can extend our encoding abilities using JavaScript's escape and unescape methods.

Sometime you'll need to encode at the client side, such as passing data to and from a pop-up window using querystrings (solely a client activity). While escape is very similar to HttpUtility.UrlEncode, there are some slight differences. Escape will encode both the apostrophe (%27) and space (%20 instead of '+').

The problem is that sometimes the security filter on the Web Server won't even allow the escaped chars. They won't allow apostrophe, but they won't allow %27 either. An easy way to test the allowed URL characters on a development site is to just append a dummy querystring, such as www.mySite.com?url=. Depending on the security system installed, you may get an error like "Inline Html scripts are not allowed in URLS for security purposes."

One solution is to take advantage of the safe '*' character. You could first encode the string, and then replace all '%' with '*'. This would give you the safe sequence %*27 instead of  ' or %27. We could then synchronize our server side encoding functions to match this pattern to allow us to freely pass encoded data between the client and server. Below is the HTML for a page to demonstrate this. It contains a encode and decode textbox and button. The buttons call their respective functions to encode/decode the data and store it in the other textbox.

DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
 <HTML
>
     <HEAD
>
         <title>Encodetitle
>
         <meta name="GENERATOR" Content
="Microsoft Visual Studio .NET 7.1">
         <meta name="CODE_LANGUAGE" Content
="C#">
         <meta name="vs_defaultClientScript" content
="JavaScript">
         <meta name="vs_targetSchema"
             content
="http://schemas.microsoft.com/intellisense/ie5">
         <script language
="javascript">
            

         script
>
     HEAD
>
     <body MS_POSITIONING
="FlowLayout">
         <form id="Form1" method="post" runat
="server">
             <P>Encoding TestP
>
             <P><INPUT id="TxtEncode" type="text" name="TxtEncode">
             <INPUT id="BtnEncode" title="Encode"
                     onclick
="DoEncode(document.Form1.TxtEncode.value)"
                     type="button" value="Encode" name="BtnEncode">
             <INPUT id="TxtResult" type="text" name
="TxtResult">
             <INPUT id="BtnDecode" onclick="DoDecode(document.Form1.TxtResult.value)"
                     type="button" value="Decode" name="BtnDecode">P
>
         form
>
     body
>
 HTML>

We can encode our data between client and server by combining JavaScript's escape and unescape methods, HttpUtility's UrlEncode and UrlDecode methods, and taking advantage that '*' isn't encoded in either.

Sunday, March 20, 2005

Method and Constructor Calling Order in OOP

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/method_and_constructor_calling_order_in_oop.htm]

I'm starting OOP in my C# class, and one of the issues to explain is the order that methods and constructors are called for inherited objects. People with a vague idea of inheritance know that one object (derived) can inherit another (base), where the derived object can reuse parts of the base. However, the behavior of the objects depends on what order the members are called in. Given a base and derived object, we want to know the code flow if the derived constructor or method is called.

For constructors, the base member is always called first. For methods, the question is really not-applicable because when there is a base and derived method both with the same name, the base member is only called if the the developer explicitly calls it with the base keyword. Let's flush this out.

Constructors

Given the classes:

public class MyBase
{
    public MyBase()
    {
        Console.WriteLine("Mybase()");
    }
}

public class MyDerived : MyBase
{
    public MyDerived()
    {
        Console.WriteLine("MyDerived()");
    }

    public MyDerived(string strName)
    {
        Console.WriteLine("MyDerived(string strName)");
    }

    public MyDerived(string strName, int intId) : this(strName)
    {
        Console.WriteLine("MyDerived(string strName, int intId)");
    }

}

Running MyDerived d = new MyDerived("name",5); will display:

Mybase()
MyDerived(string strName)
MyDerived(string strName, int intId)

As we walk through with the debugger, before executing any code, it will start at the overloaded MyDerived and walk down to the MyBase constructor. Once there, it executes the base constructor and walks back up to the calling point - executing MyDerived(string), and fthen finally MyDerived(string,int).

This makes sense - the base object should be instantiated first because we need to build the individual parts before building the whole.

Methods

Given that base class constructors are executed, many people subconsciously think that in cases where the base and derived methods have the same name, that base methods are executed too. However, this only occurs if the developer explicitly makes it that way, by using the "base" keyword (note that the derived can only call the immediate base, i.e. base.base would return an error):

public new void MyMethod(string strName)
{
    base.MyMethod(strName);
}

If "base.MyMethod(strName)" is omitted, then MyMethod will not be called - not with inheritance, polymorphism, or anything else. As we look at the keywords used in OOP, we see that this makes sense in each individual case:

Base Method: Virtual/AbstractDerived Method: Override/NewResult for calling Derived Method
virtualoverrideOnly current method is called.
abstractoverrideNothing to call (abstract has no implementation)
- (no keyword)newnew keyword hides base, therefore base won't be called by the very nature of what this keyword does.

 

Wednesday, March 16, 2005

Understanding HttpRequest URLs

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/understanding_httprequest_urls.htm]

Web applications often need to reference absolute paths, such as to retrieve images or Xml files. Fortunately, ASP.Net provides many ways to do this using the HttpRequest class. In code-behind pages this can be referenced as a property of the page like:

Page.Request.PhysicalApplicationPath()

For pages that aren't code-behinds, you can reference it through the current HttpContext like:

System.Web.HttpContext.Current.Request.PhysicalApplicationPath()

Given the following scenario, the table below shows the values for different types of paths.

  • ASP.Net application "Learning_VB", which resides on localhost (located at C:\Inetpub\wwwroot).
  • An aspx page, urltest, which is in the url/subfolder folder of the application
  • A querystring "id=5&name=Tim"

Path TypeValue
Page.Request.ApplicationPath/Learning_VB
Page.Request.CurrentExecutionFilePath/learning_VB/url/subfolder/urltest.aspx
Page.Request.FilePath/learning_VB/url/subfolder/urltest.aspx
Page.Request.Path/learning_VB/url/subfolder/urltest.aspx
Page.Request.PhysicalApplicationPathC:\Inetpub\wwwroot\Learning_VB\
Page.Request.PhysicalPathC:\Inetpub\wwwroot\Learning_VB\url\subfolder\urltest.aspx
Page.Request.QueryString.ToString()id=5&name=Tim
Page.Request.RawUrl/learning_VB/url/subfolder/urltest.aspx?id=5&name=Tim
Page.Request.Url.ToString()http://localhost/learning_VB/url/subfolder/urltest.aspx?id=5&name=Tim
Page.Request.Url.AbsolutePath /learning_VB/url/subfolder/urltest.aspx
Page.Request.Url.AbsoluteUrihttp://localhost/learning_VB/url/subfolder/urltest.aspx?id=5&name=Tim
Page.Request.Url.LocalPath /learning_VB/url/subfolder/urltest.aspx
Page.Request.Url.PathAndQuery/learning_VB/url/subfolder/urltest.aspx?id=5&name=Tim

The different types of paths have several differentiators:

  • Is it physical or virtual (note that web addresses use '/', and physical use '\') ?
  • Does it include the querystring?
  • Does it include the the full path or just start at the project folder Learning_VB)?

You can make your own version of this chart by simply creating a table on a WebForm, and then writing out the Path Type to the appropriate cell like so (note the code below is in VB, not C#):


    Private Sub Page_Load(ByVal sender As System.Object,
    ByVal e As System.EventArgs) Handles MyBase.Load

        Me.Label1.Text = Page.Request.ApplicationPath
        Me.Label2.Text = Page.Request.CurrentExecutionFilePath
        Me.Label3.Text = Page.Request.FilePath
        Me.Label4.Text = Page.Request.Path
        Me.Label5.Text = Page.Request.PhysicalApplicationPath
        Me.Label6.Text = Page.Request.PhysicalPath
        Me.Label7.Text = Page.Request.QueryString.ToString()
        Me.Label8.Text = Page.Request.RawUrl
        Me.Label9.Text = Page.Request.Url.ToString()
        Me.Label10.Text = Page.Request.Url.AbsolutePath
        Me.Label11.Text = Page.Request.Url.AbsoluteUri
        Me.Label12.Text = Page.Request.Url.LocalPath
        Me.Label13.Text = Page.Request.Url.PathAndQuery

    End Sub

I've found this a very useful chart for sorting out the different path types.

Monday, March 14, 2005

Three things you should know about DOS

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/three_things_you_should_know_about_dos.htm]

Many developers never bothered to learn much about DOS because of the widespread availability of GUI applications, like Windows Explorer. However DOS is still useful in many cases, and essential to automate almost anything. Therefore it's worth knowing a couple basics beyond just making directories and copying files.

The Call Statement

As you break a big task into smaller ones, you will need to have one script call another. However DOS scripts effectively each run in their own thread, and are not like normal .Net methods where the caller automatically waits for the called-method to finish. The question to ask is "Do you want the parent script to wait for the child script to finish?"

  • Yes: Then use the call keyword, like:  call Child.bat.
  • No: Then simply the script directly, like: Child.bat.

This can be vital when having a main host script call a bunch of sub-scripts in sequence.

Passing in Parameters

DOS Scripts can take in and pass out parameters. The two batch scripts below show how:

Parent.bat: Pass the parameters into the child by adding it after the script being called. This passes in two parameters, "Hello" and "World!"

ECHO This is the host page.
Call Child_2.bat "Hello" "World!"
ECHO done with parent

Child.bat: Access the parameters being passed in by %n, where n is the ordinal of the parameter (starting at 1), such as %1 or %2.

ECHO I am the child
ECHO %1 Some Phrase %2
pause
ECHO done with child

Using Environmental Variables

DOS supports variables. You can create your own or use existing environmental variables, such as: SystemDrive, TEMP, USERNAME, windir. Type set at the command line to see all the existing environmental variables. For example, the System Drive may vary from machine to machine. Therefore instead of hard-coding it as "C", use %SystemDrive%.

You can also create your own variable using the syntax: SET [variable=[string]]. For example, run the following DOS commands:

Set MyDosVar="Hello World"
Echo %MyDosVar%

The Echo will output "Hello World", which is the value of the variable. Variable Scope encompasses all child windows opened by the parent window.

Conclusion

If all you have is a hammer, everything looks like a nail. By being aware of what good-old DOS has to offer, it opens up your options when trying to automate tasks.

Sunday, March 13, 2005

Understanding the Number of Bytes in Integral Types

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/understanding_the_number_of_bytes_in_integral_types.htm]

As I prepare to teach about simple types in C#, one of the questions people will ask is "Why are there so many different integer types?"

C# supports nine integral types: sbyte, byte, short, ushort, int, uint, long, ulong, and char. Ignoring char, the table below shows the range and .Net Alias for each:

TypeAlias forAllowed Values

sbyte

System.SByte

Integer between –128 and 127.

byte

System.Byte

Integer between 0 and 255.

short

System.Int16

Integer between –32768 and 32767.

ushort

System.UInt16

Integer between 0 and 65535.

int

System.Int32

Integer between –2147483648 and 2147483647.

uint

System.UInt32

Integer between 0 and 4294967295.

long

System.Int64

Integer between – 9223372036854775808 and 9223372036854775807.

ulong

System.UInt64

Integer between 0 and 18446744073709551615.

The basic concept is that the larger the range of allowed values, the more memory the type requires to store that range. Range includes both magnitude as well as sign (+ or -). Therefore .Net provides different types to optimize for this. For example, no need to waste ulong when you only need to store the values 1 through 10.

Ultimately the types are based on binary storage. So storing the value 25 would really be stored as 11001, or: (1*2^4) + (1*2^3) + (0*2^2) + (0*2^1) + (1*2^0), or, more simply: 16 + 8 + 0 + 0 + 1. The following Excel spreadsheet demonstrates these calculations.

Notice that the range for unsigned integers start at 0. So byte (which has 8 bits) can store 2^8, or 256 values. This is spent covering 0 through 255. In order to make the type signed, or capable of storing negative values, there are two approaches:

  1. Use an extra bit to indicate the sign.
  2. Shift the entire range from 0 to some arbitrary negative number.

The second approach actually gives the larger range. For example, if sbyte used the first approach, it would use 1 bit for the sign, leaving only 7 bits for the magnitude. This would have a range of 0-127 (note: 2^7-1 = 127) in the positive direction, and 0-127 in the negative direction, for a total range of -127 to + 127. However, both the positive and negative directions cover 0, wasting a value. Therefore the datatype gets a larger range by simply offsetting the positive range: -128 to +127 instead of just -127 to + 127.

Given the power of today's computers, along with the simplicity of most applications, many developers can get away with just using the default int type (System.Int32) for all their integer needs. However it is still good to know what's going on behind the scenes because:

  • It is a common Computer Science principle and transcends merely the C# language.
  • You may work on an application where it does matter.
  • It will help you understand other applications that use these types.