Currently showing entries with the tag: testing
|
page 1 of 1
|
HTTP Status Code 307 - Temporary Redirect
August 19, 2007 • 9:41AM • permalink
I'm sure that many of you haven't gotten past the title before saying, "No, a HTTP Status Code of 302 is the Temporary Redirect." I'd like to briefly explain the difference between the two and show you how you can benefit from a 307 redirect. Please also note, that this is a temporary redirect and should probably be avoided in most production situations. You will see one case in particular below where this can be useful.
In .NET, the standard way to redirect between pages is to use the Response.Redirect() method. This implicitly flushes the Response buffer and instead of sending back HTML (with a status code 200 OK), it sends the user a 302 Found code, meaning the requested page was found, but under a different URI. The server also sends back the new URI in the Location header that should be subsequently retrieved by the client.
This works in most cases, except for one minor problem: the case when you're trying to POST data to the server. There are many ways around this problem (including changing it to a GET/QueryString combo), but if a POST is necessary a 307 Temporary Redirect status code will indicate to the browser that the POST method should be retained.
This can be very valuable when developing on a machine with Windows XP Pro (and hence IIS 5.1 which doesn't allow you to identify web sites with host headers.) Under IIS, I setup multiple projects with the directory schema C:\Inetpub\wwwroot\ProjectName\. In my code, I prefix all links with an Web.config driven value that indicates the subdirectory off the root that the project resides in. This way, I can use the value /ProjectName/ in dev and / in production and the links will work in both environments. I don't like to pass these values around though, so when I recently wrote a small Flash application specifically for one website, I wanted to hardcode the SWF to POST to 'http://www.domainname.com/'. It seemed like a lot of work at first, but with a 307 redirect, it was simple!
If the Flash file was hardcoded to POST to 'http://www.domainname.com/PageName.aspx', you just create a file in the localhost root directory (C:\Inetpub\wwwroot\ in my example) called PageName.aspx and run the following on Page_Load():
Response.StatusCode = 307;
Response.RedirectLocation = "/ProjectName/PageName.aspx";
This will allow proper testing in IIS 5.1 and will redirect to the correct page with a POST method and all associated form data.
One final note as to why this should only be used for testing. Part of the definition of a 307 status code directs that browsers should prompt the user of the redirect and allow them to replicate the action (for older browsers). Firefox, in particular, is one browser that fully supports the standard and prompts the user, asking if they want to allow the form data to be sent via a POST. Since this could lead to a very poor user experience, I would recommend limiting use of the 307 status code to development and testing environments only.
In .NET, the standard way to redirect between pages is to use the Response.Redirect() method. This implicitly flushes the Response buffer and instead of sending back HTML (with a status code 200 OK), it sends the user a 302 Found code, meaning the requested page was found, but under a different URI. The server also sends back the new URI in the Location header that should be subsequently retrieved by the client.
This works in most cases, except for one minor problem: the case when you're trying to POST data to the server. There are many ways around this problem (including changing it to a GET/QueryString combo), but if a POST is necessary a 307 Temporary Redirect status code will indicate to the browser that the POST method should be retained.
This can be very valuable when developing on a machine with Windows XP Pro (and hence IIS 5.1 which doesn't allow you to identify web sites with host headers.) Under IIS, I setup multiple projects with the directory schema C:\Inetpub\wwwroot\ProjectName\. In my code, I prefix all links with an Web.config driven value that indicates the subdirectory off the root that the project resides in. This way, I can use the value /ProjectName/ in dev and / in production and the links will work in both environments. I don't like to pass these values around though, so when I recently wrote a small Flash application specifically for one website, I wanted to hardcode the SWF to POST to 'http://www.domainname.com/'. It seemed like a lot of work at first, but with a 307 redirect, it was simple!
If the Flash file was hardcoded to POST to 'http://www.domainname.com/PageName.aspx', you just create a file in the localhost root directory (C:\Inetpub\wwwroot\ in my example) called PageName.aspx and run the following on Page_Load():
Response.StatusCode = 307;
Response.RedirectLocation = "/ProjectName/PageName.aspx";
This will allow proper testing in IIS 5.1 and will redirect to the correct page with a POST method and all associated form data.
One final note as to why this should only be used for testing. Part of the definition of a 307 status code directs that browsers should prompt the user of the redirect and allow them to replicate the action (for older browsers). Firefox, in particular, is one browser that fully supports the standard and prompts the user, asking if they want to allow the form data to be sent via a POST. Since this could lead to a very poor user experience, I would recommend limiting use of the 307 status code to development and testing environments only.
0 comments
Simple Speed Testing in .NET - System.Diagnostics.Stopwatch
August 18, 2007 • 6:48AM • permalink
One of the biggest problems with the .NET Framework is that so many new features are released with each major version that minor additions and features usually slip through the cracks. In my experience, very few classes have been overlooked during the transition from 1.1 to 2.0 as much as the Stopwatch class (System.Diagnostics.Stopwatch).
This is a replacement for what most people probably do to test two different blocks of code that perform the same action and compare the speed between them. The process usually goes something like: log the current time, run the test, take the difference between the current time and your logged time, rinse, repeat.
As an alternative, the Stopwatch class was built using low-level API calls, with less overhead than other .NET methods. If the hardware and Windows version of the computer support a high-resolution performance counter, it will use this counter instead of the standard PC clock.
Here is a simple example:
using System.Diagnostics;
Stopwatch sw = new Stopwatch();
string s1 = "";
string s2 = "";
string letters = "abcdefghijklmnopqrstuvwxyz";
int iterations = 50000;
sw.Start();
for (int i = 0; i < iterations; ++i)
s1 += letters[i % 26];
sw.Stop();
Response.Write("Test 1: " + sw.ElapsedMilliseconds + "ms");
sw.Reset();
sw.Start();
for (int i = 0; i < iterations; ++i)
string.Concat(s2, letters[i % 26]);
sw.Stop();
Response.Write(" | Test 2: " + sw.ElapsedMilliseconds + "ms");
As it mentions above, don't forget to Reset your Stopwatch between tests or your subsequent tests will have their times inflated (since otherwise the Stopwatch will continue incrementing from the point that it was stopped).
The Stopwatch has a few other useful methods and properties, such as IsRunning and IsHighResolution. You can view the MSDN description of the Stopwatch class here.
In case you're curious, the string.Concat function outperformed the += operator by over 550 times in repeated tests on my machine. This is due to the fact that the += creates multiple (immutable) string objects, while the string.Concat uses a buffer technique to avoid that. More to come on this topic in a future post.
This is a replacement for what most people probably do to test two different blocks of code that perform the same action and compare the speed between them. The process usually goes something like: log the current time, run the test, take the difference between the current time and your logged time, rinse, repeat.
As an alternative, the Stopwatch class was built using low-level API calls, with less overhead than other .NET methods. If the hardware and Windows version of the computer support a high-resolution performance counter, it will use this counter instead of the standard PC clock.
Here is a simple example:
using System.Diagnostics;
//Note: make sure you have this at the top of the class
Stopwatch sw = new Stopwatch();
//do any preliminary processing here, to not inflate your test results
string s1 = "";
string s2 = "";
string letters = "abcdefghijklmnopqrstuvwxyz";
int iterations = 50000;
//TEST 1
sw.Start();
for (int i = 0; i < iterations; ++i)
s1 += letters[i % 26];
sw.Stop();
//END - TEST 1
Response.Write("Test 1: " + sw.ElapsedMilliseconds + "ms");
//note that you can also use sw.ElapsedTicks
sw.Reset();
//Don't forget to reset the Stopwatch before your second test!!!
//TEST 2
sw.Start();
for (int i = 0; i < iterations; ++i)
string.Concat(s2, letters[i % 26]);
sw.Stop();
//END - TEST 2
Response.Write(" | Test 2: " + sw.ElapsedMilliseconds + "ms");
As it mentions above, don't forget to Reset your Stopwatch between tests or your subsequent tests will have their times inflated (since otherwise the Stopwatch will continue incrementing from the point that it was stopped).
The Stopwatch has a few other useful methods and properties, such as IsRunning and IsHighResolution. You can view the MSDN description of the Stopwatch class here.
In case you're curious, the string.Concat function outperformed the += operator by over 550 times in repeated tests on my machine. This is due to the fact that the += creates multiple (immutable) string objects, while the string.Concat uses a buffer technique to avoid that. More to come on this topic in a future post.
Repeating a Batch in SQL Server 2005
August 08, 2007 • 4:56PM • permalink
I haven't found this feature documented anywhere, but I picked it up from one of Itzik Ben-Gan's articles.
Normally, you use the keyword GO when you need to force the previous batch of code to immediately execute, such as when using DDL or CTEs, like so:
CREATE TABLE [dbo].[my_table]
(
id INT
)
GO
While not useful in the case above, you can repeat a batch by placing an integer value immediately after the GO statement. This trick is very helpful when populating a table with random data or when doing repeated testing. So, for example, if we want to fill the above table with 1,000,000 rows of random integers, we can easily do it!
INSERT INTO [dbo].[my_table]
(id)
VALUES
(FLOOR(RAND() * 10000))
GO 1000000
Normally, you use the keyword GO when you need to force the previous batch of code to immediately execute, such as when using DDL or CTEs, like so:
CREATE TABLE [dbo].[my_table]
(
id INT
)
GO
While not useful in the case above, you can repeat a batch by placing an integer value immediately after the GO statement. This trick is very helpful when populating a table with random data or when doing repeated testing. So, for example, if we want to fill the above table with 1,000,000 rows of random integers, we can easily do it!
INSERT INTO [dbo].[my_table]
(id)
VALUES
(FLOOR(RAND() * 10000))
GO 1000000
|
page 1 of 1
|