<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nephandus</title>
	<atom:link href="http://www.nephandus.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nephandus.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Mon, 27 Feb 2012 20:12:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>GoDaddy Can Take A Flying Leap</title>
		<link>http://www.nephandus.com/2011/12/27/godaddy-can-take-a-flying-leap/</link>
		<comments>http://www.nephandus.com/2011/12/27/godaddy-can-take-a-flying-leap/#comments</comments>
		<pubDate>Tue, 27 Dec 2011 21:14:42 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.nephandus.com/?p=44</guid>
		<description><![CDATA[This domain is no longer registered with GoDaddy in protest of GoDaddy&#8217;s support for the Stop Online Piracy Act or SOPA. It is with a heavy heart that I leave GoDaddy. For years the company offered inexpensive registration, stellar customer support, a suite of powerful tools with which to manage domains, and a number of [...]]]></description>
			<content:encoded><![CDATA[<p>This domain is no longer registered with GoDaddy in protest of GoDaddy&#8217;s support for the Stop Online Piracy Act or SOPA.<br />
<span id="more-44"></span><br />
It is with a heavy heart that I leave GoDaddy.  For years the company offered inexpensive registration, stellar customer support, a suite of powerful tools with which to manage domains, and a number of helpful (if somewhat over priced) services and add-ons for customers who wanted to use them.  Sure its corporate persona was a bit raunchy and the registration process was festooned with expensive and unnecessary products and services to inflate the bottom line, but in terms of price and support GoDaddy was and is a class act.</p>
<p>But that&#8217;s not enough.</p>
<p>The existential threat posed by SOPA to the very foundations of the Internet as we understand it can not be ignored and GoDaddy&#8217;s support of the bill &#8212; even now that that support has been withdrawn &#8212; was more than enough to send me and thousands of other technology professional packing.  </p>
<p>The lesson of GoDaddy is this: there is no crime more abhorrent than to betray the very livelihoods of your customers.  If the position of your company seeks to jepordize not just my ability to purchase your service but my ability to feed my family than no amount of discounts, stellar service, or witty ads will convince me to stay.  </p>
<p>Of course, GoDaddy is a drop in the bucket; the list of SOPA supporters is long indeed and honestly very few of them will face a boycott because of that support.  The internet is a mercurial and savage disciplinarian, however, and while few SOPA supporters will face the kind of reaction GoDaddy endured, many will no doubt fear it.  The question is, will that fear translate into a change in policy?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nephandus.com/2011/12/27/godaddy-can-take-a-flying-leap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How Hard Is This, Really?</title>
		<link>http://www.nephandus.com/2011/11/03/how-hard-is-this-really/</link>
		<comments>http://www.nephandus.com/2011/11/03/how-hard-is-this-really/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 19:45:35 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[galaxy nexus]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[nexus prime]]></category>
		<category><![CDATA[smartphone]]></category>

		<guid isPermaLink="false">http://www.nephandus.com/?p=42</guid>
		<description><![CDATA[I am not a marketing person. In fact, as a technology person, I tend to find marketing people frustrating and infuriating. Most of what they say leads me to suspect that they might just be making things up as they go along. I&#8217;m not saying that&#8217;s the way marketing works, but I often can&#8217;t shake [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" src="http://www.geeky-gadgets.com/wp-content/uploads/2011/10/google-nexus-prime2.jpg" alt="" width="234" height="274" />I am not a marketing person. In fact, as a technology person, I tend to find marketing people frustrating and infuriating. Most of what they say leads me to suspect that they might just be making things up as they go along. I&#8217;m not saying that&#8217;s the way marketing works, but I often can&#8217;t shake that nagging doubt.</p>
<p>Then again, there are clear cut cases where marketing is done well and its done badly. Apple knows how to market. Google does not.<span id="more-42"></span></p>
<p>Let me state, from the outset, that I&#8217;m an Android fan. I got an OG Droid (that&#8217;s the original Droid for those of you who don&#8217;t frequent Android news forums) back in 2009 and I&#8217;ve been hugely happy with it. No, it&#8217;s not as snappy or as polished as an iPhone, but it can do a lot of stuff that an iPhone can&#8217;t and I can tinker with it, which appeals to my more dwarfish (in the <a href="http://www.urbandictionary.com/define.php?term=Tolkienian">Tolkienian</a> sense) sensibilities.</p>
<p>So one can imagine how pleased I was to learn that not only is Google going to release its next generation phone very shortly and that it will be running the latest and greatest version of Android to boot, but that said release lines up fairly nicely with my eligibility for a phone upgrade.</p>
<p>Except&#8230; that was two months ago.</p>
<p>Since then, Google has gone back and forth on the release date for their phone. They&#8217;ve hosted a lack-luster demo of the technology in Hong Kong (of all places) which ended up being an exercise in watching an executive awkwardly stumble through features with neither enthusiasm nor any real finesse. They&#8217;ve even confused the issue by refusing to stick with a consistent naming and branding strategy. I honestly don&#8217;t know if the phone &#8212; which is apparently due out later this month &#8212; will be the Galaxy Nexus or the Nexus Prime.</p>
<p>Imagine, if you will, if Apple had run this product launch. For starters, there would be no branding confusion. Google&#8217;s original Nexus isn&#8217;t a going concern anymore. They&#8217;d call the new phone the &#8220;Nexus S&#8221; or something like that (which everyone would immediately mentally shorten to &#8220;Nexus&#8221;) and have done with it. They&#8217;d have gathered a bunch of media, fanboys, and bloggers into a huge auditorium in California somewhere and done the launch live in the AM hours, thereby ensuring that everyone in their major target markets (the US and Europe) can watch it live either at work or at home. Finally, they&#8217;d have committed, on screen and in huge easy to read type, during the presentation to both a price-point (with contract) and a release date. Preorder screens would have gone up in the middle of the presentation and by close of business that day folks who wanted the new phone would have to do nothing but wait for the drop date with an optional &#8220;wait in the overnight line for the phone because you&#8217;re crazy&#8221; event for a midnight release.</p>
<p>This isn&#8217;t difficult stuff. Apple products have their shortcomings but if they&#8217;ve done one thing it is establish to almost formulaic accuracy, the correct way to launch a piece of consumer electronics. This requires no great Madison Avenue agencies, no fantastically expensive MBA laden consultancies, just a willingness to emulate success. Instead, Google as opted for a strategy which has confounded and frustrated its most devoted customers at every turn and a lot of people have chosen to go with a competing device rather than try to guess when the Galaxy-Nexus-Prime will drop.</p>
<p>Android has made some impressive gains on the smartphone OS market these last few years but Google performance in this launch forces me to conclude that this isn&#8217;t because of, but rather in spite of, the company&#8217;s understanding of the consumer electronics market.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nephandus.com/2011/11/03/how-hard-is-this-really/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GROUP_CONCAT in MS-SQL</title>
		<link>http://www.nephandus.com/2011/05/31/group_concat-in-ms-sql/</link>
		<comments>http://www.nephandus.com/2011/05/31/group_concat-in-ms-sql/#comments</comments>
		<pubDate>Tue, 31 May 2011 21:32:45 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[group concat]]></category>
		<category><![CDATA[mssql]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.nephandus.com/?p=38</guid>
		<description><![CDATA[My first real exposure to databases was with MySQL.  Every database has its ups and downs and MySQL is no exception, but among its major ups was &#8211; to me anyway &#8211; a function called Group_Concat. If you&#8217;re not familiar with Group_Concat, consider a basic role based security system.  You have numerous users, each of [...]]]></description>
			<content:encoded><![CDATA[<p>My first real exposure to databases was with MySQL.  Every database has its ups and downs and MySQL is no exception, but among its major ups was &#8211; to me anyway &#8211; a function called <a href="http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat">Group_Concat</a>.</p>
<p>If you&#8217;re not familiar with Group_Concat, consider a basic role based security system.  You have numerous users, each of which has has one or more roles.  It is easy enough to get back a list of user/role pairs, easy enough to get back a list of roles with one user per role, and easy enough to get back a list of users with one role per user; that&#8217;s all basic join syntax.</p>
<p>But what if you want a list of roles &#8212; one row per role &#8212; and want to know every user that has that role?</p>
<p>That&#8217;s what Group_Concat is for.  Bicker and argue all you like about why one might or might not need this functionality, there are just times when it&#8217;s nice to have.</p>
<p>Unfortunately, MS-SQL doesn&#8217;t really implement it&#8230; or it didn&#8217;t.  Recently <a href="http://anthony-yio.blogspot.com/2007/12/mssql-groupconcat.html">I found</a> a sort of hacked together implementation of Group_Concat in MS-SQL that actually works.  Since I&#8217;m developing in C# these days, the following implementation applies to a SQL 2008 database implementing ASP.net&#8217;s standard role based security.</p>
<pre class="brush: sql; title: ;">
SELECT
     RoleName,
     UserNames
FROM
     dbo.aspnet_Roles AS r
     CROSS APPLY (
          SELECT
               u.UserName + ','
          FROM
               dbo.aspnet_Users u
               INNER JOIN dbo.aspnet_UsersInRoles uir
                    ON u.UserId = uir.UserId
               INNER JOIN dbo.aspnet_Roles rr
                    ON rr.RoleId = uir.RoleId
          WHERE
               r.RoleId = uir.RoleId FOR XML PATH('')
     ) D(UserNames)
     GROUP BY
          RoleName,
          UserNames
</pre>
<p>The relevant parts of this are the XML cleverness and the CROSS APPLY, everything else is basic SQL.  </p>
<p>The XML bit relies on MS-SQL&#8217;s XML support and is, bluntly, a hack.  You can play with it independently with queries like this one</p>
<pre class="brush: sql; title: ;">
SELECT
     UserName + ''
FROM
     dbo.aspnet_Users
FOR XML PATH('')
</pre>
<p>Long story short, adding that FOR XML PATH(&#8221;) to the query results in instant concatenation of values.  So now all that&#8217;s left is to properly relate this to the outer query.  That&#8217;s where the CROSS APPLY comes in.  CROSS APPLY  allows you to specify what amounts to a derived table that can legally contain references to some outer information, in this case our outer query.   That&#8217;s necessary to constrain our inner table so as to only get the users we are interested in.  We can&#8217;t do it outside of the CROSS APPLY because, by then the concatenation has already occurred.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nephandus.com/2011/05/31/group_concat-in-ms-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>No Comment</title>
		<link>http://www.nephandus.com/2010/12/13/no-comment/</link>
		<comments>http://www.nephandus.com/2010/12/13/no-comment/#comments</comments>
		<pubDate>Mon, 13 Dec 2010 13:52:00 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[economics]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[spamming]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.nephandus.com/?p=33</guid>
		<description><![CDATA[Despite my somewhat lacksidasical updating of Nephandus, my tiny handful of posts has gathered some 1,288 comments, of which perhaps 5 &#8211; charitably &#8211; are actually worthwhile. The others are spam. All of them. This despite trying a range of various CAPTCHA solutions, filters, etc, these I&#8217;ve been unable to stem the tide. Indeed, those [...]]]></description>
			<content:encoded><![CDATA[<p>Despite my somewhat lacksidasical updating of Nephandus, my tiny handful of posts has gathered some 1,288 comments, of which perhaps 5 &#8211; charitably &#8211; are actually worthwhile.</p>
<p>The others are spam.  All of them.<span id="more-33"></span></p>
<p>This despite trying a range of various CAPTCHA solutions, filters, etc, these I&#8217;ve been unable to stem the tide.  Indeed, those 1,288 are just the ones that got through.  Another ~900 were identified as SPAM by WordPress and blocked automagically.</p>
<p>Bluntly, this is absurd and, as I think about it, the possibilty of designing around such issues is equally absurd.</p>
<p>Even Gmail&#8217;s spam filters are not perfect, despite the unthinkably large data store from which they can pull and the absurd resources that Google is prepared to throw at the problem.</p>
<p>Practically &#8211; at least to my eye &#8211; this problem can not be completely solved by computer science.  The solution lies, instead, in the field of economics.</p>
<p>Spammers do  what they do because the cost is effectively zero and the preceived value is greater than zero.  With zero cost, even if the marginal utility &#8211; the preceived gain from each individual action &#8211; declines with each message or post, it never drops below the cost.</p>
<p>It is thus always profitable to spam.</p>
<p>The solution lies not in attempting to block spam, which is difficult, annoying, and labor intensive, but in reducing the preceived value of a spam message.</p>
<p>The &#8220;no follow&#8221; link convention implemented by Google helps &#8212; links so tagged (and most in blog comments are) are not given weight by Google&#8217;s search algorithms, thus eliminating the value of spamming for page-rank.  Of course, that is not the only reason people spam.</p>
<p>Some are looking to sell a product &#8211; and view spam as free advertising.  Others are looking to ensnare victims in some sort scheme &#8211; either financial or technological.</p>
<p>In both cases, spammers are hoping that humans, not computers, will follow their links.  Some social networks like MSNBC&#8217;s Newsvine have taken to banning linking entirely &#8211; at least on recently registered accounts.  Spammers then break up URLs or instruct users to search for certain phrases.</p>
<p>Ineffective?  Sure, but again, with a marginal cost of zero, who cares?</p>
<p>Perhaps it is not possible to reduce the value of spam postings to zero without destroying the possibility of meaningful comment as well.  If so then the only remaining option is to find a way to raise the cost of posting.</p>
<p>CAPTCHA was an attempt to do this, though one that obviously has met with limited success.  Back in the 1990s the notion of a pay-to-send email system was floated with micro-transactions supporting the system and making bulk-spam mailing actually cost something.</p>
<p>That was 20 years ago, however, and there&#8217;s been little meaningful progress.</p>
<p>Sadly, I have no profound conclusion to offer you, dear reader, save this one.  Markets work both ways and the simple fact is that while I can not make it economically prohibitive for spammers to post, they have made it economically prohibitive for me to maintain a comments section on this blog.</p>
<p>Effective immediately, therefore, commenting on Nephandus is disabled.  In reality it has been for some time as the volume of new-post notifications from WordPress lead me to simply ignore them and instruct Gmail to automatically delete them several months ago.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nephandus.com/2010/12/13/no-comment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Break On Through To The Other Side</title>
		<link>http://www.nephandus.com/2010/07/02/break-on-through-to-the-other-side/</link>
		<comments>http://www.nephandus.com/2010/07/02/break-on-through-to-the-other-side/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 19:23:23 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[user controls]]></category>
		<category><![CDATA[viewstate]]></category>

		<guid isPermaLink="false">http://www.nephandus.com/?p=26</guid>
		<description><![CDATA[User controls are the source of a lot of headaches in C#. They have two major issues that tend to drive programmers a little mad. The first is that they don&#8217;t play nicely with the ViewState. Particularly once users start to nest and reorder user controls, the ViewState model (much of which is based on [...]]]></description>
			<content:encoded><![CDATA[<p>User controls are the source of a lot of headaches in C#.  They have two major issues that tend to drive programmers a little mad.  The first is that they don&#8217;t play nicely with the ViewState.  Particularly once users start to nest and reorder user controls, the ViewState model (much of which is based on position within the page) starts to break down.  In many cases programmers circumvent this little nightmare by simply disabling the ViewState on some controls.</p>
<p>The second issue is that user controls are in their own scope and don&#8217;t have immediate access to the rest of the page.  That is both a blessing and a curse; good control design means that the controls should be fairly independent of each other but a more pragmatic developer will also note that user controls exist primarily so that numerous copies of the same thing can be easily created and that making entirely self contained controls leads to a lot of unnecessary duplication.</p>
<p>Fortunately there are workarounds for both of these issues.  <span id="more-26"></span></p>
<p>Regardless of view state, a user control can pass information and therefore trigger events properly using the ASP framework by means of some elaborate JavaScript trickery.  In this example, I am using JQuery and JavaScript to allow a click event inside a ViewStateless user control to set the value of a text box and click a button outside of the control, thereby triggering an event within the ASP framework.</p>
<pre class="brush: jscript; title: ;">
$(JQueryObjectForMyUserControl).find(&quot;.clickableElement&quot;)
.unbind(&quot;click&quot;).click(function() {
        var clickHandler = $(this).parents(&quot;.OuterBound&quot;).find(&quot;.ClickHandler&quot;);
        //I'm replacing the underscores with dollar signs here because that is what ASP expects to find internally
        var argument = $(this).find(&quot;a&quot;).attr(&quot;id&quot;).replace(/_/g, &quot;$&quot;);
        clickHandler.find(&quot;.ClickHandlerArgument&quot;).val(argument);
        clickHandler.find(&quot;.ClickHandlerLinkButton&quot;).click();
    });
</pre>
<p>Getting around the scope restriction requires a great deal less insanity.  For example, my user controls have to be able to activate a modal overlay and dialog box.  I could put the code for that inside each user control but that would be a lot of code bloat.  Instead, I have the dialog in one place on my page and allow the controls to set its values and activate it.</p>
<pre class="brush: csharp; title: ;">
Page page = this.Page;
ModalPopupExtender ModalPopupExtenderLockedDialog = (ModalPopupExtender)page.FindControl(&quot;ModalPopupExtenderLockedDialog&quot;);
Label LabelMessage = (Label)page.FindControl(&quot;LabelMessage&quot;);
ModalPopupExtenderLockedDialog.Show();
LabelMessage.Text = &quot;Hello World!&quot;;
</pre>
<p>Getting to properties is only a little harder.  If you need to get to the properties of your page you need only cast this.Page appropriately.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nephandus.com/2010/07/02/break-on-through-to-the-other-side/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wazza ListItemContainer?</title>
		<link>http://www.nephandus.com/2010/06/30/wazza-listitemcontainer/</link>
		<comments>http://www.nephandus.com/2010/06/30/wazza-listitemcontainer/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 13:57:42 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[quirks]]></category>
		<category><![CDATA[serialization]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.nephandus.com/?p=24</guid>
		<description><![CDATA[VirPack has me working on an application that needs a user administered list of options for people to choose from. It&#8217;s a fairly simple thing that doesn&#8217;t require relational tables so I thought I&#8217;d toss it into XML. Now, C# deals with XML really well. Almost everything, if you just ask nicely, will be quickly [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignleft" style="width: 250px"><a href="http://www.flickr.com/photos/scottpargettphoto/1838997549/"><img title="Springfield XD .40 XML" src="http://farm3.static.flickr.com/2172/1838997549_30246e88ef_m.jpg" alt="" width="240" height="160" /></a><p class="wp-caption-text">Not this kind of XML</p></div>
<p>VirPack has me working on an application that needs a user administered list of options for people to choose from.  It&#8217;s a fairly simple thing that doesn&#8217;t require relational tables so I thought I&#8217;d toss it into XML.</p>
<p>Now, C# deals with XML really well.  Almost everything, if you just ask nicely, will be quickly and easily packed off into XML the framework with just a few lines of code.</p>
<p><span id="more-24"></span></p>
<pre class="brush: csharp; title: ;">
String path = Server.MapPath(&quot;~\\myfile.xml&quot;);
using (FileStream sourceFile = new FileStream(Server.MapPath(path), FileMode.Create, FileAccess.Write))
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Foo));
            serializer.Serialize(sourceFile, bar);
        }
        bar = null;
        using (System.IO.FileStream sourceFile = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read))
        {
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Foo));
            Foo bar= serializer.Deserialize(sourceFile) as Foo;
        }
</pre>
<p>As simple as that I&#8217;ve packed my class off to be serialized and then unserialized it.  Three lines of code is hard to beat for XML serialization and deserialization.  &#8220;Foo&#8221; is a user defined type, however, and my particular task being the population of a drop-down list, no such complexity was required.  Yet, when I tried to feed a List of ListItems into the Serializer everything broke.</p>
<pre class="brush: csharp; title: ;">
//This breaks
System.Xml.Serialization.XmlSerializer listSerializer = new System.Xml.Serialization.XmlSerializer(typeof(List));
//This too
System.Xml.Serialization.XmlSerializer typedListSerializer = new System.Xml.Serialization.XmlSerializer(typeof(List&lt;ListItem&gt;));
</pre>
<p>This has to do with how C# deals with collections.  Serialization requires a root level node and a collection, despite having an appearance of such, has no root level information.  It is a collection, not a collection bounded by something else and XML serialization requires that something else.</p>
<p>So C# has a hackish workaround.  The ListItemContainer class is a simple type that contains a List of ListItems.</p>
<pre class="brush: csharp; title: ;">
//This works
System.Xml.Serialization.XmlSerializer listSerializer = new System.Xml.Serialization.XmlSerializer(typeof(ListItemContainer));
</pre>
<p>Of course, not everything you&#8217;ll wish to serialize in a list will be a list item, but the fact that C# had to create it&#8217;s own little wrapper class should be a clue for developers.  Getting a collection into XML requires a wrapper class; it&#8217;s as simple as that.</p>
<p>Would it have killed them to document that though?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nephandus.com/2010/06/30/wazza-listitemcontainer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit Testing C# Webpages</title>
		<link>http://www.nephandus.com/2010/05/06/unit-testing-c-webpages/</link>
		<comments>http://www.nephandus.com/2010/05/06/unit-testing-c-webpages/#comments</comments>
		<pubDate>Thu, 06 May 2010 14:04:57 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[test driven development]]></category>
		<category><![CDATA[watir]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.nephandus.com/?p=21</guid>
		<description><![CDATA[Unit testing is good; test driven development is better.  As Knuth once famously quipped &#8220;Beware of the above code. I have only proven it correct, not tested it.&#8221; There really is no substitution for good, solid testing. Unfortunately, at least in C#, webpages don&#8217;t like to be unit tested.  I approach this post with an [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_22" class="wp-caption alignleft" style="width: 223px"><a href="http://www.flickr.com/photos/beatkueng/2680294816/"><img class="size-medium wp-image-22" title="2680294816_e710a43d3b" src="http://www.nephandus.com/wp-content/uploads/2010/05/2680294816_e710a43d3b-213x300.jpg" alt="" width="213" height="300" /></a><p class="wp-caption-text">Image Credit: PixelPlacebo via Flickr and Creative Commons</p></div>
<p>Unit testing is good; test driven development is better.  As Knuth once famously <a href="http://www-cs-faculty.stanford.edu/~knuth/faq">quipped</a> &#8220;<em>Beware of the above code. I have only proven it correct, not tested it.&#8221;</em> There really is no substitution for good, solid testing.</p>
<p>Unfortunately, at least in C#, webpages don&#8217;t like to be unit tested.  I approach this post with an uncomfortable realization that I am about to lay out the issues and problems I&#8217;ve had while the solution I am presently using is far from satisfactory.<span id="more-21"></span></p>
<p>There is a right way and a wrong way to undertake a lot of unit testing.  If you want to learn about that, I recommend <a href="http://www.ryanhagan.net/2009/10/test-driven-development/">this post by Ryan Hagan</a> as a great jumping off point.  My problem is not in writing good unit tests, however, so much as having a place to write them.</p>
<p>Axiomatic truth of Unit Testing: Your test code should exist in a different place than your production code.  This just makes good sense.  You don&#8217;t want to publish your tests every time you push code out the door and, since you want all of your published code to be tested you don&#8217;t want to have to write tests for your tests.  In C# the way one generally accomplishes this is the creation of a separate test project within the current solution.  That way the solution contains both your code and your tests.</p>
<p>Now generally, when you&#8217;re writing tests for C# this isn&#8217;t a big deal.  Since your project gets bundled up every time you build you can add a reference to the Test project that points at your main project; that way, the test harness knows what to make of all the custom types and whatnot that your various tests will have to evaluate.</p>
<p>This does not work for webpages.</p>
<p>When C# builds a webpage there&#8217;s no handy-dandy compiled thing at which to point your test code.  That means your test code has no idea what to make of any custom objects you&#8217;ve created and that makes any meaningful testing pretty much impossible.  Consider the following short example:</p>
<pre class="brush: csharp; title: ;">
public void CreateTest()
        {
            string WidgetName = string.Empty;
            Widget expected = null;
            Widget actual;
            actual = WidgetFactory_Accessor.Create(WidgetName);
            Assert.AreNotEqual(expected, actual);
       }
</pre>
<p>In this example, &#8220;Widget&#8221; and &#8220;WidgetFactory&#8221; are both custom types.  C# has conveniently generated an accessor for my Factory but it has no reference to my main project and thus doesn&#8217;t know what a Widget is.  Consequently, this test won&#8217;t compile and I can&#8217;t run it.</p>
<p>There is a work-around solution I&#8217;ve found wherein I publish the Main Project and then create a reference from the Test Project to the published AppCode.dll file.  This works but requires that I publish the DLL every time I wish to re-evaluate my source code which makes the entire testing process prohibitively time consuming.</p>
<p>My suspicion at this point is that what I am trying to do is in fact neither possible nor recommended and that unit testing of a C# webpage should be accomplished by creating a sharp distinction between the interface and presentation layers, testing the presentation layer traditionally and then using interface testing suites like <a href="http://watir.com/">Watir</a>.  This seems the sort of thing that should be verbosely stated somewhere if it is, indeed, the case.</p>
<h2>Update</h2>
<p>As per Ryan&#8217;s suggestion below and some other feedback I&#8217;ve gotten I am moving much of the logic code out of the project and creating a project-level distinction between the interface and the presentation layers of the application.  This should allow me to more sanely test the presentation layer and leverage Watin in to handle the interface testing.</p>
<p>It&#8217;s not the sort of separation recommended, but the architecture on this particular system is fairly dated and a full out re-factoring is out of the question (for now).</p>
<p>As it&#8217;s conspicuously missing from many other write-ups I&#8217;ve seen I&#8217;ll say it here.  You can not meaningfully test anything except the interface of a C# web project.  If you want to test your code, move it into a DLL project and allow your web project to call that DLL.  Ideally the Web project should be as thin as possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nephandus.com/2010/05/06/unit-testing-c-webpages/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Teaching An Old Dog New Tricks</title>
		<link>http://www.nephandus.com/2010/04/28/teaching-an-old-dog-new-tricks/</link>
		<comments>http://www.nephandus.com/2010/04/28/teaching-an-old-dog-new-tricks/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 19:23:18 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[syntax highlighter]]></category>
		<category><![CDATA[user testing]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.nephandus.com/?p=18</guid>
		<description><![CDATA[Most of the blogging I&#8217;ve done in the past has been political and thus I really haven&#8217;t had an opportunity to try to post much in the way of source code in a blog.  Once I got Nephandus up and running on WordPress, however, I thought I&#8217;d have a shot at it and thus posted [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_19" class="wp-caption alignleft" style="width: 206px"><a href="http://www.flickr.com/photos/dirkjankraan/4476149021/"><img class="size-medium wp-image-19" title="767 Cockpit" src="http://www.nephandus.com/wp-content/uploads/2010/04/4476149021_79176350b7-196x300.jpg" alt="" width="196" height="300" /></a><p class="wp-caption-text">How do you user test this?</p></div>
<p>Most of the blogging I&#8217;ve done in the past has been political and thus I really haven&#8217;t had an opportunity to try to post much in the way of source code in a blog.  Once I got Nephandus up and running on WordPress, however, I thought I&#8217;d have a shot at it and thus posted a short article on my experiences with C#&#8217;s serialization quirks.</p>
<p>To illustrate a specific point I included a brief snippet of C# code which WordPress promptly turned into an illegible mess.  The web is a notoriously difficult place to display source code and thus I set off in search of a WordPress plug-in that would allow me to do so without too much thought.  Several days, a dozen plug-ins, and a string of curse words that would make a sailor blush with shame, <a href="http://www.viper007bond.com/wordpress-plugins/syntaxhighlighter/">I have a solution</a>.</p>
<p>There is no shortage of syntax highlighting plug-ins available, but the support for their instantiation is practically non-existent.    Nephandus is running a number of plug-ins, none of which required much more than a few mouse-clicks to install and configure yet this particular task proved more difficult and involved than anything else I&#8217;ve done with WordPress.</p>
<p>The more I thought about this frustration the more I realized that this is an ongoing problem in the software development industry.<span id="more-18"></span></p>
<p>When developers buid a word processor or an email application they spend (or they should spend) a fair bit of time working out where users will intuitively look for certain basic functionality.  Tools, options, and commands should be where the user expects them to be; that saves time and cuts down on support costs.  We can test and evaluate that design by asking people who are totally unfamiliar with the product to find those sorts of functions and watching what they do.  It&#8217;s a system that works well because, familiar with the product or not, everyone has a basic grasp of certain tasks like writing or arithmetic.</p>
<p>But how do you do that kind of testing with an IDE?</p>
<p>The people who use IDEs are, pretty much by definition, super-users.  At the very least we can expect them to have a high level of familiarity, if not with the interface itself than with the thing the interface manipulates &#8211; code in a programming language they know.  These users have very specific ideas about where things ought to be which are based, not on intuition but where they were in some other IDE that they learned.  Because the population of knowledgeable coders is small and the number of IDEs they develop on is also small, it&#8217;s likely that they&#8217;ll bring some of their preconceived notions into user testing and that those notions will persist through the testing process.</p>
<p>Neophyte users aren&#8217;t terribly helpful because while they&#8217;re learning the interface they&#8217;re also learning the language and thus don&#8217;t know enough to evaluate the more powerful aspects of a product.</p>
<p>How then do you test the usability of a new interface when that interface&#8217;s intended users are a small, niche population often with preconceived, conflicting, and sometimes nearly religious notions of how the interface should look, feel, and act?</p>
<p>That isn&#8217;t a problem that WordPress plug-in authors really need to worry too much about &#8211; at least not if they&#8217;re giving their work away for free (beggars can&#8217;t be choosers) &#8211; but those of us who make specialty products for high-end niche professionals need to find a way to tackle the problem lest we find ourselves unable to change a 30 year old catastrophe of a design because it&#8217;s what everyone knows and expects.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nephandus.com/2010/04/28/teaching-an-old-dog-new-tricks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# WebControl Behavior</title>
		<link>http://www.nephandus.com/2010/04/26/c-webcontrol-behavior/</link>
		<comments>http://www.nephandus.com/2010/04/26/c-webcontrol-behavior/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 18:52:36 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[serialization]]></category>
		<category><![CDATA[serialized]]></category>
		<category><![CDATA[session]]></category>
		<category><![CDATA[viewstate]]></category>
		<category><![CDATA[webcontrol]]></category>

		<guid isPermaLink="false">http://www.nephandus.com/?p=14</guid>
		<description><![CDATA[My &#8220;learn C# project&#8221; at work has centered around creating a drag-and-drop portlet style system for the display of custom widgets.  I&#8217;ve been using JQuery UI for the javascript functionality but the backend has been all custom C# work. People familiar with C# know that C# supports the inclusion of user defined controls called WebControls.  [...]]]></description>
			<content:encoded><![CDATA[<p>My &#8220;learn C# project&#8221; at work has centered around creating a drag-and-drop portlet style system for the display of custom widgets.  I&#8217;ve been using JQuery UI for the javascript functionality but the backend has been all custom C# work.</p>
<p>People familiar with C# know that C# supports the inclusion of user defined controls called WebControls.  These are more or less very simple C# programs which can be man-handled by another bit of C# code.  They&#8217;re handy for making your code modular: you might design a web-control that takes and validates a credit card number, for example.</p>
<p>But WebControls are notoriously tricky beasts and over the course of the last few weeks I&#8217;ve come to understand that one of the reasons for this is that they don&#8217;t behave quite the way you might expect them to when they are serialized and deserialized.<span id="more-14"></span></p>
<p>Most C# serialization occurs behind the scenes in something called the ViewState.  For those of you who have no idea what that means, ViewState is C#&#8217;s rather clever way of persisting the things on a webpage so that it feels a little more like a desktop application.  The long and the short of its behavior is that things get serialized into the ViewState just before rendering and de-serialized back out of ViewState on the next request as part of the load step.</p>
<p>Most controls go into the ViewState&#8230; but WebControls don&#8217;t.  At least, they don&#8217;t go in there by default.  Presumably you can create custom ViewState serialization for them; I have not tried this.  Instead, I serialized my WebControls very simply into Session and coded that storage into a property.  My code looked something like this</p>
<pre class="brush: csharp; title: ;">
private Widget InternalWidget
{
	get
	{
		Widget result;
		if (Session[&quot;Widget&quot; + this.UniqueID] != null)
		{
			result = Session[&quot;Widget&quot; + this.UniqueID] as Widget;
			if (result == null )
			{
				result = WidgetFactory.Create();
				result.Arguments = InternalActivePortlet.Arguments;
			}
		}
		return result;
	}
	set
	{
		Session[&quot;Widget&quot; + this.UniqueID] = value;
	}
}
</pre>
<p>Now, as expected, none of my EventHandlers persisted when the WebControl came back out of its session serialization.  The object that comes back from serialization is an entirely new object; the old one has been destroyed.  As a result, the event handlers in the deserialized object point to null function pointers.  C# doesn&#8217;t throw an error when you call a null function pointer, however; it just goes on its merry way and does nothing.</p>
<p>But the function pointers &#8211; even though they now point to null objects &#8211; remain.  C# remembers a great deal more about the session-serialized object than one might think including &#8211; and this is the part that really threw me &#8211; the fact that it&#8217;s already been through the ASP parser.</p>
<p>I had expected, since my event handlers weren&#8217;t working when the WebControl came back from Session, that the events themselves were gone and that therefore the object returned from session was new &#8212; as if it was programatically created for the first time.  This is not the case.  When you programatically create a WebControl for the first time it&#8217;s ASP file is parsed and event handlers are set up based upon the code there.  When you deserialize a WebControl from session, however, C# remembers that it has already dealt with its ASP code and does not do it a second time.</p>
<p>Consequently, none of the event handlers defined in the ASP work either.</p>
<p>I expect that all of this seems rudimentary to more experienced C# developers, but to me it was quite a mystery and it took me some time to work out the above logic.  Hopefully this will aid some neophyte coder working through the same issues I had.</p>
<p>On a totally unrelated note: I need to find a decent code display plugin for WordPress&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nephandus.com/2010/04/26/c-webcontrol-behavior/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mobile Experiments</title>
		<link>http://www.nephandus.com/2010/04/26/mobile-experiments/</link>
		<comments>http://www.nephandus.com/2010/04/26/mobile-experiments/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 12:37:12 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[apps]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.nephandus.com/2010/04/26/mobile-experiments/</guid>
		<description><![CDATA[I am not sure why anyone would want to write a blog post from their phone but if that sounds fun to you there&#8217;s apparently an Android app for that. Just remember to enable the &#8220;WordPress, Moveable Type, MetaWeblog and Blogger XML-RPC publishing protocols&#8221; in WordPress&#8217; settings/writing section.]]></description>
			<content:encoded><![CDATA[<p>I am not sure why anyone would want to write a blog post from their phone but if that sounds fun to you there&#8217;s apparently an Android app for that. <span id="more-13"></span></p>
<p>Just remember to enable the &#8220;WordPress, Moveable Type, MetaWeblog and Blogger XML-RPC publishing protocols&#8221; in WordPress&#8217; settings/writing section.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nephandus.com/2010/04/26/mobile-experiments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

