Saturday, December 31, 2005

Looking Forward to 2006, Looking Back on 2005

As is my custom, I like to take a look back at the end of the year and check out what happened. I'm bringing y'all along for the ride.

 

Reviewing my blog, I see that I had one goal for 2005: ship FlexWikiPad 1.0. Well, that didn't happen. In fact, I didn't even do any significant work on it. Why not? Because I managed to push a couple of major projects onto the stack on top of it (bet you've never done that ;). For one thing, it seems I have to write a whole new text editor control (something I also didn't finish this year). But more significantly, I decided to completely overhaul the FlexWiki internal architecture to make it possible to implement security in a sane way.

 

Of course, I didn't finish that, either, but then again I didn't expect to. It's a pretty big job to do in my spare time, and along the way, it morphed into a decision to port FlexWiki to .NET 2.0. That is actually coming along fairly well, especially now that I try to spend an hour every day working on it. With luck, I'll have something to alpha status in month or two more.

 

It wasn't all FlexWiki work this past year, though. I had paying clients, too. My work at Integic redesigning and updating their main product has, after three years, reached code complete status. That's fairly exciting for me, because as a consultant I rarely get to see a project through from the very beginning. Even more interestingly, it looks like I'll be involved in working on the next phase as well, which means I'll get to see if some of our choices wind up helping us out like we hoped they would.

 

My other work in 2005 is still ongoing. I'm developing Pluralsight's new architecture course, for one. The research for that has been very educational, as I knew it would be. Hopefully I'll be able to pull the rest of the class together over the next few months.

 

Of course, my work on MSDN2 continues as well, but I can't say much about what I'm working on just yet. When we get it in place, you'll definitely hear about it, both here and elsewhere. I think it's something that readers of this blog will find interesting.

 

As you can see, 2006 is looking to be every bit as busy as 2005 was…and then some. I'm just glad my wife will be graduating from her MBA program in the spring.

 

I'll close with a list of my favorite/most significant events/posts of the year:

 

January


 

February


 

March


 

April


 

May


 

June


 

July


 

August


  • I became a whore for rent. You should see the Google searches that post gets. :)

 

September


 

October


 

November


  • November was not a great month. Could have been worse, though. A lot worse.

  • I ran into this problem, which would have bitten me several times since if I hadn't gotten help from one of my smarter (specifically: smarter than me) friends.

 

December

Friday, December 16, 2005

sqlcmd.exe -v Rocks

I'm the first to admit that I'm no database guru, but I occasionally have need to do something beyond just a simple SELECT, and I can usually manage to fumble my way through it.

 

The other day, the thing I was fumbling my way through was restoring a database from a backup a client had sent me. While I was doing it, I ran across a neat little option to sqlcmd.exe that I hadn't seen before, but which I definitely want to remember. It's the -v option, and it lets you pass parameters to your SQL script. In my case, I wanted to pass the current directory, so I could restore the database to files in whatever directory I happened to be running. Well, putting this in a .cmd file does the trick:

 

sqlcmd -E -i restoredb.sql -v root="%CD%"

 

Then I can use the root variable in my SQL script. All I have to do is reference it with the $(root) syntax, like this:

 

RESTORE DATABASE MyDB 
    FROM DISK = '$(root)\mydb.bak'
    WITH REPLACE,
    MOVE 'mydb_data' to '$(root)\mydb.mdf',
GO

 

Nifty, eh? I know I'm far from the first one to "discover" this, but maybe it'll help someone who hasn't seen it before.

Thursday, December 15, 2005

Using a Custom WSDL File in ASP.NET Web Services

Some of the work I'm doing right now involves writing a web service that has custom WSDL. By "custom" I mean "written by hand, not generated by the ASP.NET web services infrastructure". In this case, it's because we've got a bunch of external schema types that we'd like to use in a certain way, but you might want to do the same thing for a variety of reasons, including just not liking the way the generated WSDL looks.

 

As it turns out, using an external WSDL is fairly easy. It's just a little obscure - I had a hard time tracking down how to do it using Google, so I'm documenting the process here. Following, the steps required:

 

Write a custom WSDL file.

Use the tool of your choice. The one thing you're going to want to do is to omit the <wsdl:service> declaration. This bit actually will be generated by the ASP.NET infrastructure. That makes sense, since it contains a URL, and can be more easily determined at runtime.

 

Drop the WSDL in the web directory next to your .asmx file.

Presumably, you still want people to be able to download your custom WSDL, so putting it somewhere web-accessible is a good idea.

 

Mark your web service implementation class with the [WebServiceBinding] attribute.

For instance, you might do something like this:

 

[WebServiceBinding(Name = "MyBinding", Location = "MyCustom.wsdl")]
public class MyServiceImplementation : WebService

{

// ...

}

 

The most important thing to set here is the Location property, which tells ASP.NET where your custom WSDL file lives. The Name property gives the name of the <wsdl:binding> from your custom WSDL, and is needed by ASP.NET to allow it to dispatch calls onto your implementation correctly.

 

Mark your web method with the [SoapDocumentMethod] attribute.

For example:

 

[WebMethod]
[SoapDocumentMethod(Action = "urn:foo-com:service/DoSomething",

Binding = "MyBinding")]

public DoSomethingResponse DoSomething(DoSomethingRequest request)

{

// …

}

 

The Action property associates this method with the action listed in your WSDL file. It is particularly important because ASP.NET chooses which method to invoke based on the action in the incoming message.

 

The binding element associates the operation with a particular <wsdl:binding>, in much the same way that the Name property of the [WebServiceBinding] attribute does. It’s required to be on the [SoapDocumentMethod] attribute for proper operation, but I still haven’t quite figured out why you need both.

 

Observe the generated WSDL.

If you surf to the automatically-generated WSDL page (e.g. http://server/path/to/service.asmx?wsdl), you’ll observe that ASP.NET is still generating a WSDL document for you. However, because of the changes you’ve made, that WSDL consists solely of a <wsdl:import> referencing the WSDL file you wrote, and a <wsdl:service> element containing the URL for the service. It’ll look something like this:

 

<wsdl:definitions targetNamespace="urn:foo-com:service">
 

<wsdl:import namespace="" location="MyCustom.wsdl"/>

 

<wsdl:types/>

<wsdl:service name="MyService">

  <wsdl:port name="MyBinding" binding="tns:MyBinding">

    <soap:address location="http://localhost /MyService/MyService.asmx"/>

  </wsdl:port>

  <wsdl:port name="MyBinding1" binding="tns:GetContentBinding">

    <soap12:address location="http://localhost/MyService/MyService.asmx"/>

  </wsdl:port>

</wsdl:service>

 

</wsdl:definitions>

 

Luckily, Add Web Reference respects the <wsdl:import> and (assuming you write the WSDL correctly), .NET clients will be able to generate code off of this document successfully. Other toolkits should be able to as well, but YMMV.

 

Particularly when coupled with the flexibility that IXmlSerializable gives you over the serialized XML, taking control of the WSDL is a very powerful technique.

Friday, December 9, 2005

C# Type Conversion Operators Considered Harmful

I see Fritz just posted a code sample that makes use of C# conversion operators. I don't like it. No sir, I don't like it one bit. :)

 

Here's the deal. A conversion operator is just a way of writing a method that you invoke using the C# casting syntax. The thing is, since it's a method, why not just make it a method. If I were writing this code, I'd call it ToUpdateItem() or perhaps emphasize its a factory nature by calling it something like CreateFromUpdateItem.

 

There are two problems with the type conversion operator approach as I see it. First, you're providing something that implies type compatibility, when really no such type relationship exists. Second, the conversion operator syntax implies that no new instance is created, when in fact a new object instance is created every time.

 

With a plain ol' method, people who maintain your code can see exactly what's going on. With a type conversion operator, you're just twisting the language syntax to make it look like one thing is happening, when really something else is.

 

A good rule of thumb is that if you see yourself typing "public static operator", you're doing something wrong. :)

Friday, December 2, 2005

FlexWiki 1.8.0.1696 Released

I just posted the latest version of FlexWiki over on SourceForge. You can download it here. Here are the release notes:

 

This release is primarily a bugfix release, although several minor
features have been added. Basically, the fixes were piling up, and we
were telling people "go download the latest interim build" often
enough that we decided just to make it official. Highlights of this
build include:

 

* At long last the death of the "incorrect wiki links" bug, where
  FlexWiki emitted links that corresponded to the first hit after
  startup. This most frequently manifested itself as links pointing to
  "localhost" even when the web server was accessed remotely.
* Null edits are now ignored.
* Slight performance enhancements, including the ability to turn off
  performance counters (which can cause large delays on some
  installations) via the DisablePerformanceCounters switch.
* Form support in WikiTalk

 

And much more.

 

Thanks to everyone that contributed, both those who wrote code and
those who reported bugs!

 

Please direct inquries about FlexWiki to the FlexWiki users mailing
list at
flexwiki-users@lists.sf.net.

I definitely recommend that you upgrade to this release if you're currently running 1.8.0.1677.

 

I'm guessing this will be the last official release of FlexWiki before 2.0. (You can always get unsupported interim releases from http://builds.flexwiki.com.) I've been working away in my spare (ha!) time on gutting and rearchitecting the content engine, and I've been making slow but steady progress. It'll probably be a few months before I get it to alpha status, but once there I should be able to start making rapid progress on implementing security and some caching improvements.

Sunday, November 27, 2005

Triple Whammy

It's been a bit quiet around here, but there's been good reason. As you know, my friend Alex got hit by a car. The next weekend, I sliced my thumb up with a table saw. Well, the weekend after that, the worst of the lot happened: I got a call from one of my brothers telling me that my dad had lost consciousness while returning from a vacation.

 

They say things happen in threes, and I certainly hope that's true, because after this one I'm ready for a break from hospitals. It turns out that my dad had an abdominal aortic aneurysm (a "triple A"). Briefly, this means that the large artery that leads downward from his heart had weakened and swelled. I saw the CT scan at one point: it was roughly the size of an American football.

 

My dad got lucky on several counts. To start with, he'd just traded places with my mom when he passed out, so he wasn't driving. That could easily have killed them both. On top of that, even though they were in northern Minnesota (which is basically the middle of nowhere), they happened to be near a hospital, so the ambulance was able to get him to a doctor quickly. And the doctor was good enough to get the diagnosis right and immediately put my dad on a helicopter for a hospital in Duluth. And the vascular surgeon in Duluth managed to repair my dad's artery, saving his life. Dad's blood pressure dropped to zero at one point, so it was a near thing.

 

The whole family descended on Duluth, of course. Dad was in the ICU for a week, but has since been transferred to the cardiac recovery unit. He's still in Duluth, but the rest of the family has started returning to their homes now that the largest dangers are past. We're all hoping that he'll be home by Christmas when we all return, although it's no sure thing.

 

One of the worst parts about the whole process was that my dad was so completely looped by the drugs and the shock and the sleep deprivation that he was basically delirious until about nine days after the surgery. And it wasn't until about eight days out that anyone was able to tell us it wasn't a stroke. It was pretty hard on my mom to hear my dad basically babbling nonsense about how he wasn't really in a hospital. Fortunately, sleep and changes of medication fixed that up and dad is now as sharp as ever.  

 

We spent the Thanksgiving holiday there in a hotel. My wife and my brother did a bang-up job of whipping up a first-rate giant meal using only a microwave and what they could find at the grocery store on Thursday afternoon. Still, I can certainly think of better ways to spend the holiday. But I can much more easily think of worse ways.

 

Here's hoping my next post talks about something boring like what I'm working on over at MSDN.

Thursday, November 10, 2005

Don't Argue With Power Tools

I think maybe the hospital I live near should build a tunnel from my basement to the ER. It's only about two blocks anyway, and I've walked over there four times in the last two weeks. The first three times were to visit my friend Alex, who got hit by a car. This latest time, though, was all me. Nothing quite so serious, but nonetheless not an experience I hope ever to repeat.

 

I was in my basement on Sunday, working on building a bench for my new planer. I've been buying a lot of tools lately, and it's starting to get a bit crowded down there, so I figured I'd work on some storage. So I was running a 2x4 through the table saw to cut it down to size.

 

I'm not entirely sure what happened next. My memory is a bit hazy for those few seconds. But I think I was concentrating on keeping one of my hands away from the blade, and didn't pay quite enough attention to the other. What I do remember pretty clearly is jumping away from the saw, yelling loudly, and clutching my thumb.

 

Before I go too much further, let me say that I did not sever any digits. I gave myself a really nasty cut across the pad of my thumb, but I didn't slice anything completely off. I'd say it's about a five or six on a scale of one to ten, where one is a paper cut, and ten is the aforementioned digit removal. The nurse at the ER (where I spent the next four hours) gave me an "A+", though. :p

 

Here's a picture of the rather nifty bandage they gave me.

 


 

They had to put it on with a special tool - it was sort of a cage that stretched a tubular piece of gauze out, and they fed it up and down, creating layers. Very clever, I thought.

 

If you want to see what it looks like underneath the bandage, well, what's wrong with you?!? :) But click here and check it out if you must. Warning to those with a weak stomach: it's gross. Warning to those with a highly developed photoaesthetic sense: the picture is poorly taken.

 

Anyway, it looks like I'll heal up in a few weeks. Right now, I can't feel the tip of my thumb, but I'm hoping that will come back. In the meantime, it hasn't interfered with my typing too much, and that's the important thing, since it's how I earn my bread.

 

The weirdest thing about the whole experience has been observing the mental and physical effects. I've never really hurt myself seriously before, so it was odd to feel myself going through the typical reactions. First was physical shock - I was disoriented and sweating for a few minutes right after. And then of course there was disbelief ("there's no way I just turned my thumb into a tiny pile of hamburger!"), anger (as I was walking to the ER I was super pissed that I'd been so stupid), depression (not the real kind, but I was a little down about it for a bit), etc.

 

All in all I'd say I was dumb but lucky. Which beats dumb and unlucky or even smart and unlucky. In the future I'm hoping to be smart and lucky. I also hope to return to amateur carpentry (sans the amateur surgery), but one thing I'm not sure about yet is whether this whole incident has dampened my enthusiasm to the point where I'll just find something else to do any time it's time to turn on the power tools. But if I do go back to it (as I intend to), I know this: I'm going to incorporate the piece of wood that I was cutting into the final product. Preferably with the bloodstain showing. Just something from my own twisted sense of revenge I guess. Or stubbornness.

 

So, woodworkers: be careful out there. Pay attention, build or buy whatever jig you need to make the cut safely, and think before you act.

 

Oh, and if you see my parents, don't tell them. :)