|
 Wednesday, July 02, 2008

Virtual Earth - End of Life

This week Microsoft announced that their Virtual Earth product versions 3, 4 & 5 will be retired.

As part of our planned deprecation schedule for older versions of Virtual Earth, we will be permanently retiring Virtual Earth version 3, version 4, and version 5 in the coming months. If you are currently using one of these versions, please read this notification and the end-of-life schedule that applies to the version(s) of Virtual Earth you are using. Please note, this Virtual Earth version end-of-life plan only applies to Virtual Earth and does not affect the MapPoint Web Service.

Please note, this does NOT affect the Microsoft Map Point 4.5 Geocoding class that I wrote. This class will continue to do its job. :)

Related: Google Maps Geocoding Class

#    Comments [0] |
 Monday, June 09, 2008

I Took The ASP.NET 3.5 Beta Exam, and then the red pill

At Tech-Ed last week they offered the ASP.NET 3.5 Beta Exam. The beta exam is not available in Phoenix, so I decided to give it a whirl on Thursday. I didn't plan to take the test so I didn't have a lot of time to review (maybe 30 minutes of review) and I just dove in and took it.

Normally MS Exams have about ~40 questions and they take a couple of hours for me to complete. I was expecting the same from this one...

Nope. This exam had 70 questions. Wowza. I'm assuming the reason for this is one of these scenarios:

  • This is a beta exam and they need to weed out some questions
  • They have bumped up the number of questions in the exam

So how hard was it?

Well ... it's a little harder than the 2.0 version. A lot of it is repeated from 2.0, but this new beta exam threw me for a loop in a few areas.

The areas that threw me for a loop were:

  • WCF Integration Questions (I'm very well vested in WCF, but I just was not expecting it in this exam - there's a WCF exam for that!)
  • Deep AJAX Questions (Don't do much AJAX stuff, lets be honest... JavaScript is not my favorite language)
  • Miscellaneous Mobile Questions

The main thing about MS exams is that they are LONG and tricky. Sometimes you'll get asked a question and all four answers look right. LOOK VERY CLOSE. You'll see that maybe one word is spelled wrong, or the line's are swapped, etc. They will confuse you. But the main thing to do is be alert. The test will wear on you, its long. By the 2.5 hours in, you'll get tired of the test and you'll want to just hurry through it, don't. Just take your time.

 

So How Did I do?

Since its a beta exam, I won't know for about 2-3 weeks. They send your results in the mail. I feel like I passed, but we'll see when the results come in.

... and no, I didn't take any pills before or after... :) I'm just joshin' ya'll.

#    Comments [0] |
 Tuesday, June 03, 2008

Resources from Desert Code Camp

This past weekend I presented the topic "Intro to Dependency Injection and Inversion of Control" at the Phoenix Desert Code Camp. A big thank you goes out to everyone who attended. It was such a popular topic that it actually moved up to the largest room in the conference location, the Theater at UAT! Thanks again everyone!

At the bottom of this post are the resources from this presentation.

 

Resolution from Error During the Presentation

For those of you were present when I ran into an issue with this "DynamicMethod" error, I have figured out the issue. It's a bug in Unity. It looks like its been fixed and should be available in the next release.

image

I was able to work around this issue by moving the Dependency attribute into the Interface. I have updated the code in the download below to reflect this.

 

Presentation Resource Download

 

Full Solution Download (900K)

PowerPoint Presentation

You can also view the presentation online - located here.

#    Comments [0] |
 Sunday, May 25, 2008

Intro to Microsoft Unity - Dependency Injection Container

 

Note: A full solution is supplied at the bottom of this post if you would like to download it and run it.

A couple of days ago Matt wrote about the new Unity Application Block. The Unity MSDN article describes Unity as:

The Unity Application Block (Unity) is a lightweight, extensible dependency injection container. It facilitates building loosely coupled applications and provides developers with the following advantages:

  • Simplified object creation, especially for hierarchical object structures and dependencies
  • Abstraction of requirements; this allows developers to specify dependencies at run time or in configuration and simplify management of crosscutting concerns
  • Increased flexibility by deferring component configuration to the container
  • Service location capability; this allows clients to store or cache the container

Designing a software system architecture with loosely coupled components makes life easier in the long run. A few of the benefits of loose coupling are : maximizing testability, modularizing components, and increase the maintainability of the code.

This is a simple introduction into Unity that exemplifies the simplicity of the container setup. I will cover two options for type registration:

  1. Manual Method based type Registration
  2. Configuration file (XML Based) type Registration

 

The Example Application

The application that is included at the bottom of this post is visualized via the class diagram below. This simple application utilizes very simple implementations of the repository, mapper, domain model, data transfer object (DTO) and service layer patterns for example purposes.

The application follows a very simple flow as shown below:

image

 

The console application calls into the Service layer which calls into the repository to get the data which calls into the DB. A domain object is created from the Repository call, which is passed up to the service layer. The Service layer returns a DTO via the DTO Mapper to the parent caller (the console app) and then the console app displays the customer name via a write line call.

None of these layers have any inter-dependent dependencies coded inside of them. I'm using constructor injection to inject dependencies into the calling object.

Once unity is set up, it will find the dependencies and supply them to the program at runtime. Therefore, if I need a ICustomerRepository for the service layer to work properly, Unity will give the Service layer a CustomerRepository instance. Since CustomerRepository inherits from ICustomerRepository Unity is able to make this link (once you've set it up) and supply the proper instance.

Class Diagram

image

 

The Setup & Code

The easiest way to see HOW Unity works is to get into the code. My recommendation is to download the sample below, fire it up in Visual Studio and set some break points to see how the code is interacting. Seeing is believing!

Before Unity can supply your application types at runtime, you have to tell Unity WHAT you want it to supply and where to find it. This can be done multiple ways as described here. Today we will go over manual configuration inside of the console app, and xml configuration.

Manual Configuration

image

The manual configuration that I've utilized here utilizes the fluent interface of the container.

Explanation of code: Here we are telling Unity to register a type. We're saying "If someone requests ICustomerRepository, give them an instance of CustomerRepository. If someone requests ICustomerDTOMapper, then give them an instance of CustomerDTOMapper. ..." and so on.

 

 

Using the Container From Manual Configuration

After you've set up the types of objects the container should resolve, you can then ask the container for a instance of "ICustomerService" and then invoke a method call on it. At this very point in time Unity will give you the CustomerService, and then when the customer service needs a repository Unity will then give it a instance of CustomerRepository, etc. At this point in time, everything is mapped for you behind the scenes. The only thing you have to do is ask for the first object and Unity will walk the dependency graph and fill in the blanks for you (if as long as you've given Unity the proper types it needs).

Here's how to do this in the code:

image

 

 

 

XML Configuration

XML configuration utilizes an external XML file (app.config/web.config) to create its dependency graph. This allows for a lot more freedom in what you would like to do with your app. If you're not happy with a certain version of "ICustomerRepository" you can create a new one, drop the DLL in the bin folder and change this config file to point to the new one and you're done. No recompiling!

In this implementation I'm using the app.config file because this is a Console App for example purposes. The full schema for XML configuration can be found here on the MSDN.

To utilize the XML configuration you'll need to utilize a custom config section. You can do this by placing this code into your config section of your app.config file:

image

Next, you'll need to add the container and type definition as shown below (this is just a snippet, full code is included at the bottom of the post):

image

The container gets its types from the config file at runtime.

Each type is declared in the config file as the "type" of object to find and the "mapTo" defines which object to return when the "type" is requested.

The type definitions are declared as type, assembly.

 

 

 

 

 

 

Using the Container From XML Configuration

To force Unity to use the XML Configuration you have to perform few extra set up steps in the application code as shown below. Essentially you're telling Unity that it's configuration/mappings are stored in a config file. The config section configures the container for you, as shown below.

image

To have Unity resolve an instance, its the same as the manual configuration option above. Here is the same image from above that displays how to do this:

image

 

 

 

 

Conclusion

Overall, using Unity as quite simple for this example. The docs on MSDN were pretty good, however I didn't really like the examples that were contained with the download because they did not show you how to utilize XML configuration as I wanted to. It didn't take but a few minutes to figure out what I needed to do. I think Unity is a decent solution at this time. I plan to investigate further into the depths of Unity to see if it may possibly be an alternative for my favorite container tool, Windsor Container.

 

Download The Code For This Post

FooTheory.UnityExample.zip (~477K)

#    Comments [2] |
 Friday, May 23, 2008

TIP: Utilizing Fluent Syntax with the "Is" Keyword in Rhino Mocks and NUnit

Rhino Mocks and NUnit both have a "Is" keyword, both used for a fluent style of syntax. Unfortunately this causes testing problems when you need to use them together. The .NET compiler can only understand one "Is" keyword at a time. We can't use both unless we full qualify the second one.

Having said that, I've fully qualified the "Is" keyword for Rhino Mocks and NUnit before and I find it clunky and I feel its a code smell to me.

In the figure below an example of a fully qualified "Is" keyword for Rhino Mocks is declared.

1 [Test] 2 public void ExampleTest() 3 { 4 // ... items ommited for brevity 5 6 With.Mocks(mockery) 7 .Expecting(delegate 8 { 9 Expect.Call(databaseMock.GetStoredProcCommand(null)) 10 .IgnoreArguments() 11 .Constraints(Rhino.Mocks.Constraints.Is.NotNull()) 12 .Return(databaseCommandStub); 13 }) 14 .Verify(delegate 15 { 16 IQuery query = ExampleResultQuery.GetInsertResultQueryFrom(someparameter); 17 IDatabaseCommand command = query.PrepareCommandUsing(databaseMock); 18 Assert.That(command, Is.SameAs(databaseCommandStub)); 19 }); 20 }

On line 11, we can see the fully qualified name: Rhino.Mocks.Constraints.Is.NotNull() method called.

This, my friends, is a code smell (IMO).

 

How To Fix

The NUnit testing framework provides a "Iz" syntax helper that VB.NET developers use because "Is" in VB.NET is a keyword.

Since we're using .NET Managed code we can use the Iz keyword and it will achieve the same results as Is did. Therefore we can use the Is keyword in Rhino Mocks and we can use the Iz keyword in NUnit. This saves a lot of key strokes over the course of a day.

Final Example:

1 2 [Test] 3 public void ExampleTest() 4 { 5 // ... items ommited for brevity 6 7 With.Mocks(mockery) 8 .Expecting(delegate 9 { 10 Expect.Call(databaseMock.GetStoredProcCommand(null)) 11 .IgnoreArguments() 12 .Constraints(Is.NotNull()) 13 .Return(databaseCommandStub); 14 }) 15 .Verify(delegate 16 { 17 IQuery query = ExampleResultQuery.GetInsertResultQueryFrom(someparameter); 18 IDatabaseCommand command = query.PrepareCommandUsing(databaseMock); 19 Assert.That(command, Iz.SameAs(databaseCommandStub)); 20 }); 21 }

Please note: Line 12 has the normal "Is.NotNull()" call from Rhino Mocks, and Line 19 utilizes the Iz syntax helper from NUnit.

I find this much easier on the wrist. :)

#    Comments [1] |
 Sunday, May 11, 2008

Using iTextSharp To Watermark/Write Text To Existing PDF's

First off, yes, I know there are other tutorials on how to watermark PDF's with iTextSharp. Unfortunately none of them showed me exactly what I wanted to do - which is why I wrote this one.

Currently I'm involved with a project that utilizes PDF's as their main product - a legal document. When I arrived to this client they utilized iTextSharp to "watermark" their PDF's. I've been wanting to get my hands dirty with iTextSharp for awhile now. So I cracked open the code base one weekend to see how they were watermarking the PDF's. After poking around for about 2 minutes I saw how they were performing the "watermarking" and unfortunately it was not the best way to get the job done.

Problems with current implementation:

  • Images were used to write text.
    • Huh? An image with text was "underlain" into the PDF. The image had faded text that when inside of the finished product, looked watermarked. The image would say things similar to "Sample". The entire image looked like this:
    • image
  • The watermark orientation would always end up as Portrait.
    • This was because the watermark was an image and it was created for a portrait and it was coded to never detect the page orientation. If the page was landscape the watermarked page would look like this:
    • image
  • The watermarked text could never be changed.
    • Well, it could be, but it took a code change. The images were kept as resources in the library. So if they needed a new watermark, that meant a code change, testing and a redeploy.

 

So How Do We Fix This? What's the End Goal?

  • We want to be able to watermark the PDF document with Text, not images.
  • The code should detect page orientation.
  • We should be able to watermark the PDF with text that we provide at run time.
Current Document Expected Result
A Non watermarked document A watermarked document (red is below the text)
image image

The Solution

I'm very amazed with iTextSharp's ability to manipulate PDF's. From existing PDF's to new PDF's to content extraction, iTextSharp does it all. The best part about it is... ITS FREE (other than your development time, that is).

I've created a solution which I provide the download link for at the bottom of the post, but for now here's the code that does the dirty work:

 

FooTheoryPdf.cs

1 using System.IO; 2 using System.Text; 3 using iTextSharp.text; 4 using iTextSharp.text.pdf; 5 6 namespace FooTheory.iTextSharpLibrary 7 { 8 /// <summary> 9 /// Example PDF Class 10 /// </summary> 11 public class FooTheoryPdf 12 { 13 /// <summary> 14 /// Method that will utilize iTextSharp to write the <see cref="stringToWriteToPdf"/> to the 15 /// pdf on each page of the PDF. 16 /// </summary> 17 /// <param name="sourceFile">The PDf File</param> 18 /// <param name="stringToWriteToPdf">The text to write to the pdf</param> 19 /// <returns>The bytes of the newly updated PDF with <see cref="stringToWriteToPdf"/> in the pdf.</returns> 20 public static byte[] WriteToPdf(FileInfo sourceFile, string stringToWriteToPdf) 21 { 22 PdfReader reader = new PdfReader(sourceFile.FullName); 23 24 using (MemoryStream memoryStream = new MemoryStream()) 25 { 26 // 27 // PDFStamper is the class we use from iTextSharp to alter an existing PDF. 28 // 29 PdfStamper pdfStamper = new PdfStamper(reader, memoryStream); 30 31 for (int i = 1; i <= reader.NumberOfPages; i++) // Must start at 1 because 0 is not an actual page. 32 { 33 // 34 // If you ask for the page size with the method getPageSize(), you always get a 35 // Rectangle object without rotation (rot. 0 degrees)—in other words, the paper size 36 // without orientation. That’s fine if that’s what you’re expecting; but if you reuse 37 // the page, you need to know its orientation. You can ask for it separately with 38 // getPageRotation(), or you can use getPageSizeWithRotation(). - (Manning Java iText Book) 39 // 40 // 41 Rectangle pageSize = reader.GetPageSizeWithRotation(i); 42 43 // 44 // Gets the content ABOVE the PDF, Another option is GetUnderContent(...) 45 // which will place the text below the PDF content. 46 // 47 PdfContentByte pdfPageContents = pdfStamper.GetUnderContent(i); 48 pdfPageContents.BeginText(); // Start working with text. 49 50 // 51 // Create a font to work with 52 // 53 BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, Encoding.ASCII.EncodingName, false); 54 pdfPageContents.SetFontAndSize(baseFont, 40); // 40 point font 55 pdfPageContents.SetRGBColorFill(255, 0, 0); // Sets the color of the font, RED in this instance 56 57 58 // 59 // Angle of the text. This will give us the angle so we can angle the text diagonally 60 // from the bottom left corner to the top right corner through the use of simple trigonometry. 61 // 62 float textAngle = 63 (float) FooTheoryMath.GetHypotenuseAngleInDegreesFrom(pageSize.Height, pageSize.Width); 64 65 // 66 // Note: The x,y of the Pdf Matrix is from bottom left corner. 67 // This command tells iTextSharp to write the text at a certain location with a certain angle. 68 // Again, this will angle the text from bottom left corner to top right corner and it will 69 // place the text in the middle of the page. 70 // 71 pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, stringToWriteToPdf, 72 pageSize.Width/2, 73 pageSize.Height/2, 74 textAngle); 75 76 pdfPageContents.EndText(); // Done working with text 77 } 78 pdfStamper.FormFlattening = true; // enable this if you want the PDF flattened. 79 pdfStamper.Close(); // Always close the stamper or you'll have a 0 byte stream. 80 81 82 return memoryStream.ToArray(); 83 } 84 } 85 } 86 }

Then there is a small math library I created to get the angle of the text through some simple Trig.

FooTheoryMath.cs

1 using System; 2 3 namespace FooTheory.iTextSharpLibrary 4 { 5 /// <summary> 6 /// Math library 7 /// </summary> 8 public static class FooTheoryMath 9 { 10 public static double GetHypotenuseAngleInDegreesFrom(double opposite, double adjacent) 11 { 12 //http://www.regentsprep.org/Regents/Math/rtritrig/LtrigA.htm 13 // Tan <angle> = opposite/adjacent 14 // Math.Atan2: http://msdn.microsoft.com/en-us/library/system.math.atan2(VS.80).aspx 15 16 double radians = Math.Atan2(opposite, adjacent); // Get Radians for Atan2 17 double angle = radians*(180/Math.PI); // Change back to degrees 18 return angle; 19 } 20 } 21 }

 

The Results

Utilizing a simple interface:

image

We're able to generate PDF's that are watermarked on an angle from bottom left corner to top right corner.

Here is a screen shot of what the generated PDF looks like:

Clicking the Top button:

image

Clicking the Bottom Button:

image

I'm able to change the message:

image

This will produce:

image

 

Conclusion

I found the iTextSharp quite versatile for working with PDF's. This solution will help you write text to existing PDF's quite easily.

Possible implementations include:

  • Place this into a WCF service to create a watermarking service
  • Leave it as it is, implemented as a class library.
  • Create your own .NET PDF Client that you could sell (I've read somewhere - cant find the source - that a couple third party .NET PDF components are actually written on top of iTextSharp).

While working to accomplish what I have above I found the best reference for iTextSharp was actually the iText Book written by Bruno Lowagie. You can purchase it here on Amazon.com.

And Finally ... While writing this I kept thinking .....

Why would you want to watermark existing PDF's?

There are a few options.

  1. Accountability: Lets say you have a ton of PDF's stored from a long running highly confidential report process and these PDF's are stored nightly/weekly on a certain directory. Perhaps you want to make sure that when a user logs in and accesses one of these highly confidential PDF's you water mark it with the users name on each page. Therefore, if it makes it into the hands of the media, you can see where/who it came from.
  2. Licensing: Perhaps you main product is a PDF. Lets say you're a book publisher and you sell PDF versions of the book or you allow people who have already purchased the hard copy to download the PDF version.  What you can do is force the user to create a profile in order to download the PDF. Usually this also includes some type of security question like "turn to page 435 and give us the last word on the page" in order to validate the user actually HAS the book in hand. Once they are authorized to download the PDF book, you can watermark every page on the book with their name "Licensed to: <FirstName> <LastName>. Let's face it, people are MUCH less likely to give a PDF book away on Torrent or P2P software when every single page has their name on it. It's not the BEST method of licensing, but it works.
  3. Other: Perhaps Company A is acquired by Company B and Company B wants to make sure that all PDF's on Company A's site are amended with the text "Company A is a subsidiary of Company B". What if company A has 15,000 PDF's that they have on their site? Maybe its a resume assistance site that has over 15,000 sample resumes. Are you going to open each PDF and do this by hand? Nope. Not at all. You can intercept the call for the PDF's and then write the text at the bottom before they're delivered to the end user.
  4. The list could go on and on ...

 

Download The Code

FooTheory.iTextSharpLibrary.Example.zip (4.69 MB)

#    Comments [4] |
 Wednesday, May 07, 2008

The Importance of Unit Testing WCF Attributes

Normally unit testing is used to verify that state is being altered as expected and interactions are occurring as expected (state based testing or interaction based testing). We also write integration/functional tests to ensure that layers and components are working together correctly in the overall picture.

While in the field I've noticed that most tests neglect the attributes of the WCF ServiceContract. Shouldn’t these be tested as well? Yes, they definitely should!

You may say .... "OperationContractAttribute  is just an attribute that indicates that this method is part of a service contract in a WCF application, so why do I need to test the attribute?" 

Good question... consider this scenario:

You're the developer on a large enterprise system and you've created a WCF Service that handles processing sets of data. Depending on the parameters, this data can take hours process. Therefore you've decided to implement the "IsOneWay" attribute value on the OperationContractAttribute.

Is One Way explanation:

Use the IsOneWay property to indicate that an operation does not return a reply message.
...
If the IsOneWay property is set to false (the default), even methods that return void result in a reply message. In this case, the infrastructure creates and sends an empty message to indicate to the caller that the method has returned. (Using this approach enables the infrastructure to send SOAP faults back to the client.) Setting IsOneWay to true is the only way to cancel the creation and dispatch of a response message.

 

Why Testing IsOneWay Matters

Now that you've set the IsOneWay value to true in your service, the calling applications can fire off a request and let the service crunch away on the request (remember, in this scenario, it may take hours to complete). This is an expected behavior of your service - having the method return as soon as its sent without waiting for a response message from the service.

Fast forward 4 weeks .... Joe Developer decides to remove the "IsOneWay" value (which in turn changes it to false, which is its default) because its not working for his new application as he expects. Everything works for him now, and he checks in the code to source control. Everything builds on your continuous integration environment. All tests pass, everything looks golden.

The new service updates and application updates get applied to production and almost immediately users start complaining about another line of business application "freezing up" when they click a certain button.

"All of a sudden, when I clicked the <Load Data> button, the application just froze. I just left for lunch and when I came back everything was normal. Now, its doing it again. I'm not sure what's going on. This application sucks."

You check the app logs, event viewers, traces, etc and then realize that the application IS WORKING but it stops for quite awhile at the service call. The weird thing is that the code does not throw any errors, it just takes forever to return from that call. This problem seems to be a performance problem. If you're not careful this problem could masquerade itself as another probelm in your mind:

"Is the network slow?"

"Is the service down?"

"Is it doing a retry?"

"Are all the packets getting transmitted?"

The list could go on and on.

The Reason For the Slow Down in the App

Why is the app performing so poorly at this service call? Because IsOneWay was set to false (default when not preset in the attribute values). The app that was written 4 weeks ago expects IsOneWay set to true so it does not block the current thread waiting for a response from the service call.

Since the call is set the value of IsOneWay is set to false, the application is now hanging.

How To Prevent This

The continuous integration environment should have had a test for this. Either unit test or integration test. Unfortunately it did not, and in most companies I don't see a test for this kind of thing, ever.

To fix this we need to implement a unit test for this attribute. We need to make sure that it is set to TRUE so that we dont break anything.

 

Code

Below is the code to implement the test for the IsOneWay attribute value.

FooTheory.WcfServiceExample.cs  - The service we need to test.

1 using System.ServiceModel; 2 3 namespace FooTheory.WcfServiceExample 4 { 5 [ServiceContract] 6 public interface IFooTheoryWcf 7 { 8 [OperationContract(IsOneWay = true)] 9 void Execute(); 10 11 } 12 }

The Unit Test

FooTheoryWcfContractTests.cs

 

1 using System; 2 using System.ServiceModel; 3 using FooTheory.WcfServiceExample; 4 using NUnit.Framework; 5 using NUnit.Framework.SyntaxHelpers; 6 7 namespace FooTheory.WcfExampleTests 8 { 9 [TestFixture] 10 public class FooTheoryWcfContractTests 11 { 12 private readonly string ONE_WAY_METHOD_NAME = "Execute"; 13 14 [Test] 15 public void Execute_Should_Be_OneWay() 16 { 17 object[] atts = typeof (IFooTheoryWcf) 18 .GetMethod(ONE_WAY_METHOD_NAME) 19 .GetCustomAttributes(false); 20 21 OperationContractAttribute opAttribute = 22 (OperationContractAttribute) Array.Find(atts, 23 delegate(object obj) 24 { 25 if (obj is OperationContractAttribute) 26 return true; 27 return false; 28 }); 29 30 Assert.That(opAttribute, Is.Not.Null, 31 "Could not find the attribute connected to the method that is needed."); 32 Assert.That(opAttribute.IsOneWay, Is.True, 33 "Method should be marked as IsOneWay for Application X"); 34 } 35 } 36 }

Code Explanation

The unit test uses reflection to get the attribute of OperationContract and then it checks to see if its not null and also checks to see value of the IsOneWay property.

 

Conclusion

If either one of these asserts fail, the build will break in the continuous integration environment. This will let the dev's know that something they did broke an expectation on the service contract. Catching this type of problem early in the cycle can help immensely. Not only does it save time, but it saves money in both dev time as well as end user time.

If you don't catch this early on, you could be calculating the costs of lost time of a couple of devs as well as numerous end users who are using the dependent application(s). If you're using this Service in a SaaS approach, you could really been in some hot water with those clients that utilizing your service. No one wants to use a service that is unreliable.

So, remember, test early and test often! Get those WCF Attributes under test!

#    Comments [0] |
 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] |

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: <