|
 Tuesday, April 29, 2008

3.5 Beta Exams Not Available In Phoenix

I meant to post this a couple of weeks ago but unfortunately I didn't get the chance to. Anyway... I was a little bummed out to find that the ASP.NET 3.5 Beta Exams were being offered to MCP holders until late April (I believe it was up until yesterday), but unfortunately NOT A SINGLE EXAM SITE IN PHOENIX can house this Beta Exam.

I spoke to a ProMetric rep who stated that the exam sites such as Interface, ValorIT, and even ProMetric's own testing facility were not a high enough site rating. Apparently they need a level 4 site rating to hold these beta exams, these sites only obtain a level 3 or less rating.

Upon further inspection, the closest testing facility that would allow me to take this Beta exam was at Yavapai College in Prescott, AZ (see map below). Look how far away that is:

Map image

<-- Here's where it is in relation to Phoenix.

The part that baffles me is how Phoenix can be in the top 5 largest cities in the USA (I can't find my reference for when we passed Philly, but I heard we did somewhere - If I'm wrong, oh well) and we don't have a testing facility that allows us to take Beta Exams. Don't get me wrong, I'm happy that we even have facilities that do this, but I'm amazed that a city of this size does NOT have a level 4 facility in the metro area. Literally, the metro area almost spans nearly ~100 miles in diameter.

Anyway, I'll hit up the exams when they're released. No big deal. :) I was just amazed that we didn't have the capacity to hold these exams.

Here's the links for the .NET 3.5 Study Guides:

ASP.NET Application Development (70-562)

ADO.NET Application Development (70-561)

#    Comments [0] |

TechEd Developer 2008 & Party With Palermo

If you're going to be at TechEd 2008, let me know as I'll be there.

 

Also if you're going to Palermo's event, let me know as well because I'll be there as well - "im up in yer partee - rubbin' dem elbows".

Party with Palermo See ya there.

(Click the image for more info)

#    Comments [0] |

Simple Download Counter HttpHandler

[Full code sample provided at the bottom of this post]

I use A-Drive from time to time to host small files that I want users to download for various personal projects (mainly to help conceptualize the market for entrepreneur start-up ideas). Lately I needed to use it for a project where I needed to track the number of downloads a particular file had. Normally this is something I could code up real quick, but I literally wanted to get this up and running within minutes. I'm running a site using the Graffiti CMS so I'm doing this to get some quick feedback cycles in regards to if my "product" I'm offering is worth the time to invest a full implementation. (MicroTesting).

I had uploaded the file, and then accessed it from three different networks to realize that the incremental counter was NOT incrementing. WTF?! I messed around with it some more... I deleted my cookies (thinking that maybe they wrote a cookie to verify I downloaded it so it didn't double dip in the count for my multiple downloads - aka: Unique Downloads). I contacted support, but it was the weekend so I didn't expect a reply.

Update

I received a reply from the company in regards to their download counter not working:

Dear Donn,
This is currently a bug in our system that we will resolve very soon.
Thanks,
-ADrive Support Team

So.. it was now time to create a simple HttpHandler to count downloads for me.

How To

Note: This is a very very very simple example of how you can count downloads (and no, it does capture unique user downloads). This can be altered very easily to do this.

My Simple Requirements.

- Persistence Medium For The Counter (XML)

- Increment the counter

- Allow the user to download the file

The best place to implement this functionality is inside of an HttpHandler by using the IHttpHandler Interface. The reasons are simple: I don't need a UI, I don't need complex business logic (remember - this is a super quick implementation to fix a simple problem).

Code

1 using System; 2 using System.IO; 3 using System.Text; 4 using System.Web; 5 using System.Xml; 6 7 /// <summary> 8 /// Increments a counter and forces a download to the user. 9 /// </summary> 10 public class DownloadHandler : IHttpHandler 11 { 12 private readonly string COUNTER_REPOSITORY = "App_Data/ExampleCounter.xml"; 13 private readonly string MY_FILE = "App_Data/Example.pdf"; 14 private readonly string SAMPLE_DOWNLOAD_COUNT_ELEMENT = "SampleDownloadCount"; 15 16 #region IHttpHandler Members 17 18 ///<summary> 19 ///Enables processing of HTTP Web requests 20 /// by a custom HttpHandler that implements 21 /// the <see cref="T:System.Web.IHttpHandler"></see> interface. 22 ///</summary> 23 ///<param name="context">An 24 /// <see cref="T:System.Web.HttpContext"></see> object that provides 25 /// references to the intrinsic server objects (for example, Request, 26 /// Response, Session, and Server) used to service HTTP requests. </param> 27 public void ProcessRequest(HttpContext context) 28 { 29 IncrementCounter(context); 30 SendFileToUser(context); 31 } 32 33 ///<summary> 34 ///Gets a value indicating whether another request can use 35 /// the <see cref="T:System.Web.IHttpHandler"></see> instance. 36 ///</summary> 37 /// 38 ///<returns> 39 ///true if the <see cref="T:System.Web.IHttpHandler"></see> instance 40 /// is reusable; otherwise, false. 41 ///</returns> 42 /// 43 public bool IsReusable 44 { 45 get { return false; } 46 } 47 48 #endregion 49 50 /// <summary> 51 /// Sends the file to the user. 52 /// </summary> 53 /// <param name="context">The <see cref="HttpContext"/> that 54 /// contains the request.</param> 55 private void SendFileToUser(HttpContext context) 56 { 57 // Send the file to the user. 58 FileInfo fileInfo = new FileInfo(context.Server.MapPath(MY_FILE)); 59 60 context.Response.ContentType = "application/pdf"; 61 context.Response.AddHeader( 62 "Content-Disposition", 63 "attachment; filename=" + fileInfo.Name); 64 context.Response.WriteFile(fileInfo.FullName); 65 context.Response.End(); 66 } 67 68 /// <summary> 69 /// Increments the counter. 70 /// </summary> 71 /// <param name="context">The <see cref="HttpContext"/> that contains t 72 /// he current request</param> 73 private void IncrementCounter(HttpContext context) 74 { 75 int value = int.MinValue; 76 string fileName = context.Server.MapPath(COUNTER_REPOSITORY); 77 using (XmlTextReader reader = new XmlTextReader(fileName)) 78 { 79 reader.ReadStartElement(SAMPLE_DOWNLOAD_COUNT_ELEMENT); 80 value = Convert.ToInt32(reader.ReadString()); 81 } 82 value++; 83 using (XmlTextWriter writer = new XmlTextWriter(fileName, Encoding.ASCII)) 84 { 85 writer.WriteElementString( 86 SAMPLE_DOWNLOAD_COUNT_ELEMENT, 87 value.ToString()); 88 } 89 } 90 91 92 93 94 } 95

How It Works

We have to add a line to the web.config to tell ASP.NET about the Handler and to only listen to the "GET" Http Requests.

1 <httpHandlers> 2 <add path="Download.ashx" verb="GET" type="DownloadHandler"/> 3 </httpHandlers>

When the app is fired up we first access the request, then open an XML file that looks like this:

<SampleDownloadCount>8</SampleDownloadCount>

The file is parsed, the value is incremented and then we write the value back to the file. I'm almost positive there is a more elegant solution to this but remember, I wanted this to get done FAST, I'm not looking for pretty in this implementation. Technically, this is throw away code if my test works (my 1 week MicroTesting phase). Then I go into full development.

After the counter is incremented we send the file to the end user through the response.

Note: The file "Example.pdf" is hard coded in this example but you could easily set this up so that the file represented an  identifier through the query string (download.ashx?DownloadId=1) where 1 might equate to "Example1.pdf" and 2 might equate to "Example2.pdf". Think about it awhile and run with it. Remember, this is an extremely simple example for how to count downloads.

Conclusion

It's very simple to implement this counter in a regular ASP.NET web site. Although its not production quality code, it will work for simple testing and monitoring of file downloads and should supply you with a starting point to move forward with download counters.

In a future post I will show you how you can use this inside of the Graffiti CMS to help track your download counts.

Downloads

You can download a sample example site here: FooTheory.DownloadHandler.Example.zip (7.39 KB)

#    Comments [0] |
 Monday, April 07, 2008

WTF's Per Minute

I saw this the other day on digg and I had to repost it simply for the fact that I need to have a copy of my own for reference.

This is absolutely classic and true as it gets. I nearly broke down laughing with a side-ache when I saw this - it's absolute hilarity in its best form.

 

wtfm

#    Comments [0] |
 Tuesday, April 01, 2008

NUnit 2.4.7 and the RowTest Attribute with Example

This last Sunday NUnit 2.4.7 was released. As usual, great bug fixes were implemented by the team for this release, but I think the key thing to note about this release is that this is the first release of NUnit to include an externally developed Add-In [Charlie Poole, altdotnet mailing list - 20080331].

The RowTest Add-In

NUnit now includes the RowTest extension, written by Andreas Schlapsi, in it's extension assemblies. This extension allows you to write test methods that take arguments and to provide multiple sets of argument values using the RowAttribute. To use RowTest, your test must reference the nunit.framework.extensions assembly. [NUnit 2.4.7 Release Notes]

This type of functionality is not something new to the community by any means. MBUnit developed this technology AGES ago- and honestly I think this one feature is the sole reason MANY Developers use MBUnit.

Ok, So what is the RowTest?

The RowTest Attribute allows you to specify different sets of data as declarative statements at the top of your unit test.

Example: Lets say we had to write 3 tests for 3 different sets of data. Here's a matrix of what we might need to test:

Specification Parameter 1 Parameter 2 Expected Result
Test Should Fail When Values are Null null null InvalidOperationException
Test Should Pass with two values of 5 5 5 7.07...<remainder omitted>
Test Should Pass With two ZEROS 0 0 0

In a previous release of NUnit we would have to write three unit tests for this because we can only assert one value at a time. Over time this causes duplication of code and you'll find that you have tons of test that nearly do the same thing, only with different values.

Enter The RowTestAttribute

With the RowTestAttribute (located in the NUnit.Framework.Extensions.dll) you can test rows of data with only one unit test. NUnit will run the unit test each time for each specified row of data.

Example (actual code files are available at the bottom of this post):

image

Which Tests this code:

image

Breaking It Down...

The Unit Tests in the first screen shot show two unit tests.

  1. The first one utilizes the RowTestAttribute
  2. The second one is how we normally test using NUnit.

Also note how we're using the new(er) Constraint Model for Unit testing. The unit test in the first set allow me to test via a "per row" basis. Utilizing the "RowTestAttribute" I can assign a set of data to the row and run that rows data via the values passed in. I can also expect exceptions, provide descriptions and messages - just like you would normally do in a classic NUnit test.

The second test is a basic example of what a normal Unit Test would look like. If we DID NOT use the RowTestAttribute we would have to write four unit tests to obtain the same functionality.

Setting It Up

The only thing you'll need to do to utilize the RowTestAttribute is to reference the nunit.framework.extensions.dll as well as the nunit.framework.dll. See below:

image

 

My Only Complaint

The only real complaint that I that I have right now is that ReSharper does pick up the "RowTest" attribute for unit tests, therefore it does not run the unit test. See the screen shot below:

image

This isn't a NUnit thing, its a ReSharper thing. If anyone knows how to get ReSharper to "see" RowTest as a valid Test, please let me know. Because the only way I can get this to work is to run it through the NUnit GUI or command line. (No I don't have TestDriven.NET installed either - but I'm assuming that TDD.NET would see this as a "valid" test).

 

Download Files (you will need the NUnit 2.4.7 Binaries to get this to run)

FooTheory.NUnit247.Example.zip 

Note: This is a VS2008 project. If you're running VS2005, just copy the .cs files as they are still valid 2005 format files and put them into a new VS2005 project and you'll be good to go. :)

#    Comments [3] |