Monday, August 24, 2009

Interop 2.0 vs. 1.1 Breaking Change

This isn't the most exciting adventure I'll write about but it seemed as though several people out there experienced this adventure so I thought I'd divulge my secret route to get through it alive.

Here is the super nasty and super helpful error message that I received at run-time:

Unable to cast COM object of type 'System.__ComObject' to class type 'SomeCompany.SomeProduct.Interop.SomeClass'. COM components that enter the CLR and do not support IProvideClassInfo or that do not have any interop assembly registered will be wrapped in the __ComObject type. Instances of this type cannot be cast to any other class; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.

It was clear what I had to do.

OK, maybe it wasn't so clear what I had to do but thanks to doing a little reading between the lines at this post it became clear what I needed to do.

First of all, it appears that this happens when you convert a 1.1 project to a 2.0 (or higher) project and the project has a reference to a COM DLL via interop.

The solution is to drop your reference to the COM DLL and then re-add it.

Next go to the lines where you are experiencing the errors and make a tiny change by deleting the "Class" suffix off of the type names in your variable declarations. For example, my VB.net 1.1 code looked like this and would not run in 2.0:

Dim objFdfAcX As FDFACXLib.FdfAppClass

Dim objFdf As FDFACXLib.FdfDocClass


I simply dropped the "Class" suffix and the following 2 lines ran just fine:

Dim objFdfAcX As FDFACXLib.FdfApp

Dim objFdf As FDFACXLib.FdfDoc


The great thing about this little adventure is that it reaffirmed what my friends have told me for decades, "You've got too much class." Now, I finally know what they were talking about.

Happy coding.

Friday, July 24, 2009

Seek, and Ye Shall Find - Visual Studio Find & Replace Tips

Today, I want to share with you a few tips to find your way through the real jungle, my code!

Our project is huge. 2500+ files and growing. Those aren't all image files either, wise guy!

Because of the size of our project I have always experienced a extremely slow response when I use the "Find" feature, [ctrl]+[f], in Visual Studio when I did an "Entire Solution" or "Current Project" search. This pause became unbearable. It was like standing in the middle of a jungle just waiting to get eaten. The suspense drove me nuts! Would it find anything? Would I die before I found out?! I couldn't take it.

So, as most adventurers do, I started experimenting.

The first thing I tried was "incremental search" [ctrl]+[i]. This is really cool because you don't get a pop up window, you just type [ctrl]+[i]+{whatever} and Visual Studio will start to search for "w", then "wh", then "wha", then "what", etc... I liked searching without the pop up. It was very convenient. If you find what you are looking for but you need the next match just type [ctrl]+[i] again and it will jump to the next match. [ctrl]+[shift]+[i] will allow you to search backwards through the file. Pretty cool and pretty handy. Another benefit of this is that if you always use incremental search to search within the current file that allows you to leave the traditional "Find" dialog set to "All Open Files." I believe "All Open Files" is the best use for the traditional "Find" dialog.

But wait, there's more. Order within the next 10 minutes and get free shipping.

Incremental search is nice for small jobs, sort of like an explorer's pocket knife but what should you use when you need a machete?

The answer you seek is "Find in Files." [ctrl]+[shift]+[f].



"Find in Files" is the real secret that ties my whole search strategy together! First of all, loosely speaking it is 4000 times faster than regular find because it runs asynchronously. As soon as it starts to find matches the matches appear where you specify (generally the "Find Results 1" toolbar/window). Once items appear in the "Find Results 1" window you can start double clicking on them to be transported to that spot in the code.

Here's another secret though that makes this even more powerful. That list is persisted in that window even if you do a regular "Find". So, you can have two sets of find results at the same time. There is also a "Find Results 2" pane if you need a 3rd. Now, it gets even more cool!! [Suspense Builds.... sort of like when you wait for the regular find to return a result] Because the next match of a regular find can be accessed using F3 you can move through those regular find results while moving through your list of "Find in Files" results using F8. The 2 lists can really be worked on simultaneously!

Keep in mind that any time you have a code helper window (e.g. the error list, the bookmark window, the build output window, etc...) with code line markers in it you can double click to navigate to that spot in the code AND you can use F8 to move to the next item in the list. This is a huge timesaver for me.

Just as there is a "Replace" [ctrl]+[h] command, there is also a "Replace in Files"[ctrl]+[shift]+[h] command. One thing to keep in mind is to UNCHECK the "Keep modified files open after Replace All" if you are going to modify a large set of files. Generally, loading all of those files into the IDE will slow the operation down tremendously and may cause your IDE to lock up.

So, the next time you are lost in a really big jungle, remember [ctrl]+[shift]+[f].

By the way, when a machete is not enough I like to use a bulldozer. I am currently developing a bulldozer that will do multi-file, multi-line, regular expression enabled find and replace. Keep checking the blog (or subscribe) to see when it becomes available.

Web Services - Now, that's an adventure

Recently we got this wonderful exception at work:

WebHost failed to process a request.

Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/4110503

Exception: System.ServiceModel.ServiceActivationException: The service '{ServiceName}.svc' cannot be activated due to an exception during compilation. The exception message is: Operation '{MethodName}' of contract '{InterfaceName}' specifies multiple request body parameters to be serialized without any wrapper elements. At most one body parameter can be serialized without wrapper elements. Either remove the extra body parameters or set the BodyStyle property on the WebGetAttribute/WebInvokeAttribute to Wrapped.. ---> System.InvalidOperationException: Operation '{MethodName}' of contract '{InterfaceName}' specifies multiple request body parameters to be serialized without any wrapper elements. At most one body parameter can be serialized without wrapper elements. Either remove the extra body parameters or set the BodyStyle property on the WebGetAttribute/WebInvokeAttribute to Wrapped.

I don't usually blog about exceptions because I cause so many of them! I'd never have time to make more if I wrote about each one! Well, actually, usually someone else has already thoroughly blogged about it. In this case, I did not stumble upon a blog for this exception. It was nearly as exciting as the birth of another child. So, I'll name it... "Targort".

So, where did Targort come from and how was Targort corrected?

I cannot answer that without putting a little adventure into the story first. So, we had a huge demo on the horizon and we'd been testing and tweaking for weeks. The development machines were smoking! The build server was sweating and gasping for air and the demo server looked to be coming online nicely. Then with 48 hours to go before the demo we found this one service was not running on the demo server. Of course, "everything was the same on the 2 boxes." So, it couldn't be the boxes. Finally, my boss, Roberto the Wise, was able to conclusively eliminate the boxes. We had other interfaces within the same service that would work, everything else checked out and all the evidence pointed to the code (AKA me, the meek).

Time was running short but we really suspected it was something in the code even though the code in the .svc.cs file was pretty vanilla because it was essentially just a facade in front of the real logic in the system.

Finally, my colleague, Marco the Magnificent, looked at the .svc file. You know, it is one of those files that you never look at because it has "nothing in it." Well, there lay the treasure we were searching for. The file, which had never been altered since it was created and had worked/compiled on numerous other servers, had quite a bit of information in it that didn't seem to correspond to anything we were doing:

This is what it looked like:

ServiceHost Language="C#" Factory="System.Data.Services.DataServiceHostFactory, System.Data.Services, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Service="SharedServicesService.DocManInfo.DocManInfoService"

True, our service was in the namespace "SharedServicesService.DocManInfo.DocManInfoService" but what did "System.Data.Services.DataServiceHostFactory, System.Data.Services, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" have to do with anything?

Once we changed the file to this:

ServiceHost Language="C#" Debug="true" Service="SharedServicesService.DocManInfo.DocManInfoService" CodeBehind="DocManInfoService.svc.cs"

(I was forced to omit the starting and ending characters in these files due to the limitation/restriction within blogger on certain character combinations)


Everything came together perfectly and we had 11 minutes left before the demo!


The server wasn't the only thing sweating during this adventure. I hope you enjoyed it as much as we did. Or at least, I hope this will solve your problem if you ever run into Targort the Terrible in the jungle.


Just a good piece of troubleshooting advice on web services, always make sure the WSDL file can be viewed in the browser. If the WSDL won't work, that narrows things down to a compile time issue.

Thursday, June 25, 2009

Passing Microsoft Certification Exam Strategy

It has been a while since I've written about my adventures. I guess I've been too busy working and studying for these Microsoft Certifications to have fun. Nevertheless, now that I have passed my 2nd exam I thought I would make a few suggestions for others taking these exams.

First of all, this blog isn't named "Adventures in .Net" for nothing so let me throw some adventure in as my first tip. Before you even leave the house make sure you have very good directions. These testing centers can sometimes be down alleyways or in basements and so on. Be certain of where you are going. Maybe even use a low tech thing called a "phone" to call the testing center. Online maps are only so good and cannot always help you find these out of the way places. On my first exam, I missed a turn (thanks construction!!) and I had to drive through an entire cemetery to get turned around. Driving through a cemetery before an exam is not a good omen in my book! Although, I have never failed an exam after driving through a cemetery so you might want to try it too!

Before you even leave the check-in counter, ask for 2 pens and make sure they both work. I have found that most of the pens cannot endure the adventures that I put them through. Get two, you might need them and as any adventurer knows you have to be prepared.

Next while you are at the check-in desk take a few minutes to draw a spreadsheet on the exam notes dry erase page that they give you. I believe the tests that I took had 30 questions (ask the check-in person how many questions there are) each. So, what I did was write the numbers 1-30 down the left hand margin. Put half of numbers on each page. Make the rows large so you have plenty of room. Then I made columns A-E so I had a mini spreadsheet. If you have suffered a pen burn out get another one before entering the "chamber of doom." I mean "testing room."

Now, start the test.

When I worked on question #1, I would cross off the answers that I knew were completely wrong in row #1 of my spreadsheet. Typically, this would lead me to either 1 or 2 possible correct answers. Hopefully, you know the topics well enough that it leads you to 1 correct answer but sometimes 2 might look correct. So, now that you have narrowed the field to 2 possibilities you can really focus on what makes each answer either correct or incorrect. If there is some doubt in your mind, make sure you check the little "Mark for Review" (something like that) box in the upper left corner of the test screen so you can go back to review the question before finalizing your test. On these items that you will have to review later, try to write a little note on the spreadsheet to help remind you of the key information and possible deciding factor for each question. Typically, there is one key difference between two answers and sometimes it might take a minute to search through the lines of code to see that difference. Just a note like, "line 5" will help you return to that question later and focus on line 5 and ignore all of the other identical lines.

Answer each question and keep track of the possible answers on your old school "spreadsheet."

When you are certain of an answer cross the question number off of your spreadsheet or put a big smiley face next to the question number. I like the smiley face approach because it makes me smile and gives me positive energy. Sometimes you need a little positive energy during a 3 hour exam!

Once you have completed each question, go back and review all of the questions that you are uncertain about. Here's where the spreadsheet really pays dividends. As you are re-examining each question you will only have to focus on the 2 possible correct answers and you can really stay focused on what might be correct. If you have ever taken one of these Microsoft exams you know that each answer might be 5-10 lines long so you don't want to re-read a completely wrong answer over and over again. It is a waste of precious time.

Hopefully, once you are done with your second pass through the exam you will have enough smiley faces to know that you've passed (which I believe is 70% for all exams). If not, keep reviewing the questions that you have doubts about as time permits.

I have found that I definitely will change answers when I do my question review so do not skip reviewing your answers. Often, for example, question #7 might make more sense the 2nd time through thanks to information you learned while answering question #19.

Also, on the exams that I took, after about 6 questions I just wanted to go home. Each time, I found myself saying, "This wasn't in the book! This is going to turn out really ugly." Obviously, jumping ship wasn't an option so I just kept going and each time when I went back through and reviewed my answers I found myself saying, "Now, which questions were they that I thought were so impossible?" It seemed that once I had answered all of the questions and my nerves had settled, I got a better perspective and things worked out great. So hang in there if the first few questions throw you for a loop. It will get better.

Good luck on your Microsoft certification exam(s)!