Author Archive for Ben Sanders

6 Phases of Being Employed in the Insurance Industry

Phase 1

You are listening to jazz — Your first day at work is great. Your fellow co-workers are wonderful, your office is cute, you love your agents, and your manager is the best!

Phase 2

You are listening to pop music — After a while you are so busy that you are not sure if you’re coming or going anymore.

Phase 3

You are listening to heavy metal — This is what you feel like after ONE month.

Phase 4

You are listening to hip hop — You become bloated due to stress, you’re gaining weight due to lack of exercise because you are so tired and have so much work to do and, when you do get home, you feel sluggish and suffer from constipation. Your fellow co-workers are too cheerful for your liking, your agents don’t understand a word you say and the walls of your office are closing in.

Phase 5

You are listening to GANGSTA RAP — After more time passes, your eyes start to twitch and you forget what a ‘good hair day’ feels like as you just fall out of bed and load up on caffeine.

Phase 6

You are listening to the voices in your head — You have locked your office door to keep people out. You wonder WHY you are even here in the first place and WHY you became an insurance professional!

Developer Death Marches

I’m done with my haitus from blogging…until I need another haitus ;).

What I wanted to write about is the typical, ever more frequent now, developer “death marches.” From my experiences, as well as those told by friends, occur when some executives get something in their head that must be done by a specific date with arguably shakey business reason and rationale. Then the IT manager realizes they have no real authority as they are instructed to literally kill their team by making them work mandatory overtime, weekends, and holidays. This typically leads to the developers to be stressed, zombie-like (no headshots please), and ready for revenge. {Imagine the retaliation effort here}. After the unsuccessful uprising of developer sarcasm and/or poor code…the inevitable almost always happens. The…saving grace, if you will - some executive realizes that the requirements and testing efforts are not ready, and they really had not been from the start. So the project gets delayed, shelved, or worked on at a slower pace.

I spoke with a friend of mine last week - learning that they were grinding away, now addicted to caffeine, and affecting their health only so that they could have the 3-day Memorial Day weekend to their family. I know of some others who last year had the Christmas season, but at the expense of their January thru May.

I believe companies are doing this due to higher turnover and the current economic situation. They see this as a cost-saving measure. It clearly is not. Not only does one’s codebase suffer, but their other employees see this and company-wide morale erodes. Then comes the turnover - which usually occurs during a hiring freeze (for added smite and dramatic effect). And the project, which may have even been very good for the company’s business and future, suffers to a point it either gets canceled, shelved, or redesigned by some astronaut architect.

So IT managers and executive, if you value your livelihood, and that of your developers, please, do not send them through a death march. Developers have this embedded sense of justice - and one way or another, they will win - you can bet your overpriced mocha on it…mwahahahaha…ahem…seriously…they will win. Serious.

Adobe Acrobat 8 Serious Error - Windows Terminal Server

I’m not about to go into all of the 10,000+ possible things you can do to attempt to fix whatever is causing this, including, but not limited to, firing a semi-automatic at your server. But you shouldn’t do that, since it’s not your hardware’s fault that Adobe Acrobat can’t work right. You could, however, go skeet shooting with the Acrobat CD! I’m only going to share what we did that seems to work for us.

To clarify our configuration:

Windows 2003 Server x86 Terminal Server
Adobe Acrobat Professional 8.1 (with 8.1.3 update)

We have been fighting the dreaded “Serious Error” message in Acrobat for a few months. It all started when we changed the processors in one of our terminal servers. The error I’m referring to is the one in Adobe Acrobat where it suddenly hangs for some unknown amount of time and then crashes with a “Serious Error has occurred” message.

My system administrator and I searched and searched with no luck in the Adobe forums. We tried it on a clean terminal server install, we tried messing with permissions, filemon, procmon, etc.

Finally, I had noticed a pattern, in the registry, HKEY_CURRENT_USER\Software\Adobe\Adobe Acrobat\8.0\AVGeneral has a bActivated and bLastExitNormal which was setting itself to 0 (false). I think Acrobat was thinking it wasn’t actived, and since my users weren’t admins, they key must not have been able to rewrite itself. But this key only changed when Acrobat locked up and gave the serious error. If you killed the acrobat.exe process before the error, the key stayed. Once we remotely changed everyone’s keys, it worked, until we started adding more users who didn’t have this key.

Finally, we thought we had everyone, but we received the error again. We went through and fixed them all again. This time, I felt like the only thing “patch”-related we didn’t do was this licensing service patch from Adobe: http://www.adobe.com/support/downloads/detail.jsp?ftpID=3750.

We also created a login script addendum as follows:

AdobeAcroFix.bat

REGEDIT /s \\orourke.local\sysvol\orourke.local\scripts\Acro8RegFix.reg

AdobeAcroFix.reg

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Adobe\Adobe Acrobat\8.0\AVGeneral]
 "bLastExitNormal"=dword:00000001
 "bActivated"=dword:00000001

So in summary, here’s what we did:

  1. If on terminal server run change user /install from the command line
  2. Install Acrobat Professional 8
  3. Reboot if necessary
  4. Make sure/update to 8.1.3
  5. Reboot if necessary
  6. If on terminal server run change user /install from the command line
  7. Install the Adobe Licensing patch, following the instructions exactly at the bottom of the page
  8. Reboot (if you followed the directions)
  9. On your DC, or local machine, setup the above batch file and registry file.
  10. Cross your fingers!

I sincerely hope this helps some of you suffering for as long as we did (or longer).

LINQ - OrderBy Method and Multiple Fields

Just a friendly helpful tip - if you are using LINQ and have, for example, a list of objects, you can use the OrderBy() method to order it. But in order to order it by additional column criteria, use the following:

listView.DataSource = myList.OrderBy(i => i.Field1).ThenBy(i => i.Field2);

Additionally, the OrderByDescending() and ThenByDescending() methods also exist to assit you.

Exchange 2007: Corrupt MMC Queue Viewer

This is to help out anyone that receives the following error with Microsoft Exchange 2007. When you are in the Exchange Management Console, and click Toolbox and Queue Viewer, the following error is displayed:

MMC cannot open the file {Exchange Install Folder}\Bin\Exchange Queue Viewer.msc.

This may be because the file does not exist, is not an MMC console, or was created by a later version of MMC. This may also be because you do not have sufficient access rights to the file.

To resolve, assuming you have the proper authority, delete the following file:

C:\Documents and Settings\{yourusername}\Application Data\Microsoft\MMC\Exchange Queue Viewer

ASP.NET Web Services & XElement Return Types

I’ve been a huge fan of LINQ to XML. So I have been trying to have a ASP.NET ASMX Web Service with several WebMethods return XElements. You cannot return the XDocument as it is not serializable. However, XElements are. But, in my experimentation, after having a few XElements returned, I receive an IllegalOperationException: Cannot use wildcards at the top level of a schema.

Here is an example of what I was trying to do:

using...
namespace WebServiceTest
{
    public class WebServiceTest : WebService
    {
        [WebMethod]
        public XElement OhHai()
        {
            return new XElement("OhHai");
        }

        [WebMethod]
        public XElement GetCheezburger()
        {
            return new XElement("ICanHasCheezburger");
        }

        [WebMethod]
        public XElement Errored()
        {
            return new XElement("KTHXBYE");
        }
    }
}

I have attempted this on three different computers with Visual Studio 2008. All behave correctly with one or two, but usually when adding the third, I get the exception. If I change the third to return something else, it works fine. Very strange. Obviously it’s some kind of bug on the .NET side of the world. I guess it still is best to return an XmlNode or even a string (but can sometimes be unpredictable)…

One last note for you beginners to LINQ to XML. When using XElements or XDocuments, you have really a lot at your disposal to convert this to something else. You can use the CreateReader or CreateWriter methods, ToString works, etc. My preferred method, however, is calling the WriteTo method. This allows the XML as it should be represented to be output flawlessly every time.

Support: Can’t Connect to Printer

I was trying to install my networked color-laser printer on my daughter’s laptop this weekend. She is running Vista Ultimate, my printer is a Dell 3110cn Color Laser, and it is connected and shared via Windows 2003 R2 server.

My laptop connected to the printer fine as a network printer, but her computer kept throwing the following exception:

Windows cannot connect to the printer. Operation could not be completed (error 0×000003e3).

The resolution was the following:

  1. Install the drivers for the printer on the computer
  2. Start button > Printers > Add Printer
  3. Add a local printer
  4. Create a new port > local port
  5. Enter the name to the shared printer. If the name has spaces, rename the printer’s share name on the host/server.
  6. Choose the correct drivers that were installed (from step 1)
  7. If prompted, choose to use the existing driver
  8. Name the printer for the local machine
  9. The rest of the steps are self-explanatory

I hope this helps any who struggle with this annoyance.

10 iPhone Apps to Rule the World…

So I was discussing iPhone apps with my friend R&B. I was telling him I still haven’t settled on the next big iPhone-app-money-making-scheme. He was saying his were some pretty awesome ideas - so we started joking around.

After further thought, here would be my top 10 iPhone apps necessary for world domination:

  1. Print Money
  2. Force Field
  3. Cast Magic Missile
  4. Summon Sephiroth
  5. Cloaking
  6. Say Random One-Liner
  7. Macro of the Konami code
  8. Death Ray (similar to the Death Star’s)
  9. Teleport
  10. God mode

Salesfarce.com - The True Salesforce.com

SalesFarce.com - Failure on Demand

Boy do I have stories about this one…

I remember the day that our company chose to use SalesForce.com (SFDC) as our CRM for lead management. Basically they wanted to get rid of our old back-end system and “upgrade” to a web version with a new supplier. After a brief protest from research in a past life around SFDC, I reluctantly accepted the task to work with them.

It started off fantastically. We met with two very promising people. One was an architect and one was a configuration expert. We met with our business users and mapped out how we would exchange XML data. Our task was ridiculously simple - to have a common lead schema for vendors to submit leads to SFDC’s API. Then their API would do its magic to place the lead in the correct place(s). Then, at a later time, when our sales agent wanted to quote a lead on a product, they (SFDC) would submit the selected lead’s data to our web handler that starts the sales process with our transactional system.

Let’s talk about the leads CF: SFDC explained they don’t have a web API for leads. But they didn’t mention it up front. They mentioned it late into the project. Instead they sub-contracted some no-name company by a guy named Server-On (<- that isn’t anonymized, it really sounded like he was Server On) to write a C# web service project that talked to their API, because we wouldn’t be able to comprehend it. Once I learned of this, I laid the rules for 3rd-Party work. This included fixing code analysis warnings (some could be suppressed - we weren’t Nazi’s) and writing unit tests (80% coverage - sorry Phil Haack). Well they had us attend a WebEx conference to see what they had done. I was incognito as Vic Romano and my lead was Kenny Blankenship. There had not been any attempt at checking, let alone fixing, code analysis errors. They did have unit tests! It consisted of one class named {Something}Test that called another class with some made up variables. And it only called one or two methods in total. Nice… So we pulled Presley off of his failling Callidus project to write a web service that validates and transforms (novel ideas right?) our vendors’ submitted lead data and submits them to the SFDC’s 3rd-Party web service. Oh, and at the last minute, I was notified that this 3rd-Party web service will be hosted on our servers.

Now onto the real pain…the web service that passes a product and lead data from SalesForce.com to our transactional system’s handler. They assigned this developer Crumbie. Crumbie was presented to us as a seasoned developer. Oh, and they yanked the architect from us. So Crumbie and my team of three (not counting Presley) were trying to make this work. My lead, Mr. Bitterman was the overseer, R&B was writing the integrations with our transactional system, and Cornhusker was my middle-man, writing all of the integrations between SFDC and us. So it starts off with us having numerous sessions to bring Crumbie up to speed on what we’re trying to accomplish. We find out very quick in the process that SFDC had a terminal flaw in their design. We needed a combo-box that listed our ID-Product name name-value pairs. Easy right? Not so much. SFDC doesn’t support ID fields. All…let me say that again…ALL fields in SFDC are text, not GUID/Int/ID driven. uBersweetness… So then we got past that hurdle somehow, and then Crumbie is pointing his finger at us saying our end-point is giving hard exceptions. Mr. Bitterman quickly gets me and Cornhusker involved, because they can’t recreate the exceptions. Crumbie confirmed that he is sending the XML in the body of his request. I told Cornhusker to introduce logging into his service. I want their XML string logged first thing, then he can do what he wants with it. After doing this, and Crumbie having another exception, we looked at the log. it looked like this:

<html>
    <body>
        <?xml version="1.0"?>
        <QuoteRequest>
        ...
        </QuoteRequest>
    </body>
</html>

So the rockstar developer did as told…he put his XML in the <BODY> of the request (ROFLMAO x 10000). Mr. Bitterman quick shot him a lengthy email with links to w3schools.com and the W3C spec regarding XML. He also included references to XSD’s, as Crumbie was submitted XML that was invalid. The email was a masterpiece - it remained on my cube wall for weeks.

After months of this pain, we got to meet Crumbie face-to-face. I asked the begging question, “So how long have you been with SFDC?” The answer, “Oh, about four months now.” Excellent. Just excellent.

And the last pain that comes to mind is that another area of our company inherited a bunch of Java code for their integrations. They must have forgotten that we told them upfront we’re a .NET shop.

In summary, this is obviously a combination of being a smaller SFDC customer (hence the 4-month old developer), them getting too big, too fast and not being able to have quality architecture (i.e. the lack of ID fields), and terrible project management.

If you ever want other thoughts, check out thoughtsonsalesforce.com.

Good times, good times…

WPF ListView Not Refreshing

I’ve spent the last few days tracking down how to get a ListView to refresh its associated generic list collection which is populated via LINQ to SQL. My UI is more complex than the below example, but you’ll get the idea. I essentially wanted a ListView that gets populated from a LINQ to SQL object. As the binding is occurring, I want it to check to see if the transaction has been voided. If it has, I want it to disable the Void button. I do this check view an IValueConverter. This was working, but after clicking on an unvoided transaction, the button’s IsEnabled property wasn’t changing. And after reading many posts, ranging from using ObservableCollections to changing the ListView.DataContext to changing the ListView.ItemsSource of the list, I still wasn’t able to find a simple solution to my seemingly simple problem.

After much trial and error - I thought I’d share with the world what I did to remedy it:

The XAML

MyWindow.xaml

...
<Window.CommandBindings>
    <CommandBinding Command="{x:Static MyWindow.VoidTransactionCommand}"
                    Executed="VoidTransaction" />
</Window.CommandBindings>
...
<ListView Margin="0,0,0,0" Name="myList" FontSize="10" FontFamily="Tahoma"
          Height="189"
          Width="585">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="ID#"
                            DisplayMemberBinding="{Binding Path=ID}" />
            <GridViewColumn Header="Voided?">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Button Content="Void"
                                IsEnabled="{Binding Path=IsVoided, Converter={StaticResource oppositeBooleanConverter}}"
                                Command="{x:Static MyWindow.VoidTransactionCommand}"
                                CommandParameter="{Binding Path=ID}">
                        </Button>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>
...

Teh Code :D

MyWindow.CodeBehind

...
private SomeDataContext db = new SomeDataContext(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
private List<SomeObject> privateList;
...
public static RoutedCommand VoidTransactionCommand = new RoutedCommand();
private void VoidTransaction(object sender, ExecutedRoutedEventArgs args)
{
	bool wasSuccess = insert some method that voids the transaction;
	if (!wasSuccess)
	{
		MessageBox.Show("This transaction could not be voided.");
	} else
	{
		db.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, privateList);
		ICollectionView view = CollectionViewSource.GetDefaultView(myList.ItemsSource);
		view.Refresh();
	}
}

OppositeBooleanConverter.cs

public class OppositeBooleanConverter : IValueConverter {
	public object Convert(object value, Type targetType, object
		parameter, System.Globalization.CultureInfo culture)
	{
		try
		{
			return !(bool)value;
		} catch {}
		return value;
	}

	public object ConvertBack(object value, Type targetType, object parameter,
		System.Globalization.CultureInfo culture)
	{
		return null;
	}
}

The Solution

Above in blue, you’ll notice that I call the DataContext.Refresh() method. And since it is overriden by the web method that I call in my implementation, I don’t want the UI to update the database, so I have the RefreshMode.OverwriteCurrentValues of the window-level field privateList. This will reset the data, but then you need to get a reference to the ICollectionView of the ListView.ItemsSource and call the Refresh() method of that, thereby loading your refreshed data into the view.