Thursday, December 02, 2010

Serialization’s “Pit of Success” with C# and JSON

{

Although it’s been mentioned before here, it bears repeating that before you find yourself making a reference to the DataContractJsonSerializer, you ought to consider and indeed are more likely better off with the NewtonSoft library Json.NET. Whereas the DataContractJsonSerializer relies on giving you the flexibility of creating types and using the DataContract and DataMember attributes on them for a lot of granular control, this is burdensome with types that should naturally find themselves serializable and JSON friendly. For example, let’s say I have a Dictionary<int, string>; the intent of the user shouldn’t be too complicated in the serialization process. Or, if I have a class Foo with a couple of properties, and I want to serialize an IEnumerable of said class, again, the intent doesn’t require the extra use of attributes and a complexity overhead.

This is not to say that the DataContractJsonSerializer does not have its place; if you are leveraging WCF and choosing JSON as your serialization format, it is probably the best route to go. That said, however, I have fallen more than once into a “pit of success” with Json.NET after getting burdened with trying to use the DataContractJsonSerializer.

Json.NET is still quite active, the last release during the latter half of this year. Check it out.

}

Friday, August 27, 2010

Design Related: Branding with Debbie Millman

{

I always struggled with a singular identity. Maybe that had something to do with going back and forth from East Africa and the United States, maybe it is because my father had a lot of books and it gave me a curious nature. Whatever it is, I am the kind of person who, when I find myself in a bookstore, picks up a magazine on a topic I know nothing about and enjoys trying to discover the nuances of a not yet explored world of information. I’ve done it with things like pens, model trains, and antiques.

When it comes to design, as much as it may seem by some to be orthogonal to software development, I’ve had the growing understanding that the two go hand in hand. Design, to me, is not picking nice colors for gradients or making icons. Design is planning, it’s understanding a problem and solving it. Although as a software developer my visual design has often been an afterthought (something I’ve fought with increasing intensity over time) and yet when I write a piece of software, put together a user interface, or model data structures, I am planning and problem solving. I am designing, even if I’m making a poor effort of things.

The more aware I’ve become of this, the more I’ve sought to have a baseline understanding of design which is why I found myself at the South Dakota AIGA hearing Debbie Millman give a talk on the history of branding, which was originally prompted by her thinking about the phenomenon of MySpace. I’d long been aware of Debbie; I listened to her Design Matters show when it originally became available online and look forward to a new podcast via Design Observer.

In speeding us to the present, the question of why there may be 300 national brands of cereal or 100 different types of bottled water in a store, Millman began 50,000 years ago with the “big brain bang” where scientists believe we developed our Triune brain. The 3 parts of the brain Millman talked about, Reptilllian, Limbic, and Neocortex are a basis for how she believes that branding works today – if I could shortcut to the conclusion, the reason why we put ourselves in groups and find affiliation important is because this need is hardwired. In one humorous aside, Millman said of the part of the brain that fears the unknown:

“You can’t meditate it away. It’s just there.”

The talk bolstered this point along many fronts, some anthropology, some historical/statistics and other scientific studies and anecdotes. She then divided the history of branding, starting from the US Trademark Registration (landmark legislation that is the legal foundation for branding) in 1876, into 5 different “waves:”

Wave 1: 1875 – 1920

Brands as a guarantor of consistency (Think Campbells soup, Quaker Oats).

Wave 2: 1920 – 1965

Brands as a guarantor of quality. (Think Mortin’s Salt, Pepsi).

Wave 3: 1965 – 1985

Brands as self expressive statements, telegraphing what others should think of us. (Think Nike, Levis, Volskwagen).

Wave 4: 1985 – 2000

Brands as an experience. (Think Starbucks.)

Wave 5: 2000 – present

Limbic brands. (Think Social Networking). In reference to the earlier portion of the talk on brain development, this is the part of our brains which serves us emotion and sense of group. In our present, fractured world, where traditional models of group like family are being uprooted by modernity, we turn to brands to fill that portion of our lives, which is hardwired.

I found the talk riveting, in large part because it aimed at a higher level thinking of how branding works. Afterward I had a chance to talk to Debbie and it sounds like there are new Design Matters shows in the making. I’ll look forward to hearing them and learning more.

}

Wednesday, August 11, 2010

Failure in two parts, IronRuby

{

I recently ran across a two part series from Dave Winer related to failure. Essentially Winer asserts the following:

“The only way to succeed in my opinion is if you cannot visualize failure.”

In the first post he describes a personal experience where failure was imminent and he pushed on despite it because he realized his back was to the wall.  In the second he keeps the theme by emphasizing the special level of determination necessary for success. Many of the blog posts I find my way to via Hacker News and other outlets have similar exhortations but Winer holds more gravitas for me because of his success as a founder and longevity as one of the alpha dog programmer/internet personalities.

Both pieces were inspired by the recent news that Google was no longer pursuing Wave – the kind of capitulation that may have inspired Winer’s title: “Embracing failure is a good way to fail.” As an aside, Dare Obasanjo has some thoughtful points on why Wave couldn’t grow.

Not long after I discovered that IronRuby’s future as a Microsoft project was in flux. It seemed to me similar to Wave in the sense that I remember the fanfare when all the Iron* (IronRuby, IronPython, etc… ) projects were beginning and the excitement of people in the programming community only to perk my head up now and find that the project seems no longer to have the good graces of its company. What a contrast.

I speak as an outsider but I suspected that as time passed the level of interest in these projects began to erode: everything from key people leaving teams to diminishing excitement from people on the outside. Most of my interest was directed toward IronPython since it was the most mature dynamic language implementation in the beginning (the whole concept of the Dynamic Language Runtime (DLR) came from Jim Hugunin’s early port of Python). This was both fortunate and unfortunate; I was eager to learn Ruby but since I can’t learn languages very fast I decided to maintain my focus on Python in exclusion of other DLR language implementations. All I can do is suspect but perhaps there were others like me who decided rather than trying to learn different languages simultaneously it would be better to focus on one.

Now as I think upon my encounters with the DLR, I realize that I’m a part of the “failure,” if one can call it that, of Microsoft in valuing this and other dynamic language implementations. Although I was excited early on, even spending some time creating projects and coming up with ideas that leveraged the dynamic languages on the DLR, I got bogged down by how hard it was without a lot of documentation and the difficulty of trying to convince people around me that what I was doing was worth it. (Insert the glazed eyes and “why not just use C#? It has intellisense…” conversation). In the interests of a more full disclosure, a personal tragedy from last year took a lot of wind out of my sails and I didn’t do any programming my spare time for a long stretch of time.

But of course I neither think that IronRuby is a “failure” nor do I think my lack of initiative over the last few years is the way things need to remain. Now seems an even better time to become more active in what community IronRuby has since the absence of Microsoft will create space for people like me, on the outside. I will probably return to the drawing board with a few projects and ideas in IronPython but Bruce Tate’s latest book has inspired me to think that perhaps trying to tackle multiple languages at the same time isn’t so outlandish a goal after all. The important thing I’m going to try to bring with me is the frame of mind I quoted above from Winer: being unable to imagine that IronRuby can go away or lose value as an idea or a platform. 

}

Thursday, July 29, 2010

Management Perspectives from a Groundling and Dan Pink

{

Over the weekend I took the time to watch Stan Lee’s Mutants, Monsters and Marvels, a film that consists entirely of an interview between film maker Kevin Smith and Stan Lee. As a kid who grew up loving comics, I loved the unveiling of the world behind the worlds I spent as much time as I could with my imagination: Spiderman, Fantastic Four, Hulk, Iron Man, and the list goes on though I’ll stop before daunting anyone without appreciation for such comic book geekdome.

One of the interesting segments dealt with Stan Lee’s approach as the top editor at Marvel. Although the characters we are familiar with are his creations and he would collaborate with artists on the first few releases of books, subsequently other teams of artists and writers would work on their own releases of the characters he created. When Kevin asked how he managed this he waved his hand and said that he found the best way to manage creatives was to leave them alone: that’s how you would get their best work.

Stan Lee seems to be a man of intuition (in the interview he’s matter of fact and terse, less a man of “Big Ideas” and more of “Common Sense” when it comes to managing) but I think he was getting at the management theory that is being articulating these days by Dan Pink. Pink’s ideas have to do with the connection of motivation and better outcomes that are concomitant with employee autonomy. A summary of his ideas as well as their rational basis is in this entertaining animated video from RSA:

Although I do not have any formal disagreements with Pink’s ideas (they are spot on in my book) I think what is telling is his background and where he worked. Some top notch schools and the upper echelons of government imbue a sense of personal worth and require the freedom and tactics he recommends. The same is true with Stan Lee: his management style worked precisely because of the environment he was in and the nature of his work; in comics being creative and motivated as well as finding ways to help your employees in that regard are the name of the game.

What I would add, from the groundling floor, is that in many places it’s not that these theories don’t make sense or aren’t highly empirical (Pink glosses over some behavioral economics although if you really want to dive into the field Dan Ariely is a better start); it’s that different organizations have different goals. As much of a thought bludgeon as it is, the haunting truth is that some places are perfectly happy trading out creativity, autonomy, and the requisite unpredictability associated with them.

}

Tuesday, July 27, 2010

XAML Iconography

{

I have been having a lot of fun lately using Adobe Illustrator and symbol icons to build icons in XAML. Although the typical icon libraries provide very compact image files, the advantage of XAML comes not just in space, but in the ability to manipulate the graphic that you are leveraging.

Here is a brief example of what I mean:

1. There is no shortage of good symbol fonts (or fonts in general, for that matter). I have bought fonts at both MyFonts.com and Fonts.com and had great experiences. The symbol font I will use in this case is Energetics.

Energetics_Font

2. In Illustrator, I create a document and insert the character of choice making it large enough that it will be easily visible when I import it to Blend.

Illustrator1

3. Using the File –> Import option from Blend, I have two Adobe related options; in this case we obviously leverage the Import Adobe Illustrator option

Blend1

4. Voila! We now have our same symbol in Blend but digging in it’s a XAML Path rather than an image. Although it has been imported, however, you will notice a few extra pieces of XAML that you don’t need holding the Path as its container. I usually copy the Path, delete the extras and then paste it back in.

Blend3

Now that the symbol is in XAML, not only is it not taking up the kind of space that the original image would have, it is also easier to work with if you need to manipulate it programmatically.  Here’s my weight lifter in XAML:

<Path Data="F1M562.59375,264.9375C562.59375,283.96875,560.390625,301.390625,556.015625,317.234375C551.625,
333.078125,546.125,345.03125,539.53125,353.125L510.140625,353.125C503.296875,344.578125,497.703125,332.296875,
493.375,316.296875C489.046875,300.296875,486.890625,281.96875,486.890625,261.34375L480.5625,261.34375C475.65625,
264.09375,468.9375,269.5,460.40625,277.578125C460.515625,285.671875,459.921875,299.328125,458.609375,
318.515625C457.296875,337.71875,456.359375,350.90625,455.796875,358.078125C455.671875,359.796875,454.359375,
360.640625,451.859375,360.640625C449.34375,360.640625,448.09375,359.796875,448.09375,358.078125C443.765625,
358.984375,439.578125,359.703125,435.53125,360.21875C431.484375,360.734375,425.78125,360.9375,418.4375,360.8125C411.09375,
360.703125,404.0625,359.9375,397.34375,358.5C390.625,357.078125,383.71875,354.59375,376.65625,351.0625C374.609375,357.5625,
372.46875,362.953125,370.25,367.21875C368.03125,371.5,364.578125,377.734375,359.921875,385.9375C367.328125,390.953125,
372.671875,395.703125,375.984375,400.203125C379.28125,404.703125,380.9375,410.03125,380.9375,416.1875C380.9375,424.15625,
378.453125,431.109375,373.5,437.03125C368.53125,442.96875,362.46875,447.296875,355.296875,450.015625C357.109375,456.84375,
358.96875,465.703125,360.84375,476.59375C362.71875,487.46875,364.171875,497.328125,365.203125,506.15625C366.234375,514.984375,
366.796875,521.109375,366.921875,524.53125L335.140625,524.53125C330.234375,524.53125,329.140625,522.078125,331.890625,
517.1875C332.796875,515.6875,332.21875,513.015625,330.171875,509.15625C323.453125,496.390625,312.109375,481.46875,296.171875,
464.375C295.25,463.34375,293.90625,461.84375,292.140625,459.84375C290.375,457.84375,289.09375,456.375,288.296875,455.40625C287.5,
454.4375,286.875,453.734375,286.421875,453.265625L274.8125,455.3125L289.84375,511.375C290.640625,514.09375,289.15625,517.578125,
285.40625,521.796875L250.375,521.796875L250.71875,517.53125L264.390625,504.015625L211.578125,456.34375C210.09375,454.984375,
207.390625,452.5625,203.453125,449.078125C199.515625,445.609375,196.671875,442.8125,194.90625,440.703125C193.140625,438.609375,
191.859375,436.5,191.0625,434.390625C190.265625,432.28125,189.875,429.796875,189.875,426.953125C189.875,421.375,192.28125,
415.828125,197.125,410.296875C201.96875,404.765625,209.828125,400.015625,220.71875,396.015625C231.59375,392.03125,245.578125,
389.984375,262.671875,389.859375L239.78125,350.390625C231.90625,355.984375,222.671875,359.875,212.078125,362.09375C201.484375,
364.3125,191,364.234375,180.640625,361.828125C178.015625,351.578125,176.109375,342.59375,174.921875,334.84375C173.71875,327.09375,
172.859375,319.609375,172.34375,312.359375C171.828125,305.125,171.34375,295.578125,170.90625,283.734375L151.25,272.28125L140.140625,
272.625C140.140625,313.75,132.78125,343.71875,118.09375,362.515625L90.0625,362.515625C85.84375,357.28125,82.09375,350.5625,78.78125,
342.359375C75.46875,334.15625,72.859375,324.578125,70.921875,313.640625C68.984375,302.703125,68.015625,291.03125,68.015625,
278.609375C68.015625,259.921875,70.125,242.890625,74.34375,227.515625C78.5625,212.140625,83.796875,201.140625,90.0625,
194.53125L118.09375,194.53125C121.84375,198.75,125.234375,204.359375,128.265625,211.359375C131.28125,218.375,133.78125,226.5,
135.78125,235.71875C137.765625,244.9375,139.109375,255.25,139.796875,266.640625L148.171875,266.640625C148.625,264.703125,149.5,
263.234375,150.8125,262.203125C152.125,261.171875,153.6875,260.859375,155.515625,261.265625C157.328125,261.671875,158.984375,
262.890625,160.484375,264.9375C163.890625,259.59375,167.828125,259.359375,172.265625,264.25C172.953125,262.3125,174.375,261.0625,
176.53125,260.5C178.6875,259.9375,180.578125,260.4375,182.1875,262.03125C183.65625,260.4375,185.34375,259.84375,187.21875,
260.234375C189.09375,260.640625,189.984375,262.3125,189.875,265.28125L271.390625,262.375C271.046875,252.921875,271.6875,244.75,
273.34375,237.859375C275,230.96875,277.9375,224.734375,282.15625,219.140625L314.796875,217.9375L322.484375,260.65625L448.4375,
256.5625C449.6875,253.9375,451.625,252.34375,454.25,251.78125C456.875,251.21875,458.921875,252.40625,460.40625,255.359375C462,
253.3125,463.875,251.96875,466.046875,251.34375C468.203125,250.71875,470.375,251.5,472.53125,253.65625C475.265625,249.5625,
478.578125,248.875,482.453125,251.609375C484.5,250.359375,486.09375,249.890625,487.234375,250.234375C488.03125,235.09375,
490.5625,220.578125,494.84375,206.671875C499.109375,192.765625,504.203125,182.796875,510.140625,176.75L539.53125,
176.75C542.828125,180.28125,545.90625,185.046875,548.75,191.03125C551.59375,197.015625,554.078125,203.90625,556.1875,
211.703125C558.296875,219.515625,559.890625,227.90625,560.96875,236.90625C562.046875,245.90625,562.59375,255.25,562.59375,
264.9375L562.59375,264.9375 M535.9375,182.734375L512.875,182.734375C508.765625,187.75,505.140625,194.59375,502.015625,
203.25C498.875,211.90625,496.515625,221.9375,494.921875,233.3125L518.171875,233.3125C519.640625,222.15625,521.953125,
212.203125,525.078125,203.421875C528.203125,194.640625,531.828125,187.75,535.9375,182.734375L535.9375,182.734375 M447.75,
262.375L364.015625,265.28125C371.875,268.25,378.484375,271.78125,383.84375,275.875C389.1875,279.984375,393.8125,286.25,
397.6875,294.671875C404.859375,292.859375,411.515625,292.375,417.671875,293.21875C423.828125,294.078125,429.40625,297.234375,
434.421875,302.703125L447.75,262.375 M312.234375,237.59375L309.84375,223.921875L285.40625,224.9375C280.84375,231.671875,
278.28125,239.765625,277.71875,249.21875C279.65625,253.09375,284.03125,255.015625,290.875,255.015625C295.421875,255.015625,
300,253.578125,304.625,250.671875C309.234375,247.765625,311.765625,243.40625,312.234375,237.59375L312.234375,237.59375 M375.296875,
299.625C375.296875,292.109375,371.421875,286.296875,363.671875,282.203125C355.921875,278.109375,344.75,276.046875,330.171875,
276.046875C317.1875,276.046875,307.5,277.359375,301.125,279.96875C292.8125,277.8125,286.03125,276.734375,280.796875,
276.734375C271.453125,276.734375,262.59375,278.390625,254.21875,281.6875C245.84375,285,239.203125,289.1875,234.296875,
294.25C229.390625,299.3125,226.953125,304.125,226.953125,308.6875C226.953125,313.46875,229.453125,317.296875,234.46875,
320.140625C239.484375,322.984375,244.671875,324.40625,250.03125,324.40625C257.203125,324.40625,264.953125,322.984375,
273.265625,320.140625C281.578125,317.296875,288.1875,313.921875,293.09375,310.046875C298.671875,313.359375,305.671875,
316.125,314.109375,318.34375C322.546875,320.5625,330.921875,321.671875,339.234375,321.671875C348.921875,321.671875,357.34375,
319.578125,364.53125,315.359375C371.703125,311.140625,375.296875,305.90625,375.296875,299.625L375.296875,299.625 M328.125,
340.125C328.125,337.40625,325.125,334.921875,319.15625,332.703125C313.171875,330.484375,305.625,329.359375,296.515625,
329.359375C287.859375,329.359375,280.328125,330.625,273.953125,333.125C267.578125,335.640625,264.390625,338.203125,264.390625,
340.8125C264.390625,344.921875,271.390625,347.140625,285.40625,347.484375C273.21875,351.921875,267.125,356.59375,267.125,
361.5C267.125,363.09375,268.25,364.328125,270.53125,365.171875C272.8125,366.03125,276.03125,366.65625,280.1875,367.046875C284.34375,
367.453125,287.78125,367.703125,290.53125,367.8125C284.03125,371.234375,280.796875,374.375,280.796875,377.21875C280.796875,379.15625,
282.8125,380.875,286.859375,382.34375C290.890625,383.828125,294.96875,384.5625,299.078125,384.5625C303.390625,384.5625,
307.71875,383.765625,312.0625,382.171875C316.390625,380.578125,318.5625,378.59375,318.5625,376.1875C318.5625,373.90625,317.671875,
372.265625,315.90625,371.234375C314.140625,370.21875,311.09375,369.1875,306.765625,368.15625C320.203125,364.96875,326.9375,361.5,
326.9375,357.734375C326.9375,355.578125,325.671875,353.71875,323.171875,352.1875C320.65625,350.65625,317.40625,349.3125,313.4375,
348.15625C323.21875,346.453125,328.125,343.78125,328.125,340.125L328.125,340.125 M259.078125,268.6875L189.015625,271.265625L187.65625,
275.359375L192.609375,312.109375C198.296875,306.640625,205.3125,303.625,213.625,303.046875C216.921875,297.8125,220.703125,
293.140625,224.984375,289.03125C229.265625,284.9375,234.359375,281.09375,240.28125,277.5C246.203125,273.90625,252.46875,270.96875,
259.078125,268.6875L259.078125,268.6875 M112.453125,200.5L92.796875,200.5C84.703125,210.53125,79.125,226.03125,76.046875,
246.984375L95.703125,246.984375C98.78125,226.03125,104.359375,210.53125,112.453125,200.5L112.453125,200.5 M360.59375,518.71875C360.25,
512.109375,358.546875,499.4375,355.46875,480.6875C352.390625,461.9375,348.296875,444.921875,343.171875,429.59375C338.046875,
414.28125,332.28125,406.609375,325.90625,406.609375C315.765625,406.609375,306.53125,410.09375,298.21875,417.03125C289.90625,
423.984375,285.75,430.9375,285.75,437.890625C285.75,440.734375,286.765625,443.5,288.8125,446.171875C290.859375,448.859375,295.53125,
454.203125,302.828125,462.234375C310.109375,470.265625,316.328125,477.546875,321.453125,484.109375C326.578125,490.65625,331.265625,
498.09375,335.484375,506.421875C337.1875,509.484375,338.1875,511.796875,338.46875,513.328125C338.75,514.859375,338.4375,516.65625,
337.53125,518.71875L360.59375,518.71875" Stretch="Fill" Margin="57,81,0,0" UseLayoutRounding="False" HorizontalAlignment="Left"
Height="131.781" VerticalAlignment="Top" Width="187.405">
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF2D2D2D" Offset="0"/>
<GradientStop Color="#FF3D3C3C" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
</Path>


 



}

Saturday, July 24, 2010

Excel Interop in C# .NET without COM

{

Tonight I ran across the excellent albeit unimaginatively called excellibrary project on Google Code and leveraged it in one of my personal projects. It’s nice to be able to get the Excel file format without having to do it in either CSV or with COM Interop.

Reference: Stackoverflow Question / Answer

}

Thursday, July 22, 2010

TortoiseSVN Extensions Missing on Windows 7

{

Ran into this issue recently after upgrading my TortoiseSVN shell extensions. To fix, simply run the installer again using the Repair option.

Reference: StackOverflow Question / Answer.

}

Tuesday, December 15, 2009

Keep Your Head Up

{

From an old Raganwald interview, I derived some inspiration this morning:

“Quite often we see something and we're very tempted to say "oh! this is a special case of a more general thing." and then we solve the general thing. However that is an infinite recursion: it's always a special case of a something more general and if you're always climbing up the tree on to the more general thing you'll eventually wind up with a PhD in computer science... and no code.

However, on the other hand, if we just scrabble along the earth and we never, sort of, poke our head up and look around to see the more general thing we are constantly re-solving the same problems, you're not even recognizing that two different things we solve are both aspects of same thing. So what I try to do is I always try to recognize what that general case is, and then discipline myself not to solve the general case until it's really an imperative but not to be ignorant of the general case.”

On the continuum of thinking in general, more theoretical terms and the more practical nuts and bolts, I’ll admit I err too often on being practical.

I’ve been in the trenches a lot of late so this is a good quote to meditate upon. Especially in a week like this: at the end of an iteration, being asked to “work overtime” to try to get things done and out to customers, it’s very easy to stay in scrabble mode rather than having the disciplines of study and analysis that keep the general case in mind.

}

Saturday, December 05, 2009

Library of the Week: SharpZipLib with Silverlight

{

SharpZipLib has been around in various forms for some time but via this port to Silverlight we have the benefit of leveraging it for compression and decompression in our Silverlight based web applications. Doing a search on sample code gives back a lot of examples (the best of which, IMHO, is from The Codecruncher) of how to use the library but there’s an important difference when it’s used in the Silverlight space: many members of the FileStream are marked as SECURITY CRITICAL and are therefore out of reach in your application. A very simple technique to get around this is to convert the target stream object to a MemoryStream and proceed from there. A series of examples are below, written in simpe form for brevity (reading a file in a single step to a large byte array is a taste thing; of course I’m aware you can read chunks of the file) Here’s a little sample of getting that done:

public MemoryStream GetFileData(FileStream fs) 
{
fs.Seek(0, SeekOrigin.Begin);
byte[] data = new byte[fs.Length];
fs.Read(data, 0, (int)fs.Length);
MemoryStream ms = new MemoryStream(data);
return ms;
}




Here are examples of listing, extracting, and compressing files, respectively:






//open a file dialog, pick a zip and list contents
List entries = new List();
OpenFileDialog ofd = new OpenFileDialog();
if (true == ofd.ShowDialog())
{

using(FileStream fs = ofd.File.OpenRead())
{
ZipFile zip = new ZipFile(GetFileData(fs));
foreach (ZipEntry entry in zip)
{
entries.Add(entry.Name);
}
zipFileListBox.ItemsSource = entries.ToArray();
}








//open a file dialog, pick a *.zip and extract to isolated storage
OpenFileDialog ofd = new OpenFileDialog();
if (true == ofd.ShowDialog())
{
string fiName = ofd.File.Name;
ZipEntry entry;
using(ZipInputStream zis = new ZipInputStream(GetFileData(ofd.File.OpenRead())))
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
string folderForOutput = System.IO.Path.GetFileNameWithoutExtension(ofd.File.Name);
if (!isf.DirectoryExists(folderForOutput)) {
isf.CreateDirectory(folderForOutput);
}

while ((entry = zis.GetNextEntry()) != null)
{
if (isf.FileExists(entry.Name))
{
isf.DeleteFile(entry.Name);
}
long sizeToWrite = entry.Size;
using (FileStream fs = isf.CreateFile(folderForOutput + "/" + entry.Name))
using(StreamWriter sw = new StreamWriter(fs))
{
byte[] data = new byte[sizeToWrite];
int bytesRead = zis.Read(data, 0, data.Length);
if (bytesRead > 0)
{
sw.Write(data);
}
}
}
}
}








//open a file dialog, pick some files and create a *.zip
OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = true;
if (true == ofd.ShowDialog())
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (FileStream fs = isf.CreateFile("TheZip.zip"))
using (ZipOutputStream zipOut = new ZipOutputStream(fs))
{
foreach (FileInfo selectedFile in ofd.Files) {
byte[] fileData = new byte[selectedFile.Length];
using (FileStream selectedFileStream = selectedFile.OpenRead()) {
selectedFileStream.Read(fileData, 0, fileData.Length);
ZipEntry entry = new ZipEntry(selectedFile.Name);
entry.DateTime = DateTime.Now;
entry.Size = selectedFile.Length;
zipOut.PutNextEntry(entry);
zipOut.Write(fileData, 0, fileData.Length);
}
}
zipOut.Finish();
}
}
}




It must be noted that SharpZipLib is GPL but because of a special clause in the license, you can use it in a “closed source” application as Jon Galloway explains here.



}

Wednesday, November 18, 2009

Windows 7 In the House

{

Just  a quick test from Windows 7.

}

Tuesday, October 27, 2009

Library of the Week: Silverlight’s MD5 implementation

{

While there are a slew of cryptographic hashing algorithms a programmer finds at their disposal, and despite the documented vulnerabilities accompanying it, MD5 remains a popular approach to generating hashes. Hashes, as you know, are useful for a variety of things – verifying file integrity and password storage being just a few.

I discovered the Silverlight MD5 implementation because a project I work on leveraged MD5 for file integrity. I was a bit curious about this since it’s long been a recommendation to skip MD5 and use hashing algorithms like SHA-1 and SHA-2 which are proven to be more robust. It’s not just the predecessor of my project, many places still use MD5 despite the bad rap it takes. I posted on SuperUser and got some interesting answers, the most notable of which (I marked as the answer) detailed how MD5 is faster than SHA-1. Other comments can be summarized with this excerpt of an answer that wwas most highly upvoted:

“A MD5 hash is "good enough" for most menial tasks. Recall that it's still incredibly difficult to produce meaningful collisions in the same number of bytes.”

Silverlight’s core assemblies do not support MD5 but a person named Reid Borsuk at Microsoft created an implementation that is robust and easy to use. Because the code is hosted on MSDN Code Gallery you will need to put it into a project on your own but it’s not that hard. Here are some simple steps:

1. Create a Silverlight Library project

2. Download the MD5.cs and MD5Managed.cs (you can also download the MD5Test.cs if you’re interested in unit testing it)

3. Add both files to your Silverlight Library project.

4. Compile and you’re done!

If' that’s not straightforward enough, I’ve created a downloadable Visual Studio 2008 solution with the library, a Silverlight Application and a Web application to show it in action. Here is the code behind generating a hash from a file stream in a button’s click event:

 
private void cryptoButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (true == ofd.ShowDialog()) {
using (FileStream fs = ofd.File.OpenRead())
{
MD5Managed md5 = new MD5Managed();
byte[] hash = md5.ComputeHash(fs);

fs.Close();
}
}
}


Thanks a lot Reid!



}

Tuesday, October 20, 2009

Library Of The Week: Simple Styles for Silverlight

{

I’ll admit I have a Man Crush on Robbie Ingebretsen that began when I discovered his work at MIX earlier this year. To expound a bit: Microsoft has worked hard to try to draw a line in the sand between “developer” and “designer” – a line I always had a visceral dislike for because it’s always been people like Robbie Ingebretsen who I’ve always tried to pattern myself after: people who can write code AND produce beautiful designs.

One of the more difficult things I’ve encountered in Silverlight is dealing with control templates. Even something as simple as a button, when opened in Blend, involves quite a few different moving parts so that changing behavior doesn’t always produce a desired effect. For example: changing the background of the button at some given visual state will not affect the button unless you take into account a predefined background gradient that is a part of it.

The Simple Styles samples are stripped down, intuitive versions of the control templates with a concise starting point for anyone working to customize their behavior. To go back to the previous example, changing the background of a button involves changing the BackgroundElement. Rather than changing individual gradient stops in a Visual State, simple modify the entire element related to that Visual State.

Default Button Template Simple Button
102 lines of XAML 38 lines of XAML

The button is a starting point for simple conversations but there are controls like the listbox which can be deceptively unwieldy in how they are managed1.

The structure of the Simple Styles is also beautiful – not simply a resource dictionary with everything crammed together but a separate file for each control, a gesture one would think was straightforward until you see the many examples of Silverlight styles coming from Blend generated files.  

I mentioned previously that I think that the antidote to the “blank slate” of RIA is good precedent and patterns developers and designers turn to when they build things. I think Simple Styles are a step in that direction; what I wouldn’t give to look through Robbie’s resource dictionaries. How about it Robbie?

}

Thursday, October 08, 2009

Library Of The Week: ImageTools

{

I’m not exactly sure of the reasoning, but Silverlight does not have support for either GIF or BMP file formats. This is to say that if you use the Image control, you will be unsuccessful setting the source property to a GIF/BMP file. It’s heresay from nearly a year ago but a member of the Silverlight team, Ashish Thapliyal, posted on (his|her) blog the following:

“We don’t want to take the hit for another codec. It may only be a little bit of download time—but our mandate is small and fast and every little bit counts. We are also hesitant to support .gif because it implies support for animated .gif, which we decided would have to be integrated into our animation scheme somehow—and that will be a lot of work.

Looking from Flash perspective, Flash does not support .gif either. However, as of present, this is something being evaluated, but no date has been announced.”

Initially it was this roadblock that led me down the path to ImageTools. ImageTools is a project that provides Silverlight with good support for GIF and BMP amongst other formats, complete with its own Image control that allows a user to preview either format. It’s been a lifesaver for me on my current project since we have a requirement for preview capability with both.

ImageTools is more than just support for those antiquated formats. Once you’ve downloaded the latest release you’ll see there are a series of demos to look at:

Animation
This project shows how easy it is to load an image using the AnimatedImage type. All the sample files are GIF format.

Colors
This project shows the ability to apply brightness and contrast to images on the fly using the ImageTools.Image type.

Dialog
Asynchronously loading an image file using ImageTools.Image with IsLoadingSynchronously flag.

Editor
Shows the ImageEditorContainer control and some editing features

Flip
Shows the ImageTools.Image.Transform method which supplies not just the ability to rotate, but also to “flip” the pixels within an image either on the X or Y axis (horizontally or vertically)

Loading
I’m not completely sure why this is called “loading” because there’s a lot more going on here: the AnimatedImage control is on display with the ability to apply filters to images that are loaded. The examples given are  Sepia, Inverter, and GrayscaleBT709.  The IImageFilter interface allows an extensible way to define filters, look into the ImageTools.Filtering library to see the interface and other filters available.

Resizing
Shows dynamic resizing of an existing image (returns an Image object with resized Image type)

SaveCanvas
Pretty sick; this handy extension method can return an Image object representing any canvas.

As you can see, my simple problem of needing support for more image formats resulted in finding a library that went the distance in giving a developer flexibility with image manipulation. One more thing, I love the dependency injected goodness of how the library works. Here’s a little snippet of code to give you an idea of how well designed (extensible!) the library is:

1. Add a reference to ImageTools, ImageTools.IO.Bmp, ImageTools.IO.Gif

2. Here is code to load the files – notice the Decoders.AddDecoder takes the generic type parameter to dynamically support the desired file format which means you need only reference the format specific libraries that you need:

    public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
// add decoders
Decoders.AddDecoder<BmpDecoder>();
Decoders.AddDecoder<GifDecoder>();

}

private void Button_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == true)
{
// because decoders are taken care of,
// load images as needed!

ImageTools.Image i = new ImageTools.Image();
using(FileStream fs = ofd.File.OpenRead()){
// note: myImage is ImageTools.Controls.AnimatedImage
i.SetSource(fs);
myImage.Source = i;

}
}

}
}




It's a bummer when support for things, like well known file formats like GIF are not supported via a more arbitrary decision making process but the consolation is that it’s an opportunity for people make up for it in the community. ImageTools is a great library, every Silverlight developer should check it out.



}

Sunday, September 27, 2009

Library Of The Week: Json.NET

{

In the Christian Bible there’s a story of 10 lepers miraculously healed by Jesus. Even if you don’t believe in Christianity, imagine a leper living in the dregs of society, totally dejected until one day a man shows up and heals him and nine other fellow outcasts. Imagine how happy they should be.

They’d say thank you, right?

In the Bible story, only one of the men returns to say thank you and the other nine are so busy getting back to the lives they wished they had that they forget about the reason they were healed in the first place.

There’s evidence of this kind of lack of gratitude in the ecosystem of free libraries and projects available for .NET developers on the web. I’m a part of that club and not proud of it. I use open source .NET libraries on a regular basis and don’t say thank you. But more than just me, I look at the community participation on CodePlex projects and find it amazing how few people say a simple “thank you.”

With that in mind, I’m going to start profiling libraries that I’ve used with success to build up awareness of their existence and hopefully inspire the people who write them to do more good work since what they do is so tremendously helpful.

The first library I want to profile is the Json.NET library available from CodePlex. It contains a great, intuitive Json serialization/deserialization library. You can point to most serializable objects and convert them to a JSON format with such simple sleight of hand as:

	List<Foo> data = new List<Foo>();
// adds to data
string json = JsonConvert.Serialize(data);




As if that wasn’t simple, retrieving values from their serialized format is also made trivial:





	string jsonItems = GetYourJSON();
List<Foo> data = JsonConvert.DeserializeObject<List<Foo>>(jsonItems);




One great differentiator of Silverlight versus existing web technologies is the ability to have a virtual file system on a client computer. While HTML 5 seems to include facilities for this it is not yet built into existing browsers and even when it is, previous track records on “standards” are a precedent for how balkanized the implementation of them can be. In many areas of web development, you can push the envelope of existing technologies to get what you do out of Silverlight, but the existence of Isolated Storage is a killer feature.



Give Json.NET a try whether you’re doing Silverlight or using a different .NET related paradigm. It’s a great library.



}

Sunday, September 20, 2009

Exception HOF Pattern in C#

{

There’s probably a name for this specific approach but in a personal project of late I’ve found a useful pattern for generalizing my exception handling. I write a ExceptionHelper class that takes a variety of high order function style methods to handle my exceptions in a single spot. Here is a somewhat simple form of what I've been doing:

    public class ExceptionHelper
{

public static void ExecuteWithSuppress(Action code)
{
try
{
code();
}
catch (Exception ex)
{
// pass and ignore the exception
}
}

public static void ExecuteWithHandler(Action code)
{
try
{
code();
}
catch (Exception ex)
{
Console.WriteLine("An exception occured! Details: \n" + ex.ToString());
}
}

public static void ExecuteWithHandler(Action code, string errorMessage)
{
try
{
code();
}
catch (Exception ex)
{
Console.WriteLine((errorMessage.Length > 0) ? errorMessage : ex.ToString());
}
}

public static void ExecuteWithHandler(Action code, Action onError)
{
try
{
code();
}
catch (Exception ex)
{
if (onError != null)
{
onError();
}
}
}

public static void ExecuteWithHandler(Action code, Action onError, string errorMessage)
{
try
{
code();
}
catch (Exception ex)
{
Console.WriteLine((errorMessage.Length > 0) ? errorMessage : ex.ToString());
if (onError != null)
{
onError();
}
}
}

public static bool ExecuteWithNotificationButIgnore(Action code)
{
bool ret = true;
try
{
code();
}
catch (Exception ex)
{
ret = false;
}
return ret;
}

public static void ExecuteWithLogging<T>(Action code) {
try
{
code();
}
catch (Exception ex)
{
if (ex is T) {
Console.WriteLine("Logging exception " + ex.ToString());
}
}
}

public static void ExecuteWithLogging(Action code, Action<Exception> handles) {
try
{
code();
}
catch (Exception ex)
{
handles(ex);
}
}

}


At this point I use it in a lot of places, here are a few scenarios:



ExecuteWithSuppress(Action code) – code that has a low impact of failure or an expected failure under some conditions. For example, a client of mine once had a legacy database they wanted to me parse a “name” field from. We set up basic heuristics to separate out first and last and so on, but on failure we just returned a blank string.



ExecuteWithHandler(Action code) – you have some generalized exception handling to do something: prompt the user, do logging, etc. ExecuteWithHandler(Action code, Action handler) – you get to pass in the exception handling you want


ExecuteWithHandler(Action code, string errorMessage) – pass a custom error message


ExecuteWithNotificationButIngore(Action code) – try to execute some code but return a boolean to indicate success


ExecuteWithLogging<T>(Action code) – run some code, indicate the types of exceptions to differentiate


ExecuteWithLogging(Action code, Action<Exception> handles) – pass a method to catch be passed the exception that occurs.




The resulting code I write with this pattern, I find pleasant. Here are some examples:



    string userName = String.Empty;
ErrorHelper.ExecuteWithSuppress(() => userName = doc.Descendants("Name").First().Value);
return userName;


if (ErrorHelper.ExecuteWithNotificationButIgnore(() =>
{
SendEmail();
}
else
{
// message not delivered, etc, etc.
}


I want it to be absolutely clear that this is not a replacement for try/catch/finally logic where it is warranted. It is simply an alternative that can help to keep code clear and readable. As with many things in software, there is taste involved in when and where something like this is leveraged. But it works well enough for me that I thought I’d share.



}

Saturday, September 19, 2009

FizzBuzz Functional

{

I’ve been reading Tomas Petricek and John Skeet’s Functional Programming for the Real World. I’m hoping I can, as Steve McConnel says, program into1 my C# projects some elements of functional problem solving. As I was working to grok the beginning portions of the book I thought I’d rewrite FizzBuzz since I’ve aleady posted a few versions of a solution. Here is my solution:

Func<int, int[], bool> isMultiple = (n, n2) => n2.Any(m => n % m == 0);
Func<int, int, string, string> fb = (n, n2, s) => (n % n2 == 0) ? s : String.Empty;


foreach(var i in Enumerable
.Range(1, 100)
.Select(n =>(isMultiple(n, new int[]{3,5}))
?fb(n, 3, "Fizz") + fb(n, 5, "Buzz")
:fb(n, n, n.ToString())
)Console.WriteLine(i);


Another version, using ForEach on a List<T>:



Func<int, int[], bool> isMultiple = (n, n2) => n2.Any(m => n % m == 0);
Func<int, int, string, string> fb = (n, n2, s) => (n % n2 == 0) ? s : String.Empty;

Enumerable
.Range(1, 100)
.Select(n => (isMultiple(n, new int[] { 3, 5 }))
? fb(n, 3, "Fizz") + fb(n, 5, "Buzz")
: fb(n, n, n.ToString()))
.ToList()
.ForEach(num => Console.WriteLine(num));


I'm just starting to wade into using F# but I'm hoping to start building my proficiency the further I get into the book



1"Don't limit your programming thinking only to the concepts that are supported automatically by your language. The best programmers think of what they want to do, and then they assess how to accomplish their objectives with the programming tools at their disposal." – Steve McConnell, Code Complete 2nd Edition



}

UI Inspiration for Silverlight’s Blank Slate

{

I’ll admit that I spent an inordinate amount of time last week thinking about dialog boxes. Silvelright’s canned prompt comes courtesy of a call to MessageBox.Show which displays the browser’s native modal dialog. I think you get the same thing from HtmlPage.Window.Alert too. Needless to say, these should leave you wanting.

A good place to start, rather than wasting the better part of a day playing around like me, is to begin with a really good convention rather than making something “original.”

So without further ado, I’m linking to a nice PSD courtesy of teehan+lax that contains visual styles for many of the iPhone’s UI Elements. I’ll have to build a nice workflow to get things like this into XAML.

 

One more philosophical note (noted below so that if you just needed the link you won’t be daunted by my long windedness) – almost 100 episodes ago the Hanselminutes podcast featured Scott interviewing David Heinemeier Hansson and Martin Fowler at RailsConf 2007. When talking about UI design and originality here is what DHH had to say:

“I think the low level of
expressiveness that we have in HTML and CSS
and JavaScript is actually a huge boon to most
applications that constraints are a good thing,
that constraints leads to better applications when
we don’t need to reinvent everything
. When you
just have blank canvas where you can paint
whatever you want on it, you pretty much end up
with something “original” every time; and I don’t
think originality in UI design is necessarily a good
thing; I just think actually most of the time it's a
bad thing.”

I agree with DHH on this point. It’s worth listening to the entire podcast to put some context to his comments. Where my opinion veers from his or at least my hope for Silverlight is that conventions more powerful than those of HTML/CSS/JavaScript begin to come together for developers and they spend less time thinking about a blank slate and more about how their application works with the benefit of a better experience. Themes are a good step in this direction but things like dialogs go beyond to interactions as opposed to just colors and gradients.

}

Thursday, July 16, 2009

Why IE6 Continues To Ruin My Life

{

Via a good friend, this post confirms that many of us are in the same situation: corporate IT people force users to stay in IE6 which forces, in turn, all of us developers to suffer by having to support it. The post, written from an inside Digg perspective doesn't tell the whole story so I’d like to add one dimension. Many corporate environments are in this unfortunate cycle based on the inability to project abstract costs, that is to say that often (always?) software is rushed through and “finished” in an agile, YAGNI kind of way, and after the fact managers1 have a hard time capturing the costs it takes to support legacy browsers because of “finished” software. The two development efforts are seen as separate, so the extra time in new development doesn’t factor into the decision to keep what is old.

Cheers for Virtual PC and the ability to test things out without having it installed locally but nevertheless I’d like to force everyone to upgrade and forget that browser ever existed.

Side note, if you are fortunate enough to force an upgrade, here is some help.

1I’m sure special kinds of managers are able to guess this in and make good decisions but they are a rare breed and the elixir they drink is hard to find.

}

Wednesday, May 06, 2009

Proper 0.2: INotify, DependencyProperty Support

{

Several years ago, in a land of Visual Studio 2005 and no CodeRush, I made a tool called Proper to automate the monotony of creating properties. You just type something like “int Foo;string Bar;” and you’d get basic property generation. You can use shortcuts to types by typing an undercore “_” character. For example, “i_” will pop up int, “dt_” would pop up DateTime (You can also create your own). It’s funny how the stuff that you’re half serious about can last so long – at the time I wanted to write something useful entirely in JavaScript and to experiment a little with JQuery.

The tool suffered neglect for the next few years until recently when I began working with Silverlight and was amazed at how a similar monotony (and more code!) accompanies using INotifyPropertyChanged and implementing dependency properties. I remembered my old tool and added support for generating them there. Here are some screenshots that should illustrate how it works (you select “advanced options” and then select a few checkboxes, in a nutshell). I’ll update the feature to report bugs – I’m sure there are a few. I also neglected to update it for VB.NET – I’ll do that over the next few weeks.

If you do spot a bug, let me know. There are a few new goals I have with the tool, the first of which is refactoring some of the embarrassing JavaScript I crufted together to make this work. I remember Kevin Dangoor talking about Embarrassment Driven Development (when your code is so embarrassing that you’re motivated to update it); that’s the one thing about JavaScript – you can’t hide the way things are constructed. :)

}

Friday, April 24, 2009

Using IronPython For Converters in Silverlight

{

 

Tim Heuer has a great intro post on Silverlight data binding and value converters. The concept is a really nice one but I’m not wild about having to write a class that implements the IValueConverter interface every time I need some ad-hoc tweaking of the values I get from being data bound and how I’d like to use them within XAML. What set me off this track was a case where I simply needed to invert a boolean – what should just be “not myvalue” ended up requiring a class, an interface, and so on.

Dynamic languages excel at this sort of thing and since they support the ability to evaluate code on the fly I thought it would make sense to write a single implementation of IValueConverter and host Python inside of it to evaluate binding expressions that are passed in. Here is what that might look like:

public class PythonExpConverter : IValueConverter
{
private ScriptEngine _engine;

public PythonExpConverter()
{

ScriptRuntimeSetup setup = Python.CreateRuntimeSetup(null);
setup.DebugMode = true;
var runtime = new ScriptRuntime(setup);
_engine = Python.GetEngine(runtime);

}

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
object result;
string python = parameter.ToString()
.Replace("value", value.ToString());
try
{
result = _engine.Execute(python);
}
catch (Exception ex)
{
// pass, just use original value
result = value;
}
return result;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// same concept as above
return value;
}
}


No magic, just instantiate the Python runtime and then proceed to leverage it in the Convert phase by taking a string as the parameter for the conversion method. Use value as a keyword in your Python expression to get at the value of the underlying data.  Once this is added as a static resource, you can leverage it in many ways. For example, if I had a class “Person”:



public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool OnVacation { get; set; }
public double Balance { get; set; }
}


Let’s say I’m binding to an instance of Person (yeah, very contrived) with the following template conversions:

1. Uppercase last name.


2. If OnVacation is true, disable a link to their schedule.


3. Format balance using some currency specific format.


Here is the XAML that leverages my single converter for all of the above:



<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Text="First Name" Width="100" />
<TextBlock Text="Last Name" Width="100" />
<TextBlock Text="Is Active" Width="100" />
<TextBlock Text="Rating" Width="100" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}" Width="100" />
<TextBlock Text="{Binding LastName, Converter={StaticResource PythonExpConverter}, ConverterParameter=\'value\'.upper()}" Width="100" />
<HyperlinkButton Width="100" NavigateUri="http://foo" Content="View"
IsEnabled="{Binding OnVacation, Converter={StaticResource PythonExpConverter}, ConverterParameter=not value}" />
<TextBlock Text="{Binding Balance, Converter={StaticResource PythonExpConverter}, ConverterParameter=\'%2.2f\' % value}" Width="100" />
</StackPanel>
</StackPanel>


This is a very powerful approach since the limitations you hit will probably be born by a limitation in skill with Python or your dynamic language of choice rather than the approach. 



}