<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Dave Bouwman</title>
    <link>http://blog.davebouwman.net/</link>
    <description>Software Development :: .NET - GIS - ESRI</description>
    <language>en-us</language>
    <copyright>Dave Bouwman</copyright>
    <lastBuildDate>Thu, 03 Jul 2008 04:43:39 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.7174.0</generator>
    <managingEditor>dave@davebouwman.com</managingEditor>
    <webMaster>dave@davebouwman.com</webMaster>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=b92c4619-7c32-4f84-b120-2fbd839fc5a1</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,b92c4619-7c32-4f84-b120-2fbd839fc5a1.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,b92c4619-7c32-4f84-b120-2fbd839fc5a1.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=b92c4619-7c32-4f84-b120-2fbd839fc5a1</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm doing a technical review for some chapters on the <a href="http://www.dojotoolkit.org">Dojo
Toolkit</a> for an upcoming Wrox Press book on Javascript Frameworks. I suppose not
surprisingly, the sample code for the server side code is php.
</p>
        <p>
So, in order to be a good reviewer, I'm jumping into the PHP pool. I have to say that
in reading the sample code, it's a lot "closer to the metal" then ASP.NET,
so this should be interesting to say the least.
</p>
        <p>
So - should you want to embark on a similar journey, here's the best info I could
find on <a href="http://blogs.iis.net/bills/archive/2006/09/19/How-to-install-PHP-on-IIS7-_2800_RC1_2900_.aspx">installing
php as an ISAPI extension</a>. 
</p>
        <p>
If you are running Vista SP1 or Server 2008, you can install FastCGI support and run
PHP that way. The basic steps are <a href="http://learn.iis.net/page.aspx/246/using-fastcgi-to-host-php-applications-on-iis7/">outlined
here</a>.
</p>
        <p>
Looks like things are up and running - php here I come! 
</p>
        <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=b92c4619-7c32-4f84-b120-2fbd839fc5a1" />
        <br />
        <hr />
        <hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></body>
      <title>Installing PHP on IIS7 (Vista)</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,b92c4619-7c32-4f84-b120-2fbd839fc5a1.aspx</guid>
      <link>http://blog.davebouwman.net/2008/07/03/InstallingPHPOnIIS7Vista.aspx</link>
      <pubDate>Thu, 03 Jul 2008 04:43:39 GMT</pubDate>
      <description>&lt;p&gt;
I'm doing a technical review for some chapters on the &lt;a href="http://www.dojotoolkit.org"&gt;Dojo
Toolkit&lt;/a&gt; for an upcoming Wrox Press book on Javascript Frameworks. I suppose not
surprisingly, the sample code for the server side code is php.
&lt;/p&gt;
&lt;p&gt;
So, in order to be a good reviewer, I'm jumping into the PHP pool. I have to say that
in reading the sample code, it's a lot &amp;quot;closer to the metal&amp;quot; then ASP.NET,
so this should be interesting to say the least.
&lt;/p&gt;
&lt;p&gt;
So - should you want to embark on a similar journey, here's the best info I could
find on &lt;a href="http://blogs.iis.net/bills/archive/2006/09/19/How-to-install-PHP-on-IIS7-_2800_RC1_2900_.aspx"&gt;installing
php as an ISAPI extension&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
If you are running Vista SP1 or Server 2008, you can install FastCGI support and run
PHP that way. The basic steps are &lt;a href="http://learn.iis.net/page.aspx/246/using-fastcgi-to-host-php-applications-on-iis7/"&gt;outlined
here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Looks like things are up and running - php here I come! 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=b92c4619-7c32-4f84-b120-2fbd839fc5a1" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;hr&gt;
davebouwman.net weblog - copyright 2005-2008 - licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"&gt; Creative
Commons License. &lt;/a&gt;</description>
      <comments>http://blog.davebouwman.net/CommentView,guid,b92c4619-7c32-4f84-b120-2fbd839fc5a1.aspx</comments>
      <category>PHP</category>
    </item>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=6edd0657-17e1-4e5f-9f22-28436c8c4809</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,6edd0657-17e1-4e5f-9f22-28436c8c4809.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,6edd0657-17e1-4e5f-9f22-28436c8c4809.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=6edd0657-17e1-4e5f-9f22-28436c8c4809</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It's looking really dark outside and the trees are whippin around, so I brought up
the weather channel's radar map to see this... 
</p>
        <p>
          <a href="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/Isthisbad_E1EE/weather_2.png">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="412" alt="weather" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/Isthisbad_E1EE/weather_thumb.png" width="596" border="0" />
          </a>
        </p>
        <p>
Time to hunker down!
</p>
        <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=6edd0657-17e1-4e5f-9f22-28436c8c4809" />
        <br />
        <hr />
        <hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></body>
      <title>Is this bad?</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,6edd0657-17e1-4e5f-9f22-28436c8c4809.aspx</guid>
      <link>http://blog.davebouwman.net/2008/07/02/IsThisBad.aspx</link>
      <pubDate>Wed, 02 Jul 2008 22:04:55 GMT</pubDate>
      <description>&lt;p&gt;
It's looking really dark outside and the trees are whippin around, so I brought up
the weather channel's radar map to see this... 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/Isthisbad_E1EE/weather_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="412" alt="weather" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/Isthisbad_E1EE/weather_thumb.png" width="596" border="0" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Time to hunker down!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=6edd0657-17e1-4e5f-9f22-28436c8c4809" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;hr&gt;
davebouwman.net weblog - copyright 2005-2008 - licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"&gt; Creative
Commons License. &lt;/a&gt;</description>
      <comments>http://blog.davebouwman.net/CommentView,guid,6edd0657-17e1-4e5f-9f22-28436c8c4809.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=7bd84cca-07a3-4e12-9430-ae8fa0d12b06</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,7bd84cca-07a3-4e12-9430-ae8fa0d12b06.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,7bd84cca-07a3-4e12-9430-ae8fa0d12b06.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=7bd84cca-07a3-4e12-9430-ae8fa0d12b06</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A reader recently asked me to expand upon the "Keep it Simple" advice in the <a href="http://www.davebouwman.net/fundamentals/philosophy.aspx">fundamentals</a> section
of my web site. Just like my advice, I had kept this section pretty lean...
</p>
        <blockquote>
          <h2>Keep it simple
</h2>
          <p>
Anybody can build complex software. Creating simple software that can accomplish the
same task is much more difficult. In the end though, the simpler it is, the easier
it is to test, which makes it easier to maintain, and easier to extend.
</p>
        </blockquote>
        <p>
To illustrate the idea, I'll talk about a project that I'm working on right now. Basically
I'm helping / mentoring a team through a short term project to build a data viewer
application based on <a href="http://maps.live.com">Virtual Earth</a>, <a href="http://www.dojotoolkit.org">Dojo</a>,
ArcGIS Server (9.2) and ASP.NET.
</p>
        <p>
One of the user stories in this project is:
</p>
        <blockquote>
          <p>
As an administrator I want the Data Viewer to be database agnostic so that I can easily
configure it to pull point data from SQL Server, Oracle or file based data sources.
</p>
        </blockquote>
        <p>
Now, this is a great idea, and certainly possible. In fact it ends up being very interesting
to design (plug-ins, configuration sections and Inversion of Control oh my!). 
</p>
        <h2>Simple works...
</h2>
        <p>
In looking at the project (it's very short term) and the team (new to web development)
and the current problem they are trying to solve (display data from SQL Server), my
recommendation to the team is that we "keep it simple" for now, and just address the
SQL Server data source. 
</p>
        <p>
While we could define a set of interfaces, build out a whole configuration model,
and create the actual data access objects for these various data sources, in the context
of this project it's extraneous. To be "successful", we need to display the current
data in Virtual Earth. With tight time frames and limited resources, I believe the
tradeoff between building for an unknown complex future need, and applying time and
effort to the core objective, is a good one. The team will be able to get the database
access tier of the system completed in a short time, and it will be very simple to
understand - parameters are passed to a class, which calls a stored procedure, which
returns the point data. Simple, clean, and working.
</p>
        <p>
But what about the "can accomplish the same task" bit? Good question - I'd suggest
that in this situation, with the current data is in SQL Server, you are doing the
same task - just using a simpler design to achieve the goal. 
</p>
        <h2>Add Complexity when it is Needed
</h2>
        <p>
If / when a need arises to add data from Oracle, it will be a very simple task to
create another class which mimics the SQL Server class, with the only difference being
that it uses the Oracle data connection classes. Should this Data Viewer become a
huge hit, and is used so extensively that it must become configurable by non-developers,
it could then be refactored to add in the additional complexity required to support
configuration sections and a plug-in data provider model. But for now, the much simpler
solution works just fine.
</p>
        <p>
So - to summarize: Make choices which trend towards keeping the code as simple as
possible. Don't add extra features or design elements to handle unknown or fuzzy future
requirements. <strong>Add complexity only when it's really needed</strong>. While
it's fun to monkey with internal design optimizations etc, keep your eyes on the prize:
software that works for the user. And keep in mind <a href="http://www.codinghorror.com/blog/archives/001137.html">who
will be maintaining the software</a> over the long haul - while you may be a whiz
at generics (for example) keep in mind that for many people they tend to make understanding
the code more difficult. 
</p>
        <p>
That's pretty much my take on this, but I'd love to hear your thoughts on keeping
software "simple". How do you decide when to add complexity? How do you define complexity?
</p>
        <h2>Other thoughts on Simplicity:
</h2>
        <p>
          <a href="http://www.joelonsoftware.com/items/2006/12/09.html">Joel On Software: Simplicity</a>
        </p>
        <p>
          <a href="http://www.codesimplicity.com/archives/23">The Fourth Law of Software Design:
Complexity vs. Ease of Maintenance</a>
        </p>
        <p>
          <a href="http://www.jbox.dk/quotations.htm">Various Quotes on Simplicity in Software
Design</a>
        </p>
        <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=7bd84cca-07a3-4e12-9430-ae8fa0d12b06" />
        <br />
        <hr />
        <hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></body>
      <title>Software Simplicity Revisited</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,7bd84cca-07a3-4e12-9430-ae8fa0d12b06.aspx</guid>
      <link>http://blog.davebouwman.net/2008/07/02/SoftwareSimplicityRevisited.aspx</link>
      <pubDate>Wed, 02 Jul 2008 18:00:37 GMT</pubDate>
      <description>&lt;p&gt;
A reader recently asked me to expand upon the "Keep it Simple" advice in the &lt;a href="http://www.davebouwman.net/fundamentals/philosophy.aspx"&gt;fundamentals&lt;/a&gt; section
of my web site. Just like my advice, I had kept this section pretty lean...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;h2&gt;Keep it simple
&lt;/h2&gt;
&lt;p&gt;
Anybody can build complex software. Creating simple software that can accomplish the
same task is much more difficult. In the end though, the simpler it is, the easier
it is to test, which makes it easier to maintain, and easier to extend.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
To illustrate the idea, I'll talk about a project that I'm working on right now. Basically
I'm helping / mentoring a team through a short term project to build a data viewer
application based on &lt;a href="http://maps.live.com"&gt;Virtual Earth&lt;/a&gt;, &lt;a href="http://www.dojotoolkit.org"&gt;Dojo&lt;/a&gt;,
ArcGIS Server (9.2) and ASP.NET.
&lt;/p&gt;
&lt;p&gt;
One of the user stories in this project is:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
As an administrator I want the Data Viewer to be database agnostic so that I can easily
configure it to pull point data from SQL Server, Oracle or file based data sources.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Now, this is a great idea, and certainly possible. In fact it ends up being very interesting
to design (plug-ins, configuration sections and Inversion of Control oh my!). 
&lt;/p&gt;
&lt;h2&gt;Simple works...
&lt;/h2&gt;
&lt;p&gt;
In looking at the project (it's very short term) and the team (new to web development)
and the current problem they are trying to solve (display data from SQL Server), my
recommendation to the team is that we "keep it simple" for now, and just address the
SQL Server data source. 
&lt;/p&gt;
&lt;p&gt;
While we could define a set of interfaces, build out a whole configuration model,
and create the actual data access objects for these various data sources, in the context
of this project it's extraneous. To be "successful", we need to display the current
data in Virtual Earth. With tight time frames and limited resources, I believe the
tradeoff between building for an unknown complex future need, and applying time and
effort to the core objective, is a good one. The team will be able to get the database
access tier of the system completed in a short time, and it will be very simple to
understand - parameters are passed to a class, which calls a stored procedure, which
returns the point data. Simple, clean, and working.
&lt;/p&gt;
&lt;p&gt;
But what about the "can accomplish the same task" bit? Good question - I'd suggest
that in this situation, with the current data is in SQL Server, you are doing the
same task - just using a simpler design to achieve the goal. 
&lt;/p&gt;
&lt;h2&gt;Add Complexity when it is Needed
&lt;/h2&gt;
&lt;p&gt;
If / when a need arises to add data from Oracle, it will be a very simple task to
create another class which mimics the SQL Server class, with the only difference being
that it uses the Oracle data connection classes. Should this Data Viewer become a
huge hit, and is used so extensively that it must become configurable by non-developers,
it could then be refactored to add in the additional complexity required to support
configuration sections and a plug-in data provider model. But for now, the much simpler
solution works just fine.
&lt;/p&gt;
&lt;p&gt;
So - to summarize: Make choices which trend towards keeping the code as simple as
possible. Don't add extra features or design elements to handle unknown or fuzzy future
requirements. &lt;strong&gt;Add complexity only when it's really needed&lt;/strong&gt;. While
it's fun to monkey with internal design optimizations etc, keep your eyes on the prize:
software that works for the user. And keep in mind &lt;a href="http://www.codinghorror.com/blog/archives/001137.html"&gt;who
will be maintaining the software&lt;/a&gt; over the long haul - while you may be a whiz
at generics (for example) keep in mind that for many people they tend to make understanding
the code more difficult. 
&lt;/p&gt;
&lt;p&gt;
That's pretty much my take on this, but I'd love to hear your thoughts on keeping
software "simple". How do you decide when to add complexity? How do you define complexity?
&lt;/p&gt;
&lt;h2&gt;Other thoughts on Simplicity:
&lt;/h2&gt;
&lt;p&gt;
&lt;a href="http://www.joelonsoftware.com/items/2006/12/09.html"&gt;Joel On Software: Simplicity&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.codesimplicity.com/archives/23"&gt;The Fourth Law of Software Design:
Complexity vs. Ease of Maintenance&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.jbox.dk/quotations.htm"&gt;Various Quotes on Simplicity in Software
Design&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=7bd84cca-07a3-4e12-9430-ae8fa0d12b06" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;hr&gt;
davebouwman.net weblog - copyright 2005-2008 - licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"&gt; Creative
Commons License. &lt;/a&gt;</description>
      <comments>http://blog.davebouwman.net/CommentView,guid,7bd84cca-07a3-4e12-9430-ae8fa0d12b06.aspx</comments>
      <category>.NET</category>
      <category>Fundamentals</category>
      <category>SQL Server</category>
      <category>Virtual Earth</category>
    </item>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=fa482ae9-352d-43ae-932c-6fdede874b70</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,fa482ae9-352d-43ae-932c-6fdede874b70.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,fa482ae9-352d-43ae-932c-6fdede874b70.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=fa482ae9-352d-43ae-932c-6fdede874b70</wfw:commentRss>
      <slash:comments>8</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <img style="margin: 0px 10px 0px 0px" height="219" alt="vista" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/UpgradingtoVista64_D4E5/vista_60027ea1-f326-48e0-b85c-74a64c8d9fd6.png" width="219" align="left" border="0" /> I
was running into a LOT of weirdness with my Windows Xp installation, so I figured
I'd upgrade to Vista 64 instead of futzing with another re-do of Xp.
</p>
        <p>
I've been running Vista on my notebook an home workstation for about 6 months with
no issues, and with my MSDN subscription, so it's a no-cost thing - just grab the
disk and an authorization code, and let 'er rip.
</p>
        <p>
Hardware Compatibility is one of the first things you should be concerned about when
jumping to the 64-bit platform, but we had pre-planned this to some extent. When we
built out our development boxes, we followed the "<a href="http://www.hanselman.com/blog/TheCodingHorrorUltimateDeveloperRigThrowdownPart2.aspx">CodingHorror
Ultimate Developer Rig</a>" parts list. So other than the quad core CPU, I've
got exactly the same box. Since <a href="http://www.hanselman.com/blog">Scott Hanselman</a> has
been running Vista 64 for a long time, with few issues (here's a link to his podcast
on the <a href="http://www.hanselman.com/blog/HanselminutesPodcast81VistaX64RedoForDevelopers.aspx">Vista
64 Developer Experience</a>) this should go pretty smoothly.
</p>
        <p>
One nice thing about re-paving a machine is you get to clean out all the crud that
accumulates over time. So, as I re-built things, I created a list of all the stuff
I could not live without. 
</p>
        <h2>Vista Components:
</h2>
        <ul>
          <li>
IIS w/ IIS 6 compatibility 
</li>
          <li>
Disable User Access Control - secure, but a hassle 
</li>
        </ul>
        <h2>Development Tools:
</h2>
        <ul>
          <li>
Visual Studio 2008 
</li>
          <li>
            <a href="http://www.aptana.com">Aptana Studio</a> - Javascript / Ajax IDE 
</li>
          <li>
            <a href="http://www.mygenerationsoftware.com/">MyGeneration</a> - free code generation
tool 
</li>
          <li>
            <a href="http://www.mbunit.com/">MbUnit</a> - unit testing on crack 
</li>
          <li>
            <a href="http://www.testdriven.net/">TestDriven.net</a> - Unit Testing harness for
Visual Studio 
</li>
          <li>
            <a href="http://www.roland-weigelt.de/ghostdoc/">GhostDoc</a> - why write your own
Xml comments? 
</li>
        </ul>
        <h2>Productivity:
</h2>
        <ul>
          <li>
Office Enterprise 2007 
</li>
          <li>
Visio 2007 
</li>
          <li>
            <a href="http://www.bayden.com/SlickRun/">Slickrun</a>  - launcher goodness 
</li>
          <li>
            <a href="http://www.foldershare.com">FolderShare</a> - sync folders across multiple
systems 
</li>
          <li>
            <a href="http://notepad-plus.sourceforge.net/">Notepad++</a> - notepad with tabs and
syntax hilighting</li>
          <li>
            <a href="http://www.getfirefox.com">FireFox</a>
            <ul>
              <li>
                <a href="http://www.getfirebug.com">FireBug</a> - must have for Ajax development</li>
              <li>
                <a href="http://www.foxmarks.com/">FoxMarks</a> - sync bookmarks across multiple systems 
</li>
              <li>
                <a href="https://addons.mozilla.org/en-US/firefox/addon/1419">IETab</a> - runs IE
inside FireFox - good for SharePoint 
</li>
            </ul>
          </li>
        </ul>
        <h2>GIS:
</h2>
        <ul>
          <li>
ArcGIS Desktop (Editor) 9.3 Beta 
</li>
          <li>
uDig 
</li>
        </ul>
        <p>
 
</p>
        <p>
So, .NET developers - what other tools do you install on a fresh box?
</p>
        <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=fa482ae9-352d-43ae-932c-6fdede874b70" />
        <br />
        <hr />
        <hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></body>
      <title>Upgrading to Vista 64</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,fa482ae9-352d-43ae-932c-6fdede874b70.aspx</guid>
      <link>http://blog.davebouwman.net/2008/06/23/UpgradingToVista64.aspx</link>
      <pubDate>Mon, 23 Jun 2008 23:02:30 GMT</pubDate>
      <description>&lt;p&gt;
&lt;img style="margin: 0px 10px 0px 0px" height="219" alt="vista" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/UpgradingtoVista64_D4E5/vista_60027ea1-f326-48e0-b85c-74a64c8d9fd6.png" width="219" align="left" border="0" /&gt; I
was running into a LOT of weirdness with my Windows Xp installation, so I figured
I'd upgrade to Vista 64 instead of futzing with another re-do of Xp.
&lt;/p&gt;
&lt;p&gt;
I've been running Vista on my notebook an home workstation for about 6 months with
no issues, and with my MSDN subscription, so it's a no-cost thing - just grab the
disk and an authorization code, and let 'er rip.
&lt;/p&gt;
&lt;p&gt;
Hardware Compatibility is one of the first things you should be concerned about when
jumping to the 64-bit platform, but we had pre-planned this to some extent. When we
built out our development boxes, we followed the &amp;quot;&lt;a href="http://www.hanselman.com/blog/TheCodingHorrorUltimateDeveloperRigThrowdownPart2.aspx"&gt;CodingHorror
Ultimate Developer Rig&lt;/a&gt;&amp;quot; parts list. So other than the quad core CPU, I've
got exactly the same box. Since &lt;a href="http://www.hanselman.com/blog"&gt;Scott Hanselman&lt;/a&gt; has
been running Vista 64 for a long time, with few issues (here's a link to his podcast
on the &lt;a href="http://www.hanselman.com/blog/HanselminutesPodcast81VistaX64RedoForDevelopers.aspx"&gt;Vista
64 Developer Experience&lt;/a&gt;) this should go pretty smoothly.
&lt;/p&gt;
&lt;p&gt;
One nice thing about re-paving a machine is you get to clean out all the crud that
accumulates over time. So, as I re-built things, I created a list of all the stuff
I could not live without. 
&lt;/p&gt;
&lt;h2&gt;Vista Components:
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
IIS w/ IIS 6 compatibility 
&lt;/li&gt;
&lt;li&gt;
Disable User Access Control - secure, but a hassle 
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Development Tools:
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
Visual Studio 2008 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.aptana.com"&gt;Aptana Studio&lt;/a&gt; - Javascript / Ajax IDE 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.mygenerationsoftware.com/"&gt;MyGeneration&lt;/a&gt; - free code generation
tool 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.mbunit.com/"&gt;MbUnit&lt;/a&gt; - unit testing on crack 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.testdriven.net/"&gt;TestDriven.net&lt;/a&gt; - Unit Testing harness for
Visual Studio 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.roland-weigelt.de/ghostdoc/"&gt;GhostDoc&lt;/a&gt; - why write your own
Xml comments? 
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Productivity:
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
Office Enterprise 2007 
&lt;/li&gt;
&lt;li&gt;
Visio 2007 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.bayden.com/SlickRun/"&gt;Slickrun&lt;/a&gt;&amp;#160; - launcher goodness 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.foldershare.com"&gt;FolderShare&lt;/a&gt; - sync folders across multiple
systems 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://notepad-plus.sourceforge.net/"&gt;Notepad++&lt;/a&gt; - notepad with tabs and
syntax hilighting&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.getfirefox.com"&gt;FireFox&lt;/a&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.getfirebug.com"&gt;FireBug&lt;/a&gt; - must have for Ajax development&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.foxmarks.com/"&gt;FoxMarks&lt;/a&gt; - sync bookmarks across multiple systems 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1419"&gt;IETab&lt;/a&gt; - runs IE
inside FireFox - good for SharePoint 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;GIS:
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
ArcGIS Desktop (Editor) 9.3 Beta 
&lt;/li&gt;
&lt;li&gt;
uDig 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
So, .NET developers - what other tools do you install on a fresh box?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=fa482ae9-352d-43ae-932c-6fdede874b70" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;hr&gt;
davebouwman.net weblog - copyright 2005-2008 - licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"&gt; Creative
Commons License. &lt;/a&gt;</description>
      <comments>http://blog.davebouwman.net/CommentView,guid,fa482ae9-352d-43ae-932c-6fdede874b70.aspx</comments>
      <category>Devt Tools</category>
      <category>General</category>
    </item>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=e384527a-0c05-40a3-87a5-0406e0260715</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,e384527a-0c05-40a3-87a5-0406e0260715.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,e384527a-0c05-40a3-87a5-0406e0260715.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=e384527a-0c05-40a3-87a5-0406e0260715</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <img alt="haak" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/MoreonMVCMVPPatterns_7D0D/haak_d8c95710-d807-43d2-946c-966c70daebad.png" width="209" align="left" border="0" height="177" />
          <a href="http://haacked.com/articles/AboutHaacked.aspx">Phil
Haack</a> posted a <a href="http://haacked.com/archive/2008/06/16/everything-you-wanted-to-know-about-mvc-and-mvp-but.aspx">comparison
of MVC and MVP patterns</a> with some zen on how these patterns work in the web.<br /><br /><br /><br /><br /><br /><br /><br /><br /></p>
        <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=e384527a-0c05-40a3-87a5-0406e0260715" />
        <br />
        <hr />
        <hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></body>
      <title>More on MVC / MVP Patterns</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,e384527a-0c05-40a3-87a5-0406e0260715.aspx</guid>
      <link>http://blog.davebouwman.net/2008/06/18/MoreOnMVCMVPPatterns.aspx</link>
      <pubDate>Wed, 18 Jun 2008 14:53:39 GMT</pubDate>
      <description>&lt;p&gt;
&lt;img alt="haak" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/MoreonMVCMVPPatterns_7D0D/haak_d8c95710-d807-43d2-946c-966c70daebad.png" width="209" align="left" border="0" height="177"&gt;&lt;a href="http://haacked.com/articles/AboutHaacked.aspx"&gt;Phil
Haack&lt;/a&gt; posted a &lt;a href="http://haacked.com/archive/2008/06/16/everything-you-wanted-to-know-about-mvc-and-mvp-but.aspx"&gt;comparison
of MVC and MVP patterns&lt;/a&gt; with some zen on how these patterns work in the web.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=e384527a-0c05-40a3-87a5-0406e0260715" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;hr&gt;
davebouwman.net weblog - copyright 2005-2008 - licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"&gt; Creative
Commons License. &lt;/a&gt;</description>
      <comments>http://blog.davebouwman.net/CommentView,guid,e384527a-0c05-40a3-87a5-0406e0260715.aspx</comments>
      <category>.NET</category>
    </item>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=145926c4-dadd-4c1e-8e94-6b31b8233d98</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,145926c4-dadd-4c1e-8e94-6b31b8233d98.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,145926c4-dadd-4c1e-8e94-6b31b8233d98.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=145926c4-dadd-4c1e-8e94-6b31b8233d98</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We recently moved from using Exchange to <a href="http://www.google.com/a/help/intl/en/admins/editions.html">Google
Apps</a>. The transition has gone really smoothly, but there have been a few hurdles
- mainly surrounding synchronization of Mail and Calendar across multiple devices.
</p>
        <p>
While the Google Apps are all web-based, accessing them in a browser is not always
an option - particularly when on airplanes. Additionally - if you rely heavily on
your calendar for reminders like I do, remembering to keep a browser open on your
calendar page is just one step too many. ;-)
</p>
        <p>
So - here's my device situation:
</p>
        <p>
          <img height="231" alt="devices" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/SynchronizingGoogleEmailandCalendaracros_665B/devices_df0f291c-2aca-4f77-82f2-6f0b4793f065.png" width="494" border="0" />  
</p>
        <p>
Under Exchange, my notebook and workstation would connect to Exchange for email and
calendar, and synchronization was automatic. My phone would pick up email via IMAP
to Exchange, but the calendar was synched when I connected the phone to either PC
via a USB cable. Overall pretty good, but the calendar synch to the phone was a little
more involved than I'd like - why not synch over the air?
</p>
        <p>
Anyhow, with the move to Google, I can of course access mail and calendar from all
three via a web browser. This is fine for email on the PC's, but a little less than
optimal for the calendar. Needing to have a calendar open to get reminders is not
good for me. Call me old school, but I like Outlook - as far as email and calendar
go - it works for me.  
</p>
        <h2>Connecting Outlook with Google Apps
</h2>
        <p>
Actually getting a single instance of  Outlook talking to GMail via <a href="http://mail.google.com/support/bin/answer.py?hl=en&amp;ctx=mail&amp;answer=12103">POP</a> or <a href="http://mail.google.com/support/bin/answer.py?hl=en&amp;ctx=mail&amp;answer=75726">IMAP</a> is
pretty easy, and well documented. If you use IMAP, then you can have multiple clients
systems connected and everything is synchronized for you.
</p>
        <p>
The calendar is another matter. For PC's you need to run the Google Calendar Synch,
which will copy items between your local Outlook calendar and a Google Calendar. It
does the sync on a scheduled basis, so there may be some lag, but since you are planning
things in the future, a 10-30 minute lag should not be a big deal.
</p>
        <p>
On my phone, I'm using Mobile Outlook connecting to IMAP for mail, along with <a href="http://www.goosync.com">GooSync</a> keeps
my mobile Calendar in line with my Google Calendar. What's sweet it that this works
bi-directionally - over the air - something which was not an option with our Exchange
setup.
</p>
        <p>
          <img height="517" alt="goog" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/SynchronizingGoogleEmailandCalendaracros_665B/goog_a96cd347-a105-4173-9dc9-d81c1a93b1b8.png" width="533" border="0" />
        </p>
        <p>
If you are thinking about jumping to Google Apps, I'd say go for it. The transition
has been smooth and everything we need is working with a lot less headaches for our
IT staff.
</p>
        <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=145926c4-dadd-4c1e-8e94-6b31b8233d98" />
        <br />
        <hr />
        <hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></body>
      <title>Synchronizing Google Email and Calendar across Devices</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,145926c4-dadd-4c1e-8e94-6b31b8233d98.aspx</guid>
      <link>http://blog.davebouwman.net/2008/06/18/SynchronizingGoogleEmailAndCalendarAcrossDevices.aspx</link>
      <pubDate>Wed, 18 Jun 2008 13:18:43 GMT</pubDate>
      <description>&lt;p&gt;
We recently moved from using Exchange to &lt;a href="http://www.google.com/a/help/intl/en/admins/editions.html"&gt;Google
Apps&lt;/a&gt;. The transition has gone really smoothly, but there have been a few hurdles
- mainly surrounding synchronization of Mail and Calendar across multiple devices.
&lt;/p&gt;
&lt;p&gt;
While the Google Apps are all web-based, accessing them in a browser is not always
an option - particularly when on airplanes. Additionally - if you rely heavily on
your calendar for reminders like I do, remembering to keep a browser open on your
calendar page is just one step too many. ;-)
&lt;/p&gt;
&lt;p&gt;
So - here's my device situation:
&lt;/p&gt;
&lt;p&gt;
&lt;img height="231" alt="devices" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/SynchronizingGoogleEmailandCalendaracros_665B/devices_df0f291c-2aca-4f77-82f2-6f0b4793f065.png" width="494" border="0" /&gt;&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
Under Exchange, my notebook and workstation would connect to Exchange for email and
calendar, and synchronization was automatic. My phone would pick up email via IMAP
to Exchange, but the calendar was synched when I connected the phone to either PC
via a USB cable. Overall pretty good, but the calendar synch to the phone was a little
more involved than I'd like - why not synch over the air?
&lt;/p&gt;
&lt;p&gt;
Anyhow, with the move to Google, I can of course access mail and calendar from all
three via a web browser. This is fine for email on the PC's, but a little less than
optimal for the calendar. Needing to have a calendar open to get reminders is not
good for me. Call me old school, but I like Outlook - as far as email and calendar
go - it works for me.&amp;#160; 
&lt;/p&gt;
&lt;h2&gt;Connecting Outlook with Google Apps
&lt;/h2&gt;
&lt;p&gt;
Actually getting a single instance of&amp;#160; Outlook talking to GMail via &lt;a href="http://mail.google.com/support/bin/answer.py?hl=en&amp;amp;ctx=mail&amp;amp;answer=12103"&gt;POP&lt;/a&gt; or &lt;a href="http://mail.google.com/support/bin/answer.py?hl=en&amp;amp;ctx=mail&amp;amp;answer=75726"&gt;IMAP&lt;/a&gt; is
pretty easy, and well documented. If you use IMAP, then you can have multiple clients
systems connected and everything is synchronized for you.
&lt;/p&gt;
&lt;p&gt;
The calendar is another matter. For PC's you need to run the Google Calendar Synch,
which will copy items between your local Outlook calendar and a Google Calendar. It
does the sync on a scheduled basis, so there may be some lag, but since you are planning
things in the future, a 10-30 minute lag should not be a big deal.
&lt;/p&gt;
&lt;p&gt;
On my phone, I'm using Mobile Outlook connecting to IMAP for mail, along with &lt;a href="http://www.goosync.com"&gt;GooSync&lt;/a&gt; keeps
my mobile Calendar in line with my Google Calendar. What's sweet it that this works
bi-directionally - over the air - something which was not an option with our Exchange
setup.
&lt;/p&gt;
&lt;p&gt;
&lt;img height="517" alt="goog" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/SynchronizingGoogleEmailandCalendaracros_665B/goog_a96cd347-a105-4173-9dc9-d81c1a93b1b8.png" width="533" border="0" /&gt; 
&lt;/p&gt;
&lt;p&gt;
If you are thinking about jumping to Google Apps, I'd say go for it. The transition
has been smooth and everything we need is working with a lot less headaches for our
IT staff.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=145926c4-dadd-4c1e-8e94-6b31b8233d98" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;hr&gt;
davebouwman.net weblog - copyright 2005-2008 - licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"&gt; Creative
Commons License. &lt;/a&gt;</description>
      <comments>http://blog.davebouwman.net/CommentView,guid,145926c4-dadd-4c1e-8e94-6b31b8233d98.aspx</comments>
      <category>Productivity</category>
      <category>Software</category>
    </item>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=b234c347-0d4e-4f7e-ae18-4961f4921488</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,b234c347-0d4e-4f7e-ae18-4961f4921488.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,b234c347-0d4e-4f7e-ae18-4961f4921488.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=b234c347-0d4e-4f7e-ae18-4961f4921488</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Based on the outcome of the <a href="http://blog.davebouwman.net/2008/05/29/DeveloperSurveyDesignPatterns.aspx">Developer
Survey</a>, I thought I' put together some posts on the common patterns referenced
in some of the questions, starting with the Model View Controller (MVC) family.
</p>
        <p>
There has been plenty written about MVC on the formal side of things - here are two
good sources of information - <a href="http://en.wikipedia.org/wiki/Model-view-controller">Wikipedia
MVC entry</a>,  and some <a href="http://martinfowler.com/eaaDev/uiArchs.html#ModelViewController">thoughts</a> from
Martin Fowler.
</p>
        <h2>The Basics
</h2>
        <p>
The MVC family of patterns are about separating the presentation of data from the
business logic surrounding the management of the data. There are many other patterns
based on the key MVC ideas - <a href="http://martinfowler.com/eaaDev/PassiveScreen.html">Passive
View</a>, <a href="http://martinfowler.com/eaaDev/SupervisingPresenter.html">Supervising
Controller</a>, <a href="http://martinfowler.com/eaaDev/SeparatedPresentation.html">Presentation
Model</a> and <a href="http://martinfowler.com/eaaDev/SeparatedPresentation.html">Separated
Presentation</a> are 4 such patterns. The differences are subtle, and all share they
key idea of separating the presentation logic from the business logic, from the data
itself. It's worth noting that the opposite of MVC family is called "Autonomous View"
in which all the logic is in the form itself - so if this is how you are developing,
now you can use a fancy name for it!
</p>
        <p>
Since MVC was one of the first patterns that dealt with this separation, we'll start
with it, and look at the three components... 
</p>
        <h3>Model: 
</h3>
        <p>
The model is the data and it's usually a class. So in GIS-land, it could be a "Parcel"
class, which may have a Geometry property. The important part is that this class has
no dependencies on the presentation layer, or the controller. It's just a dumb data
container. Typically this class will implement one or more interfaces, which the View
and Controller will utilize. Interfaces are used a lot in these patterns, so here's
a link to an <a href="http://www.codeproject.com/KB/cs/abstractsvsinterfaces.aspx">article
that compares Abstract Classes and Interfaces</a> that can serve as a refresher if
needed.
</p>
        <h3>View:
</h3>
        <p>
As the name suggests the View is responsible for organizing and presenting the Model.
Usually this means showing it visually on a form. In order to remove dependencies
between the View and the Model, the View will interact with an interface, instead
of a specific view class - i.e. IParcelFeature instead of "Parcel". The view typically
raises events when the user makes changes in the interface, and exposes properties
allowing the Controller to "see" the model or other state of the view. The View does
not make any changes to the Model itself (in some  MV* patterns does not actually
have visibility of the model - the controller sets all the control values directly,
and responds to all control events). Again, the events and properties of the View
are defined via an interface.
</p>
        <h3>Controller:
</h3>
        <p>
The name conveys things pretty well - this is the business logic component that controls
what actually happens to the model when an event occurs in the view. There may be
multiple controllers that can work with a given class, or multiple model classes that
can work with a given controller. This is where the Interfaces on the Models come
in. If the Controller's "contract" is based on an Interface (IParcelFeature), then
we can use the Controller with any class that implements the interface. Similarly,
the Controller also implements an Interface, which is it's contract with the View.
</p>
        <h2>Pulling it to all together:
</h2>
        <p>
In MVC, the Controller gets a model and a View. It then passed the required data to
the View which renders the UI. When the user interacts with the UI (i.e. clicks a
button), the View raises events, which the Controller responds to by making required
changes to the Model, which is then used to update the View. 
</p>
        <h2>Why Bother?
</h2>
        <p>
So - this is nice, but why separate things out like this? There are a number of reasons.
First is known as <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single
Responsibility</a>. This concept basically says that a class should have one purpose,
and anything not connected with that purpose should be in a separate class. In regards
to the subject at hand, it would tell you to avoid mixing presentation code, with
business logic because they are not actually related.
</p>
        <p>
Another reason for MVC is re-use. If you model your application like this, you can
plug and play the components - particularly the View. So, suppose you need to create
a business application that has a windows forms client for some functionality, a web
client for some other functions, and a web service API. You can build out a model,
a controller, and three views - one for the windows forms application, one for a web
form, and a third (more limited one) for the web service.
</p>
        <p>
A final (and biggest) reason is testability. If you keep the Model (data) separate
from the View (User Interface) which is separate from the Controller (business logic),
writing unit tests becomes much easier. If you've implemented interfaces as the contract
between the components, you can test the components individually. 
</p>
        <h2>The Pain of Testing
</h2>
        <p>
Without getting too deep into unit testing, the basic idea is to have a test harness
which spins up various classes in your code, and executes methods. This gets complicated
because our classes have dependencies on data - stored in databases, shape files,
whatever. If we want to re-run our tests frequently, we want to be sure our test data
is static - otherwise the tests break, and that defeats the purpose. So - the next
best option is to create "fake" static data in our tests. The brute force method would
be to create specific test classes which implement the required interfaces (ISomeView,
ISomeModel etc), but just contain enough logic to complete the test. Depending on
the test you would have an invalid geometry, invalid PIN number or a myriad of other
conditions. This would allow you to create test "Parcels" in your unit test harness,
that you could then pass to the Controller to test it's methods, without actually
connecting to a shape file. You could also create a class that implemented the View
interface, and use that to raise events and ensure that the Controller reacted correctly.
Essentially you can write unit tests for everything but the "click" event handler
in the UI layer. Since that code was likely written for you by the IDE, and it's super
basic, it's not a really high priority for testing.
</p>
        <h2>Easing the Pain of Testing: Dynamic Mocking
</h2>
        <p>
Of course that's a lot of work, and developers hate extra work, so tools were created
to help out. While this is beyond the scope of this post, I'm talking about "mocking"
frameworks, such as <a href="http://www.nmock.org/">NMock</a>, <a href="http://www.ayende.com/projects/rhino-mocks.aspx">RhinoMocks</a> or <a href="http://www.typemock.com/">TypeMock</a>.
These frameworks can create a "test dummy" class that implements a specific 
interface right in the test definition. You basically "record" some values into the
Mock, then pass it into a method, and it can validate behavior. 
</p>
        <p>
Of course you still need to fill up the dynamically mocked Interface with valid data
- and the geometries are likely the scariest thing to start with. So that's where
I started a few years ago.
</p>
        <h2>I can haz code?
</h2>
        <p>
I don't have anything lying around that's easily sharable, but I did post a sample
about Supervising Controller code about a year ago. The code is in VB.NET, with a
Visual Studio 2005 solution, and is oriented towards showing how to create a plug-in
framework, while leveraging Supervising Controller, so that's the gist of the article.
It also does not have any tests, but I'll be posting more leveraging MVC patterns
and unit testing in the future.
</p>
        <p>
          <a href="http://blog.davebouwman.net/2007/06/05/PluginFrameworkSupervisingControllerExample.aspx">Plug-in
Framework &amp; Supervising Controller Example</a> (Article - read this before digging
into the code)
</p>
        <p>
          <a href="http://www.davebouwman.net/sourcecode/pluginUI.zip">Download Sample Code</a>
        </p>
        <h2>Summary
</h2>
        <p>
The idea here was to introduce the main idea of the MVC pattern - separation of behavior
logic from presentation logic, usually to facilitate testing. The actual implementation
of this idea can take many flavors, and can vary in complexity, but the underlying
concept is the same. 
</p>
        <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=b234c347-0d4e-4f7e-ae18-4961f4921488" />
        <br />
        <hr />
        <hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></body>
      <title>Model View Controller Patterns: An Intro</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,b234c347-0d4e-4f7e-ae18-4961f4921488.aspx</guid>
      <link>http://blog.davebouwman.net/2008/06/17/ModelViewControllerPatternsAnIntro.aspx</link>
      <pubDate>Tue, 17 Jun 2008 16:18:00 GMT</pubDate>
      <description>&lt;p&gt;
Based on the outcome of the &lt;a href="http://blog.davebouwman.net/2008/05/29/DeveloperSurveyDesignPatterns.aspx"&gt;Developer
Survey&lt;/a&gt;, I thought I' put together some posts on the common patterns referenced
in some of the questions, starting with the Model View Controller (MVC) family.
&lt;/p&gt;
&lt;p&gt;
There has been plenty written about MVC on the formal side of things - here are two
good sources of information - &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;Wikipedia
MVC entry&lt;/a&gt;,&amp;nbsp; and some &lt;a href="http://martinfowler.com/eaaDev/uiArchs.html#ModelViewController"&gt;thoughts&lt;/a&gt; from
Martin Fowler.
&lt;/p&gt;
&lt;h2&gt;The Basics
&lt;/h2&gt;
&lt;p&gt;
The MVC family of patterns are about separating the presentation of data from the
business logic surrounding the management of the data. There are many other patterns
based on the key MVC ideas - &lt;a href="http://martinfowler.com/eaaDev/PassiveScreen.html"&gt;Passive
View&lt;/a&gt;, &lt;a href="http://martinfowler.com/eaaDev/SupervisingPresenter.html"&gt;Supervising
Controller&lt;/a&gt;, &lt;a href="http://martinfowler.com/eaaDev/SeparatedPresentation.html"&gt;Presentation
Model&lt;/a&gt; and &lt;a href="http://martinfowler.com/eaaDev/SeparatedPresentation.html"&gt;Separated
Presentation&lt;/a&gt; are 4 such patterns. The differences are subtle, and all share they
key idea of separating the presentation logic from the business logic, from the data
itself. It's worth noting that the opposite of MVC family is called "Autonomous View"
in which all the logic is in the form itself - so if this is how you are developing,
now you can use a fancy name for it!
&lt;/p&gt;
&lt;p&gt;
Since MVC was one of the first patterns that dealt with this separation, we'll start
with it, and look at the three components... 
&lt;/p&gt;
&lt;h3&gt;Model: 
&lt;/h3&gt;
&lt;p&gt;
The model is the data and it's usually a class. So in GIS-land, it could be a "Parcel"
class, which may have a Geometry property. The important part is that this class has
no dependencies on the presentation layer, or the controller. It's just a dumb data
container. Typically this class will implement one or more interfaces, which the View
and Controller will utilize. Interfaces are used a lot in these patterns, so here's
a link to an &lt;a href="http://www.codeproject.com/KB/cs/abstractsvsinterfaces.aspx"&gt;article
that compares Abstract Classes and Interfaces&lt;/a&gt; that can serve as a refresher if
needed.
&lt;/p&gt;
&lt;h3&gt;View:
&lt;/h3&gt;
&lt;p&gt;
As the name suggests the View is responsible for organizing and presenting the Model.
Usually this means showing it visually on a form. In order to remove dependencies
between the View and the Model, the View will interact with an interface, instead
of a specific view class - i.e. IParcelFeature instead of "Parcel". The view typically
raises events when the user makes changes in the interface, and exposes properties
allowing the Controller to "see" the model or other state of the view. The View does
not make any changes to the Model itself (in some&amp;nbsp; MV* patterns does not actually
have visibility of the model - the controller sets all the control values directly,
and responds to all control events). Again, the events and properties of the View
are defined via an interface.
&lt;/p&gt;
&lt;h3&gt;Controller:
&lt;/h3&gt;
&lt;p&gt;
The name conveys things pretty well - this is the business logic component that controls
what actually happens to the model when an event occurs in the view. There may be
multiple controllers that can work with a given class, or multiple model classes that
can work with a given controller. This is where the Interfaces on the Models come
in. If the Controller's "contract" is based on an Interface (IParcelFeature), then
we can use the Controller with any class that implements the interface. Similarly,
the Controller also implements an Interface, which is it's contract with the View.
&lt;/p&gt;
&lt;h2&gt;Pulling it to all together:
&lt;/h2&gt;
&lt;p&gt;
In MVC, the Controller gets a model and a View. It then passed the required data to
the View which renders the UI. When the user interacts with the UI (i.e. clicks a
button), the View raises events, which the Controller responds to by making required
changes to the Model, which is then used to update the View. 
&lt;/p&gt;
&lt;h2&gt;Why Bother?
&lt;/h2&gt;
&lt;p&gt;
So - this is nice, but why separate things out like this? There are a number of reasons.
First is known as &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;Single
Responsibility&lt;/a&gt;. This concept basically says that a class should have one purpose,
and anything not connected with that purpose should be in a separate class. In regards
to the subject at hand, it would tell you to avoid mixing presentation code, with
business logic because they are not actually related.
&lt;/p&gt;
&lt;p&gt;
Another reason for MVC is re-use. If you model your application like this, you can
plug and play the components - particularly the View. So, suppose you need to create
a business application that has a windows forms client for some functionality, a web
client for some other functions, and a web service API. You can build out a model,
a controller, and three views - one for the windows forms application, one for a web
form, and a third (more limited one) for the web service.
&lt;/p&gt;
&lt;p&gt;
A final (and biggest) reason is testability. If you keep the Model (data) separate
from the View (User Interface) which is separate from the Controller (business logic),
writing unit tests becomes much easier. If you've implemented interfaces as the contract
between the components, you can test the components individually. 
&lt;/p&gt;
&lt;h2&gt;The Pain of Testing
&lt;/h2&gt;
&lt;p&gt;
Without getting too deep into unit testing, the basic idea is to have a test harness
which spins up various classes in your code, and executes methods. This gets complicated
because our classes have dependencies on data - stored in databases, shape files,
whatever. If we want to re-run our tests frequently, we want to be sure our test data
is static - otherwise the tests break, and that defeats the purpose. So - the next
best option is to create "fake" static data in our tests. The brute force method would
be to create specific test classes which implement the required interfaces (ISomeView,
ISomeModel etc), but just contain enough logic to complete the test. Depending on
the test you would have an invalid geometry, invalid PIN number or a myriad of other
conditions. This would allow you to create test "Parcels" in your unit test harness,
that you could then pass to the Controller to test it's methods, without actually
connecting to a shape file. You could also create a class that implemented the View
interface, and use that to raise events and ensure that the Controller reacted correctly.
Essentially you can write unit tests for everything but the "click" event handler
in the UI layer. Since that code was likely written for you by the IDE, and it's super
basic, it's not a really high priority for testing.
&lt;/p&gt;
&lt;h2&gt;Easing the Pain of Testing: Dynamic Mocking
&lt;/h2&gt;
&lt;p&gt;
Of course that's a lot of work, and developers hate extra work, so tools were created
to help out. While this is beyond the scope of this post, I'm talking about "mocking"
frameworks, such as &lt;a href="http://www.nmock.org/"&gt;NMock&lt;/a&gt;, &lt;a href="http://www.ayende.com/projects/rhino-mocks.aspx"&gt;RhinoMocks&lt;/a&gt; or &lt;a href="http://www.typemock.com/"&gt;TypeMock&lt;/a&gt;.
These frameworks can create a "test dummy" class that implements a specific&amp;nbsp;
interface right in the test definition. You basically "record" some values into the
Mock, then pass it into a method, and it can validate behavior. 
&lt;/p&gt;
&lt;p&gt;
Of course you still need to fill up the dynamically mocked Interface with valid data
- and the geometries are likely the scariest thing to start with. So that's where
I started a few years ago.
&lt;/p&gt;
&lt;h2&gt;I can haz code?
&lt;/h2&gt;
&lt;p&gt;
I don't have anything lying around that's easily sharable, but I did post a sample
about Supervising Controller code about a year ago. The code is in VB.NET, with a
Visual Studio 2005 solution, and is oriented towards showing how to create a plug-in
framework, while leveraging Supervising Controller, so that's the gist of the article.
It also does not have any tests, but I'll be posting more leveraging MVC patterns
and unit testing in the future.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.davebouwman.net/2007/06/05/PluginFrameworkSupervisingControllerExample.aspx"&gt;Plug-in
Framework &amp;amp; Supervising Controller Example&lt;/a&gt; (Article - read this before digging
into the code)
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.davebouwman.net/sourcecode/pluginUI.zip"&gt;Download Sample Code&lt;/a&gt;
&lt;/p&gt;
&lt;h2&gt;Summary
&lt;/h2&gt;
&lt;p&gt;
The idea here was to introduce the main idea of the MVC pattern - separation of behavior
logic from presentation logic, usually to facilitate testing. The actual implementation
of this idea can take many flavors, and can vary in complexity, but the underlying
concept is the same. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=b234c347-0d4e-4f7e-ae18-4961f4921488" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;hr&gt;
davebouwman.net weblog - copyright 2005-2008 - licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"&gt; Creative
Commons License. &lt;/a&gt;</description>
      <comments>http://blog.davebouwman.net/CommentView,guid,b234c347-0d4e-4f7e-ae18-4961f4921488.aspx</comments>
      <category>.NET</category>
      <category>Unit Testing</category>
    </item>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=78658ccf-8635-418e-a5fa-55c4fa427f77</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,78658ccf-8635-418e-a5fa-55c4fa427f77.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,78658ccf-8635-418e-a5fa-55c4fa427f77.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=78658ccf-8635-418e-a5fa-55c4fa427f77</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We just put up another <a href="http://65.101.234.201/txfire/">"demo" site</a> -
this time working with <a href="http://www.sanborn.com">Sanborn</a> to provide visualization
for their wildfire risk model outputs they have created for the <a href="http://txforestservice.tamu.edu/main/default.aspx?dept=frp">Texas
Forest Service</a>. For information on the data, there is contact information on the
"About" tab.
</p>
        <p>
          <a href="http://65.101.234.201/txfire/">
            <img height="334" alt="txfire" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/TexasWildfireRiskVisualization_121E6/txfire_11ebbc5b-96c4-47bb-a5cd-8a7f83659e89.png" width="500" border="0" />
          </a>
        </p>
        <p>
From a technical stand-point, we added a few new features to this viewer... 
</p>
        <h2>Dealing with Multiple Tile Layers
</h2>
        <p>
The viewer is pulling in multiple tile services, representing multiple layers in a
map, as opposed to a single "fused" tile layer. This is the first time I've
implemented multiple layers using the ArcGIS Server Tile Cache code, and it turns
out it's currently a bit of a pain. For this site, we've got 7 tile layers, and to
do that with the current tile server code, I needed to create 7 map services (mxd's),
and then configure 7 tile services in the TileServer. Clearly this should be streamlined.
For example, the url <a title="http://65.101.234.201/tileservice/txfirewfsi/023131001.ashx" href="http://65.101.234.201/tileservice/txfirewfsi/023131001.ashx">http://65.101.234.201/tileservice/txfirewfsi/023131001.ashx</a> pulls
a specific tile from the txfirewfsi tile service. (shown below)
</p>
        <img alt="Tile" src="http://65.101.234.201/tileservice/txfirewfsi/023131001.ashx" />
        <p>
However, I'm thinking that it would be nice to be able to add a layer name in the
url -'parcels' in this case -   <a href="http://65.101.234.201/tileservice/txbasemap/parcels/023133.ashx">http://65.101.234.201/tileservice/txbasemap/<strong>parcels</strong>/023133.ashx</a>.
This way you could specify the fused tiles, or just a specific layer.
</p>
        <h2>Adjusting Layer Transparency
</h2>
        <p>
This was easy, if not obvious. Adding in a Dojo.slider, and hooking up some events
was pretty simple. However, it turns out that changing the .Opacity property of a <a href="http://msdn.microsoft.com/en-us/library/bb429539.aspx">VETileSourceSpecification</a> has
no effect after the layer has been added to map. Instead you need to delete the layer
and re-add it with the new opacity. Since the browser is caching the tiles, this is
actually very fast.
</p>
        <p>
          <img height="234" alt="trans" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/TexasWildfireRiskVisualization_121E6/trans_7cc5991d-521c-4925-80a0-fdafdf8d6317.png" width="486" border="0" />
        </p>
        <h2>Virtual Earth 3D
</h2>
        <p>
This was also the first time I tried throwing things into 3D mode. It took a few quick
tweaks in the javascript, and some different CSS for the markers, but for the most
part - it "just worked".
</p>
        <p>
          <img height="240" alt="tx-3d" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/TexasWildfireRiskVisualization_121E6/tx-3d_62837332-521e-4e81-8b8e-9887a0070c8f.png" width="299" border="0" />
        </p>
        <p>
There are a few issues with the dojo menus that I'm going to sort out so I'll save
the Url for the 3d page until that's dialed.
</p>
        <p>
So, this took about 3 days to pull together -- if you are looking under the covers,
the code is VERY "demo" and has some issues - there are a few weird things
with the layer list checkboxes and I have not really tested in IE7, and all bets are
off with IE6. I'd love to hear thoughts &amp; ideas though.
</p>
        <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=78658ccf-8635-418e-a5fa-55c4fa427f77" />
        <br />
        <hr />
        <hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></body>
      <title>Texas Wildfire Risk Visualization Demo Site</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,78658ccf-8635-418e-a5fa-55c4fa427f77.aspx</guid>
      <link>http://blog.davebouwman.net/2008/06/13/TexasWildfireRiskVisualizationDemoSite.aspx</link>
      <pubDate>Fri, 13 Jun 2008 03:53:19 GMT</pubDate>
      <description>&lt;p&gt;
We just put up another &lt;a href="http://65.101.234.201/txfire/"&gt;&amp;quot;demo&amp;quot; site&lt;/a&gt; -
this time working with &lt;a href="http://www.sanborn.com"&gt;Sanborn&lt;/a&gt; to provide visualization
for their wildfire risk model outputs they have created for the &lt;a href="http://txforestservice.tamu.edu/main/default.aspx?dept=frp"&gt;Texas
Forest Service&lt;/a&gt;. For information on the data, there is contact information on the
&amp;quot;About&amp;quot; tab.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://65.101.234.201/txfire/"&gt;&lt;img height="334" alt="txfire" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/TexasWildfireRiskVisualization_121E6/txfire_11ebbc5b-96c4-47bb-a5cd-8a7f83659e89.png" width="500" border="0" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
From a technical stand-point, we added a few new features to this viewer... 
&lt;/p&gt;
&lt;h2&gt;Dealing with Multiple Tile Layers
&lt;/h2&gt;
&lt;p&gt;
The viewer is pulling in multiple tile services, representing multiple layers in a
map, as opposed to a single &amp;quot;fused&amp;quot; tile layer. This is the first time I've
implemented multiple layers using the ArcGIS Server Tile Cache code, and it turns
out it's currently a bit of a pain. For this site, we've got 7 tile layers, and to
do that with the current tile server code, I needed to create 7 map services (mxd's),
and then configure 7 tile services in the TileServer. Clearly this should be streamlined.
For example, the url &lt;a title="http://65.101.234.201/tileservice/txfirewfsi/023131001.ashx" href="http://65.101.234.201/tileservice/txfirewfsi/023131001.ashx"&gt;http://65.101.234.201/tileservice/txfirewfsi/023131001.ashx&lt;/a&gt; pulls
a specific tile from the txfirewfsi tile service. (shown below)
&lt;/p&gt;
&lt;img alt="Tile" src="http://65.101.234.201/tileservice/txfirewfsi/023131001.ashx" /&gt; 
&lt;p&gt;
However, I'm thinking that it would be nice to be able to add a layer name in the
url -'parcels' in this case -&amp;#160;&amp;#160; &lt;a href="http://65.101.234.201/tileservice/txbasemap/parcels/023133.ashx"&gt;http://65.101.234.201/tileservice/txbasemap/&lt;strong&gt;parcels&lt;/strong&gt;/023133.ashx&lt;/a&gt;.
This way you could specify the fused tiles, or just a specific layer.
&lt;/p&gt;
&lt;h2&gt;Adjusting Layer Transparency
&lt;/h2&gt;
&lt;p&gt;
This was easy, if not obvious. Adding in a Dojo.slider, and hooking up some events
was pretty simple. However, it turns out that changing the .Opacity property of a &lt;a href="http://msdn.microsoft.com/en-us/library/bb429539.aspx"&gt;VETileSourceSpecification&lt;/a&gt; has
no effect after the layer has been added to map. Instead you need to delete the layer
and re-add it with the new opacity. Since the browser is caching the tiles, this is
actually very fast.
&lt;/p&gt;
&lt;p&gt;
&lt;img height="234" alt="trans" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/TexasWildfireRiskVisualization_121E6/trans_7cc5991d-521c-4925-80a0-fdafdf8d6317.png" width="486" border="0" /&gt; 
&lt;/p&gt;
&lt;h2&gt;Virtual Earth 3D
&lt;/h2&gt;
&lt;p&gt;
This was also the first time I tried throwing things into 3D mode. It took a few quick
tweaks in the javascript, and some different CSS for the markers, but for the most
part - it &amp;quot;just worked&amp;quot;.
&lt;/p&gt;
&lt;p&gt;
&lt;img height="240" alt="tx-3d" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/TexasWildfireRiskVisualization_121E6/tx-3d_62837332-521e-4e81-8b8e-9887a0070c8f.png" width="299" border="0" /&gt; 
&lt;/p&gt;
&lt;p&gt;
There are a few issues with the dojo menus that I'm going to sort out so I'll save
the Url for the 3d page until that's dialed.
&lt;/p&gt;
&lt;p&gt;
So, this took about 3 days to pull together -- if you are looking under the covers,
the code is VERY &amp;quot;demo&amp;quot; and has some issues - there are a few weird things
with the layer list checkboxes and I have not really tested in IE7, and all bets are
off with IE6. I'd love to hear thoughts &amp;amp; ideas though.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=78658ccf-8635-418e-a5fa-55c4fa427f77" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;hr&gt;
davebouwman.net weblog - copyright 2005-2008 - licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"&gt; Creative
Commons License. &lt;/a&gt;</description>
      <comments>http://blog.davebouwman.net/CommentView,guid,78658ccf-8635-418e-a5fa-55c4fa427f77.aspx</comments>
      <category>Dojo</category>
      <category>Virtual Earth</category>
    </item>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=39c46c08-0b8a-43c4-ad83-7f17e92b4fc5</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,39c46c08-0b8a-43c4-ad83-7f17e92b4fc5.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,39c46c08-0b8a-43c4-ad83-7f17e92b4fc5.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=39c46c08-0b8a-43c4-ad83-7f17e92b4fc5</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Just a quick note that if you've ever run into trouble keeping things positioned correctly
in your browser app, take a look at <a href="http://api.dojotoolkit.org/jsdoc/dojo/HEAD/dojo.coords">dojo.coords</a>.
(ok, the doc is limited, but poke around with FireBug, and it's pretty easy to see
what it does)
</p>
        <p>
Basically this allows you to get the top, left, width, height, x and y for any element
on your page. I was having issues with my Dojo slider control's positioning when added
into the Virtual Earth control via map.AddControl. Basically the control loads just
fine initially...
</p>
        <p>
          <img height="283" alt="initial-pos" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/Dojo.CoordsGoodness_97BC/initial-pos_dff4c141-bdb3-4a61-8c44-922f0adb1b4a.png" width="272" border="0" />
        </p>
        <p>
But when the browser window is re-sized, the control remains absolutely positioned
on the page, rather than relative to the container (the VE control), as can be seen
below. 
</p>
        <p>
          <img height="267" alt="after-resize" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/Dojo.CoordsGoodness_97BC/after-resize_aca0b487-f6ba-49b1-9c46-de6d6694995d.png" width="277" border="0" />
        </p>
        <p>
 
</p>
        <p>
Setting the CSS postition:relative, does not work at all, so the solution was to write
a little code that would respond to the browser re-size event, and re-position the
control. Hooking to the resize event is very easy with dojo.connect...  
</p>
        <p>
dojo.connect(window, 'onresize', positionZoomSlider);
</p>
        <p>
Getting the correct position values in order to calculate the correct position was
also easy when using dojo.coords... here's the function that positions my slider.
</p>
        <p>
function positionZoomSlider() {<br />
            //This is needed
because the dojo slider seems to always be absolutely positioned.<br />
            //so we attach
this to the browser re-size so when things move around, the slider<br />
            //is repositioned
correctly.            
<br />
            var control = $get('verticalZoomContainer');<br />
            control.style.top
=  dojo.coords(dojo.byId('contentContainer')).t + 30 + "px"; 
<br />
            control.style.left
= dojo.coords(dojo.byId('contentContainer')).l + 20 + "px"; 
<br />
        } <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=39c46c08-0b8a-43c4-ad83-7f17e92b4fc5" /><br /><hr /><hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></p>
      </body>
      <title>Dojo.Coords Goodness</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,39c46c08-0b8a-43c4-ad83-7f17e92b4fc5.aspx</guid>
      <link>http://blog.davebouwman.net/2008/06/11/DojoCoordsGoodness.aspx</link>
      <pubDate>Wed, 11 Jun 2008 16:47:32 GMT</pubDate>
      <description>&lt;p&gt;
Just a quick note that if you've ever run into trouble keeping things positioned correctly
in your browser app, take a look at &lt;a href="http://api.dojotoolkit.org/jsdoc/dojo/HEAD/dojo.coords"&gt;dojo.coords&lt;/a&gt;.
(ok, the doc is limited, but poke around with FireBug, and it's pretty easy to see
what it does)
&lt;/p&gt;
&lt;p&gt;
Basically this allows you to get the top, left, width, height, x and y for any element
on your page. I was having issues with my Dojo slider control's positioning when added
into the Virtual Earth control via map.AddControl. Basically the control loads just
fine initially...
&lt;/p&gt;
&lt;p&gt;
&lt;img height="283" alt="initial-pos" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/Dojo.CoordsGoodness_97BC/initial-pos_dff4c141-bdb3-4a61-8c44-922f0adb1b4a.png" width="272" border="0"&gt; 
&lt;/p&gt;
&lt;p&gt;
But when the browser window is re-sized, the control remains absolutely positioned
on the page, rather than relative to the container (the VE control), as can be seen
below. 
&lt;/p&gt;
&lt;p&gt;
&lt;img height="267" alt="after-resize" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/Dojo.CoordsGoodness_97BC/after-resize_aca0b487-f6ba-49b1-9c46-de6d6694995d.png" width="277" border="0"&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Setting the CSS postition:relative, does not work at all, so the solution was to write
a little code that would respond to the browser re-size event, and re-position the
control. Hooking to the resize event is very easy with dojo.connect...&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
dojo.connect(window, 'onresize', positionZoomSlider);
&lt;/p&gt;
&lt;p&gt;
Getting the correct position values in order to calculate the correct position was
also easy when using dojo.coords... here's the function that positions my slider.
&lt;/p&gt;
&lt;p&gt;
function positionZoomSlider() {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //This is needed
because the dojo slider seems to always be absolutely positioned.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //so we attach
this to the browser re-size so when things move around, the slider&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //is repositioned
correctly.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var control = $get('verticalZoomContainer');&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; control.style.top
=&amp;nbsp; dojo.coords(dojo.byId('contentContainer')).t + 30 + "px"; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; control.style.left
= dojo.coords(dojo.byId('contentContainer')).l + 20 + "px"; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=39c46c08-0b8a-43c4-ad83-7f17e92b4fc5" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;hr&gt;
davebouwman.net weblog - copyright 2005-2008 - licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"&gt; Creative
Commons License. &lt;/a&gt;</description>
      <comments>http://blog.davebouwman.net/CommentView,guid,39c46c08-0b8a-43c4-ad83-7f17e92b4fc5.aspx</comments>
      <category>Dojo</category>
    </item>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=1c2f34d7-efd8-4be2-90d0-63102d38533d</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,1c2f34d7-efd8-4be2-90d0-63102d38533d.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,1c2f34d7-efd8-4be2-90d0-63102d38533d.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=1c2f34d7-efd8-4be2-90d0-63102d38533d</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
So I've been using the Dojo toolkit for a while now, but mainly for the Dijit and
DojoX UI components.  For the actual Ajax communication layer,  I've been
relying on the Microsoft Ajax framework because of it's seamless integration with
the ASP.NET Web Service model. Since I've got the whole mess of Dojo already being
loaded into the browser, I figured I should drop the crutches, and work out how to
work directly with the Dojo ajax framework. 
</p>
        <p>
The one downside of this is that you no longer get the client side proxies for your
ASP.NET Web Services. Thus today's article - how to directly access an ASP.NET JSON
Web Service using dojo.xhrGet. 
</p>
        <h2>Part 1: Create a Web Service
</h2>
        <p>
This is pretty simple - just add a web service to your web site. I tend to put the
code right in the asmx file, rather than in the code-behind in app_code, but that's
just personal preference.
</p>
        <pre class="code">
          <span style="background: #ffee62">&lt;%</span>
          <span style="color: blue">@ </span>
          <span style="color: #a31515">WebService </span>
          <span style="color: red">Language</span>
          <span style="color: blue">="C#" </span>
          <span style="color: red">Class</span>
          <span style="color: blue">="ASPWebService" </span>
          <span style="background: #ffee62">%&gt; </span>
          <span style="color: blue">using </span>System; <span style="color: blue">using </span>System.Web; <span style="color: blue">using </span>System.Web.Services; <span style="color: blue">using </span>System.Web.Services.Protocols;
[<span style="color: #2b91af">WebService</span>(Namespace = <span style="color: #a31515">"http://tempuri.org/"</span>)]
[<span style="color: #2b91af">WebServiceBinding</span>(ConformsTo = <span style="color: #2b91af">WsiProfiles</span>.BasicProfile1_1)] <span style="color: blue">public
class </span><span style="color: #2b91af">ASPWebService </span>: System.Web.Services.<span style="color: #2b91af">WebService </span>{
[<span style="color: #2b91af">WebMethod</span>] <span style="color: blue">public string </span>SayHello()
{ <span style="color: blue">return </span><span style="color: #a31515">"Hello
to Dojo " </span>+ <span style="color: #2b91af">DateTime</span>.Now.ToLongDateString();
} }</pre>
        <a href="http://11011.net/software/vspaste">
        </a>
        <p>
 
</p>
        <p>
By default your web service will be configured to "speak" SOAP, which is
fine if you are consuming it from another application, but for Ajax based browser
apps, it's much easier to work with JSON. 
</p>
        <h2>Part 2: JSON-ify the Web Service
</h2>
        <p>
This is actually really simple - just include System.Web.Script.Services, and the
[ScriptService] attribute to the web service as shown below.
</p>
        <pre class="code">
          <span style="background: #ffee62">&lt;%</span>
          <span style="color: blue">@ </span>
          <span style="color: #a31515">WebService </span>
          <span style="color: red">Language</span>
          <span style="color: blue">="C#" </span>
          <span style="color: red">Class</span>
          <span style="color: blue">="ASPWebService" </span>
          <span style="background: #ffee62">%&gt; </span>
          <span style="color: blue">using </span>System; <span style="color: blue">using </span>System.Web; <span style="color: blue">using </span>System.Web.Services; <span style="color: blue">using </span>System.Web.Services.Protocols; <strong><span style="color: blue">using </span>System.Web.Script.Services;</strong> [<span style="color: #2b91af">WebService</span>(Namespace
= <span style="color: #a31515">"http://tempuri.org/"</span>)] [<span style="color: #2b91af">WebServiceBinding</span>(ConformsTo
= <span style="color: #2b91af">WsiProfiles</span>.BasicProfile1_1)] [<span style="color: #2b91af">ScriptService</span>] <span style="color: blue">public
class </span><span style="color: #2b91af">ASPWebService </span>: System.Web.Services.<span style="color: #2b91af">WebService </span>{
[<span style="color: #2b91af">WebMethod</span>] [<span style="color: #2b91af">ScriptMethod</span>(ResponseFormat
= <span style="color: #2b91af">ResponseFormat</span>.Json, UseHttpGet=<span style="color: blue">true</span>)] <span style="color: blue">public
string </span>SayHello() { <span style="color: blue">return </span><span style="color: #a31515">"Hello
to Dojo " </span>+ <span style="color: #2b91af">DateTime</span>.Now.ToLongDateString();
} }</pre>
        <a href="http://11011.net/software/vspaste">
        </a>
        <a href="http://11011.net/software/vspaste">
        </a>
        <p>
We also add a [ScriptMethod] attribute to the WebMethod. We do this for two reasons
- first, we want to specify that the response  format should be JSON, and we
also want to allow access to this method via http Get's (this is disabled by default).
</p>
        <p>
At this point you can hit the web service in your web browser, and get the standard
Web Service browser. But if you also stick /js on the end of the url, you will get
the client side Javascript that integrates with the MS Ajax Framework. But we're trying
to work with Dojo, so we'll move on... 
</p>
        <h2>Part 3: Testing the Service in a Browser
</h2>
        <p>
Our simple "SayHello" web method does not take any arguments, so we should
be able to just "GET" it via a browser.
</p>
        <p>
The tricky bit that took me some time to sleuth down was that you also need to edit
web.config to tell the web service to respond to all Gets and Posts. Add this section
(just copy out the parts you are missing - do not paste this whole thing into your
web.config or you will get an error!):
</p>
        <pre class="code">
          <span style="color: blue">&lt;</span>
          <span style="color: #a31515">system.web</span>
          <span style="color: blue">&gt;
&lt;</span>
          <span style="color: #a31515">webServices</span>
          <span style="color: blue">&gt;
&lt;</span>
          <span style="color: #a31515">protocols</span>
          <span style="color: blue">&gt;
&lt;</span>
          <span style="color: #a31515">add </span>
          <span style="color: red">name</span>
          <span style="color: blue">=</span>"<span style="color: blue">HttpGet</span>"<span style="color: blue">/&gt;
&lt;</span><span style="color: #a31515">add </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">HttpPost</span>"<span style="color: blue">/&gt;
&lt;/</span><span style="color: #a31515">protocols</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">webServices</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span></pre>
        <p>
          <span style="color: blue">
          </span>
        </p>
        <a href="http://11011.net/software/vspaste">
        </a>
        <p>
        </p>
        <p>
Once you do this, you will get the response back. Despite the fact that we have used
the [ScriptMethod] attribute to specify that the SayHello web method should return
Json, this will only occur if you sent the request content-type to "application/json;
charset=utf-8". Without that, you'll still get xml.
</p>
        <h2>Part 4: Create a Simple Page
</h2>
        <p>
For this, I created about the simplest page I could - just a button and a div that
will be updated. Here's the whole page...
</p>
        <pre class="code">
          <span style="color: blue">&lt;!</span>
          <span style="color: #a31515">DOCTYPE </span>
          <span style="color: red">html
PUBLIC </span>
          <span style="color: blue">"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;</span>
          <span style="color: #a31515">html </span>
          <span style="color: red">xmlns</span>
          <span style="color: blue">="http://www.w3.org/1999/xhtml"&gt;
&lt;</span>
          <span style="color: #a31515">head</span>
          <span style="color: blue">&gt;
&lt;</span>
          <span style="color: #a31515">title</span>
          <span style="color: blue">&gt;</span>Dojo
to ASP.NET WebServices<span style="color: blue">&lt;/</span><span style="color: #a31515">title</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">script </span><span style="color: red">type</span><span style="color: blue">="text/javascript" </span><span style="color: red">src</span><span style="color: blue">="http://o.aolcdn.com/dojo/1.1.1/dojo/dojo.xd.js" </span><span style="color: red">djConfig</span><span style="color: blue">="parseOnLoad:true,
isDebug:true"&gt;&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">script </span><span style="color: red">type</span><span style="color: blue">="text/javascript"&gt;
function </span>updateSampleOne(){ <span style="color: blue">var </span>contentNode
= dojo.byId(<span style="color: #a31515">"sampleone"</span>); dojo.xhrGet({
url: <span style="color: #a31515">"./ASPWebService.asmx/SayHello"</span>,
handleAs: <span style="color: #a31515">"json"</span>, contentType: <span style="color: #a31515">"application/json;
charset=utf-8"</span>, load: <span style="color: blue">function</span>(data,args){contentNode.innerHTML
= data.d;}, error: <span style="color: blue">function</span>(error,args){console.warn(<span style="color: #a31515">"error!"</span>,error);}
}); }; <span style="color: blue">&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">head</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">h1</span><span style="color: blue">&gt;</span>Using
Dojo to Consume ASP.NET JSON WebServices<span style="color: blue">&lt;/</span><span style="color: #a31515">h1</span><span style="color: blue">&gt;
&lt;</span><span style="color: #a31515">input </span><span style="color: red">id</span><span style="color: blue">="btGetString" </span><span style="color: red">type</span><span style="color: blue">="button" </span><span style="color: red">value</span><span style="color: blue">="Update" </span><span style="color: red">onclick</span><span style="color: blue">="updateSampleOne();"
/&gt; &lt;</span><span style="color: #a31515">div </span><span style="color: red">id</span><span style="color: blue">="sampleone"&gt;</span>This
will update<span style="color: blue">&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">body</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">html</span><span style="color: blue">&gt;</span></pre>
        <a href="http://11011.net/software/vspaste">
        </a>
        <a href="http://11011.net/software/vspaste">
        </a>
        <p>
Breaking down the dojo code...
</p>
        <p>
          <span style="color: blue">var </span>contentNode = dojo.byId(<span style="color: #a31515">"sampleone"</span>);
</p>
        <p>
This simply get's a the div that we'll be updating.
</p>
        <pre class="code">dojo.xhrGet({
  url: <span style="color: #a31515">"./ASPWebService.asmx/SayHello"</span>,
handleAs: <span style="color: #a31515">"json"</span>, contentType: <span style="color: #a31515">"application/json;
charset=utf-8"</span>, load: <span style="color: blue">function</span>(data,args){contentNode.innerHTML
= data.d;}, error: <span style="color: blue">function</span>(error,args){console.warn(<span style="color: #a31515">"error!"</span>,error);}
});</pre>
        <a href="http://11011.net/software/vspaste">
        </a>
        <p>
This is the actual ajax xhr request. Since we are using a GET, we are using dojo.xhrGet. 
</p>
        <p>
The Url of our web service is the asmx file followed by the name of the web method.
Since it's located in the same folder as this html file, we reference it as ./ASPWebService.asmx/SayHello.
</p>
        <p>
The response will be json, so we set handleAs to json
</p>
        <p>
We set the contentType to "application/json; charset=utf-8" as per the <a href="http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx">ASP.NET
security requirements</a>.
</p>
        <p>
When the response returns, we need to do something with it, this is where load comes
in. Dojo uses anonymous functions a lot, and for a simple situation like this, it's
pretty easy to follow. The returned JSON is:
</p>
        <p>
{"d":"Hello to Dojo Tuesday, June 03, 2008"}. 
</p>
        <p>
So we set the contentNode.innerHTML is set to data.d 
</p>
        <p>
Should an error occur, the error function is called.
</p>
        <h2>Summary:
</h2>
        <p>
So - while this is a little more convoluted than just using the MS Ajax client library
and the Script Manager, it does save us from loading multiple client-side frameworks.
Since I'm using Dojo for many other UI components, it seemed a waste to also drag
along MS Ajax when this is a viable alternative.
</p>
        <p>
One may ask why use the ASP.NET Web Services model? Well, from the server side it's
pretty easy to work with. Once a service is created you can access it via Json or
SOAP. They are also easy to unit test.
</p>
        <p>
I'll likely extend this with some more complex examples - like submitting a form,
or sending / receiving complex types, but I'll leave it here for now.
</p>
        <p>
          <a href="http://www.davebouwman.net/sourcecode/DojoService.zip">Download the sample
code</a>
        </p>
        <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=1c2f34d7-efd8-4be2-90d0-63102d38533d" />
        <br />
        <hr />
        <hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></body>
      <title>Accessing ASP.NET Web Services with dojo.xhrGet</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,1c2f34d7-efd8-4be2-90d0-63102d38533d.aspx</guid>
      <link>http://blog.davebouwman.net/2008/06/10/AccessingASPNETWebServicesWithDojoxhrGet.aspx</link>
      <pubDate>Tue, 10 Jun 2008 03:06:12 GMT</pubDate>
      <description>&lt;p&gt;
So I've been using the Dojo toolkit for a while now, but mainly for the Dijit and
DojoX UI components.&amp;#160; For the actual Ajax communication layer,&amp;#160; I've been
relying on the Microsoft Ajax framework because of it's seamless integration with
the ASP.NET Web Service model. Since I've got the whole mess of Dojo already being
loaded into the browser, I figured I should drop the crutches, and work out how to
work directly with the Dojo ajax framework. 
&lt;/p&gt;
&lt;p&gt;
The one downside of this is that you no longer get the client side proxies for your
ASP.NET Web Services. Thus today's article - how to directly access an ASP.NET JSON
Web Service using dojo.xhrGet. 
&lt;/p&gt;
&lt;h2&gt;Part 1: Create a Web Service
&lt;/h2&gt;
&lt;p&gt;
This is pretty simple - just add a web service to your web site. I tend to put the
code right in the asmx file, rather than in the code-behind in app_code, but that's
just personal preference.
&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: #a31515"&gt;WebService &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ASPWebService&amp;quot; &lt;/span&gt;&lt;span style="background: #ffee62"&gt;%&amp;gt; &lt;/span&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System; &lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web; &lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.Services; &lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.Services.Protocols;
[&lt;span style="color: #2b91af"&gt;WebService&lt;/span&gt;(Namespace = &lt;span style="color: #a31515"&gt;&amp;quot;http://tempuri.org/&amp;quot;&lt;/span&gt;)]
[&lt;span style="color: #2b91af"&gt;WebServiceBinding&lt;/span&gt;(ConformsTo = &lt;span style="color: #2b91af"&gt;WsiProfiles&lt;/span&gt;.BasicProfile1_1)] &lt;span style="color: blue"&gt;public
class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ASPWebService &lt;/span&gt;: System.Web.Services.&lt;span style="color: #2b91af"&gt;WebService &lt;/span&gt;{
[&lt;span style="color: #2b91af"&gt;WebMethod&lt;/span&gt;] &lt;span style="color: blue"&gt;public string &lt;/span&gt;SayHello()
{ &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Hello
to Dojo &amp;quot; &lt;/span&gt;+ &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.ToLongDateString();
} }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; 
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
By default your web service will be configured to &amp;quot;speak&amp;quot; SOAP, which is
fine if you are consuming it from another application, but for Ajax based browser
apps, it's much easier to work with JSON. 
&lt;/p&gt;
&lt;h2&gt;Part 2: JSON-ify the Web Service
&lt;/h2&gt;
&lt;p&gt;
This is actually really simple - just include System.Web.Script.Services, and the
[ScriptService] attribute to the web service as shown below.
&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: #a31515"&gt;WebService &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ASPWebService&amp;quot; &lt;/span&gt;&lt;span style="background: #ffee62"&gt;%&amp;gt; &lt;/span&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System; &lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web; &lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.Services; &lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.Services.Protocols; &lt;strong&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.Script.Services;&lt;/strong&gt; [&lt;span style="color: #2b91af"&gt;WebService&lt;/span&gt;(Namespace
= &lt;span style="color: #a31515"&gt;&amp;quot;http://tempuri.org/&amp;quot;&lt;/span&gt;)] [&lt;span style="color: #2b91af"&gt;WebServiceBinding&lt;/span&gt;(ConformsTo
= &lt;span style="color: #2b91af"&gt;WsiProfiles&lt;/span&gt;.BasicProfile1_1)] [&lt;span style="color: #2b91af"&gt;ScriptService&lt;/span&gt;] &lt;span style="color: blue"&gt;public
class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ASPWebService &lt;/span&gt;: System.Web.Services.&lt;span style="color: #2b91af"&gt;WebService &lt;/span&gt;{
[&lt;span style="color: #2b91af"&gt;WebMethod&lt;/span&gt;] [&lt;span style="color: #2b91af"&gt;ScriptMethod&lt;/span&gt;(ResponseFormat
= &lt;span style="color: #2b91af"&gt;ResponseFormat&lt;/span&gt;.Json, UseHttpGet=&lt;span style="color: blue"&gt;true&lt;/span&gt;)] &lt;span style="color: blue"&gt;public
string &lt;/span&gt;SayHello() { &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Hello
to Dojo &amp;quot; &lt;/span&gt;+ &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.ToLongDateString();
} }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; 
&lt;p&gt;
We also add a [ScriptMethod] attribute to the WebMethod. We do this for two reasons
- first, we want to specify that the response&amp;#160; format should be JSON, and we
also want to allow access to this method via http Get's (this is disabled by default).
&lt;/p&gt;
&lt;p&gt;
At this point you can hit the web service in your web browser, and get the standard
Web Service browser. But if you also stick /js on the end of the url, you will get
the client side Javascript that integrates with the MS Ajax Framework. But we're trying
to work with Dojo, so we'll move on... 
&lt;/p&gt;
&lt;h2&gt;Part 3: Testing the Service in a Browser
&lt;/h2&gt;
&lt;p&gt;
Our simple &amp;quot;SayHello&amp;quot; web method does not take any arguments, so we should
be able to just &amp;quot;GET&amp;quot; it via a browser.
&lt;/p&gt;
&lt;p&gt;
The tricky bit that took me some time to sleuth down was that you also need to edit
web.config to tell the web service to respond to all Gets and Posts. Add this section
(just copy out the parts you are missing - do not paste this whole thing into your
web.config or you will get an error!):
&lt;/p&gt;
&lt;pre class="code"&gt; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.web&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;webServices&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;protocols&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;HttpGet&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;HttpPost&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;protocols&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;webServices&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.web&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;span style="color: blue"&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Once you do this, you will get the response back. Despite the fact that we have used
the [ScriptMethod] attribute to specify that the SayHello web method should return
Json, this will only occur if you sent the request content-type to &amp;quot;application/json;
charset=utf-8&amp;quot;. Without that, you'll still get xml.
&lt;/p&gt;
&lt;h2&gt;Part 4: Create a Simple Page
&lt;/h2&gt;
&lt;p&gt;
For this, I created about the simplest page I could - just a button and a div that
will be updated. Here's the whole page...
&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #a31515"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html
PUBLIC &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot;
&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Dojo
to ASP.NET WebServices&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://o.aolcdn.com/dojo/1.1.1/dojo/dojo.xd.js&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;djConfig&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;parseOnLoad:true,
isDebug:true&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
function &lt;/span&gt;updateSampleOne(){ &lt;span style="color: blue"&gt;var &lt;/span&gt;contentNode
= dojo.byId(&lt;span style="color: #a31515"&gt;&amp;quot;sampleone&amp;quot;&lt;/span&gt;); dojo.xhrGet({
url: &lt;span style="color: #a31515"&gt;&amp;quot;./ASPWebService.asmx/SayHello&amp;quot;&lt;/span&gt;,
handleAs: &lt;span style="color: #a31515"&gt;&amp;quot;json&amp;quot;&lt;/span&gt;, contentType: &lt;span style="color: #a31515"&gt;&amp;quot;application/json;
charset=utf-8&amp;quot;&lt;/span&gt;, load: &lt;span style="color: blue"&gt;function&lt;/span&gt;(data,args){contentNode.innerHTML
= data.d;}, error: &lt;span style="color: blue"&gt;function&lt;/span&gt;(error,args){console.warn(&lt;span style="color: #a31515"&gt;&amp;quot;error!&amp;quot;&lt;/span&gt;,error);}
}); }; &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Using
Dojo to Consume ASP.NET JSON WebServices&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;btGetString&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;button&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Update&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;updateSampleOne();&amp;quot;
/&amp;gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sampleone&amp;quot;&amp;gt;&lt;/span&gt;This
will update&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; 
&lt;p&gt;
Breaking down the dojo code...
&lt;/p&gt;
&lt;p&gt;
&lt;span style="color: blue"&gt;var &lt;/span&gt;contentNode = dojo.byId(&lt;span style="color: #a31515"&gt;&amp;quot;sampleone&amp;quot;&lt;/span&gt;);
&lt;/p&gt;
&lt;p&gt;
This simply get's a the div that we'll be updating.
&lt;/p&gt;
&lt;pre class="code"&gt;dojo.xhrGet({
  url: &lt;span style="color: #a31515"&gt;&amp;quot;./ASPWebService.asmx/SayHello&amp;quot;&lt;/span&gt;,
handleAs: &lt;span style="color: #a31515"&gt;&amp;quot;json&amp;quot;&lt;/span&gt;, contentType: &lt;span style="color: #a31515"&gt;&amp;quot;application/json;
charset=utf-8&amp;quot;&lt;/span&gt;, load: &lt;span style="color: blue"&gt;function&lt;/span&gt;(data,args){contentNode.innerHTML
= data.d;}, error: &lt;span style="color: blue"&gt;function&lt;/span&gt;(error,args){console.warn(&lt;span style="color: #a31515"&gt;&amp;quot;error!&amp;quot;&lt;/span&gt;,error);}
});&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; 
&lt;p&gt;
This is the actual ajax xhr request. Since we are using a GET, we are using dojo.xhrGet. 
&lt;/p&gt;
&lt;p&gt;
The Url of our web service is the asmx file followed by the name of the web method.
Since it's located in the same folder as this html file, we reference it as ./ASPWebService.asmx/SayHello.
&lt;/p&gt;
&lt;p&gt;
The response will be json, so we set handleAs to json
&lt;/p&gt;
&lt;p&gt;
We set the contentType to &amp;quot;application/json; charset=utf-8&amp;quot; as per the &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx"&gt;ASP.NET
security requirements&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
When the response returns, we need to do something with it, this is where load comes
in. Dojo uses anonymous functions a lot, and for a simple situation like this, it's
pretty easy to follow. The returned JSON is:
&lt;/p&gt;
&lt;p&gt;
{&amp;quot;d&amp;quot;:&amp;quot;Hello to Dojo Tuesday, June 03, 2008&amp;quot;}. 
&lt;/p&gt;
&lt;p&gt;
So we set the contentNode.innerHTML is set to data.d 
&lt;/p&gt;
&lt;p&gt;
Should an error occur, the error function is called.
&lt;/p&gt;
&lt;h2&gt;Summary:
&lt;/h2&gt;
&lt;p&gt;
So - while this is a little more convoluted than just using the MS Ajax client library
and the Script Manager, it does save us from loading multiple client-side frameworks.
Since I'm using Dojo for many other UI components, it seemed a waste to also drag
along MS Ajax when this is a viable alternative.
&lt;/p&gt;
&lt;p&gt;
One may ask why use the ASP.NET Web Services model? Well, from the server side it's
pretty easy to work with. Once a service is created you can access it via Json or
SOAP. They are also easy to unit test.
&lt;/p&gt;
&lt;p&gt;
I'll likely extend this with some more complex examples - like submitting a form,
or sending / receiving complex types, but I'll leave it here for now.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.davebouwman.net/sourcecode/DojoService.zip"&gt;Download the sample
code&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=1c2f34d7-efd8-4be2-90d0-63102d38533d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;hr&gt;
davebouwman.net weblog - copyright 2005-2008 - licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"&gt; Creative
Commons License. &lt;/a&gt;</description>
      <comments>http://blog.davebouwman.net/CommentView,guid,1c2f34d7-efd8-4be2-90d0-63102d38533d.aspx</comments>
      <category>ASP.NET</category>
      <category>Dojo</category>
    </item>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=503f8d56-ec1f-48c8-8fd6-ffc39e3ae188</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,503f8d56-ec1f-48c8-8fd6-ffc39e3ae188.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,503f8d56-ec1f-48c8-8fd6-ffc39e3ae188.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=503f8d56-ec1f-48c8-8fd6-ffc39e3ae188</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <img style="margin: 0px 5px 0px 0px;" alt="mic_thumb" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/VerySpatialPodcastInterview_12708/mic_thumb_e6a5d025-32d4-4d06-8be0-d2173aae8f7b.gif" align="left" border="0" height="150" width="100" /> While
at Where 2.0, <a href="http://www.chrisspagnuolo.com">Chris Spagnuolo</a> and I recorded
a podcast with the Very Spatial crew. 
<br /></p>
        <p>
          <br />
In this podcast we talk (at a high-level) about internals of the <a href="http://www.gains.org/MapTools/WISDOMMapExplorer/tabid/547/language/en-US/Default.aspx">Global
Avian Influenza</a> mapping application we built for the <a href="http://www.wcs.org">Wildlife
Conservation Society</a>, and some of the complexities and how we overcame them (think
1-M-M-M database relationships, with complex query criteria and 300ms response times). 
<br /></p>
        <p>
For those that know us, you won't be suprised that we also talked about Agile - how
it fits in with the Where 2.0 crowd, and how we work Agile into our contracting. All
-in - all, a fun experience. 
<br /></p>
        <p>
The <a href="http://veryspatial.com/?p=2156">podcast</a> went live today. Thanks Jesse
&amp; Sue!
</p>
        <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=503f8d56-ec1f-48c8-8fd6-ffc39e3ae188" />
        <br />
        <hr />
        <hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></body>
      <title>VerySpatial Podcast Interview</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,503f8d56-ec1f-48c8-8fd6-ffc39e3ae188.aspx</guid>
      <link>http://blog.davebouwman.net/2008/06/05/VerySpatialPodcastInterview.aspx</link>
      <pubDate>Thu, 05 Jun 2008 03:01:30 GMT</pubDate>
      <description>&lt;p&gt;
&lt;img style="margin: 0px 5px 0px 0px;" alt="mic_thumb" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/VerySpatialPodcastInterview_12708/mic_thumb_e6a5d025-32d4-4d06-8be0-d2173aae8f7b.gif" align="left" border="0" height="150" width="100"&gt; While
at Where 2.0, &lt;a href="http://www.chrisspagnuolo.com"&gt;Chris Spagnuolo&lt;/a&gt; and I recorded
a podcast with the Very Spatial crew. 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
In this podcast we talk (at a high-level) about internals of the &lt;a href="http://www.gains.org/MapTools/WISDOMMapExplorer/tabid/547/language/en-US/Default.aspx"&gt;Global
Avian Influenza&lt;/a&gt; mapping application we built for the &lt;a href="http://www.wcs.org"&gt;Wildlife
Conservation Society&lt;/a&gt;, and some of the complexities and how we overcame them (think
1-M-M-M database relationships, with complex query criteria and 300ms response times). 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
For those that know us, you won't be suprised that we also talked about Agile - how
it fits in with the Where 2.0 crowd, and how we work Agile into our contracting. All
-in - all, a fun experience. 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
The &lt;a href="http://veryspatial.com/?p=2156"&gt;podcast&lt;/a&gt; went live today. Thanks Jesse
&amp;amp; Sue!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=503f8d56-ec1f-48c8-8fd6-ffc39e3ae188" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;hr&gt;
davebouwman.net weblog - copyright 2005-2008 - licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"&gt; Creative
Commons License. &lt;/a&gt;</description>
      <comments>http://blog.davebouwman.net/CommentView,guid,503f8d56-ec1f-48c8-8fd6-ffc39e3ae188.aspx</comments>
      <category>Agile</category>
      <category>Ajax</category>
      <category>Podcast</category>
      <category>Virtual Earth</category>
    </item>
    <item>
      <trackback:ping>http://blog.davebouwman.net/Trackback.aspx?guid=44d75924-dc67-43f0-b940-4f9b45cb435e</trackback:ping>
      <pingback:server>http://blog.davebouwman.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.davebouwman.net/PermaLink,guid,44d75924-dc67-43f0-b940-4f9b45cb435e.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.davebouwman.net/CommentView,guid,44d75924-dc67-43f0-b940-4f9b45cb435e.aspx</wfw:comment>
      <wfw:commentRss>http://blog.davebouwman.net/SyndicationService.asmx/GetEntryCommentsRss?guid=44d75924-dc67-43f0-b940-4f9b45cb435e</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
This is the third and final part of a three part series summarizing the results of
the 2008 Geospatial Developer Survey. For further information, be sure to check out
read <a href="http://blog.davebouwman.net/2008/05/27/GeospatialDeveloperSurveyResults.aspx">part
one</a> and <a href="http://blog.davebouwman.net/2008/05/29/DeveloperSurveyDesignPatterns.aspx">part
two</a>.  
</p>
        <h2> 
</h2>
        <h2>Use of Source Control Systems
</h2>
        <p>
This is where we start to see some divergence from the larger developer community. 
</p>
        <p>
 <img height="250" alt="scc" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/scc_3c1fcd3e-134d-473f-8a9f-7378e276603d.png" width="322" border="0" /></p>
        <p>
Source control is as much a part of most developers lives as the language they use.
It should be automatic and used by default. Subversion is good, and free. It's not
trivial to setup, but with free subversion hosting services like Assembla.com, there
is virtually no reason not use it. (btw - although I have an "Assembla"
badge in my sidebar, I am not paid to endorse them - their service is solid and so
I promote it).
</p>
        <h2>Automated Build Tools
</h2>
        <p>
With more than half of the respondents not doing automated builds, we are seeing more
of the separation from main-stream development. 
</p>
        <p>
          <img height="244" alt="autobuild-tools" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/autobuild-tools_36a0f8ba-8c45-4f0a-a02e-ff89c9a8378e.png" width="337" border="0" />
        </p>
        <p>
All the choices on this question were .NET, but I also compiled the "Other -
Please specify" results into a chart.
</p>
        <p>
 <img height="271" alt="autobuild-other" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/autobuild-other_6cf10080-19ba-4e3e-84a9-dab32567ca7d.png" width="466" border="0" /></p>
        <h2>Unit Testing
</h2>
        <p>
There were 3 questions on unit testing, mainly because I see this as a key element
raising the quality of GIS software projects. Unit testing is as much a philosophy
about how you develop software as it is the actual writing of tests. Committing to
doing unit testing really says you care about quality, and that you realize that manual
testing, while valuable, is never as consistent as automated tests. So, with that
we start with a look at what percent of projects are using unit testing.
</p>
        <p>
          <img height="273" alt="Using_Unit-Testing" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/Using_Unit-Testing_254e1899-80bf-4fe2-bce5-eeccda80a9af.png" width="467" border="0" />
        </p>
        <p>
I don't know how this stacks up to other industries, but I'd say there is room for
some growth here. Everyone talks about GIS getting on the "service bus",
but we need to make sure that when we get on the bus, our code does not fail!
</p>
        <p>
The next question basically asked why you were not doing more unit testing.
</p>
        <p>
          <img height="245" alt="why-not-unit-testing" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/why-not-unit-testing_ddc0f9fa-85bd-463f-af87-3bb60a975581.png" width="259" border="0" />
        </p>
        <p>
This is actually pretty good. I'd have to question the 14% who don't think it's valuable,
but I'll chock that up to them not knowing what's really involved.
</p>
        <p>
I've heard the "not-enough time" thing before, but the problem is that you
will have bugs. And someone will find them. Better the developer finding them sooner
than a client finding them later. Also, in terms of time, on big projects, I think
you actually save time.Having automated tests, helps you prevent regression. Think
about all the stuff that breaks between a big ArcGIS releases - that's regression,
and that's what good automated tests can catch.   
</p>
        <p>
Difficulty. This is true. Writing good unit tests is hard. Using good design patterns
help, and good tools can ease the pain, but even still it's not easy. Writing unit
tests for ArcObjects code is very difficult, but not impossible. In these cases, I
focus the tests on the most critical parts of a system - basically putting the effort
where it will payoff the most. For these areas, I shoot for 100% code coverage - if
they are the most complex, I want to make sure that my tests cover all possibilities.
Again, difficult, but if you are writing a complex spatial rule engine, that works
with relationships between multiple layers, business workflows, and user permissions,
there is no realistic way to manually test it on any sort of a regular basis.
</p>
        <p>
The next question was "If tests were easier to write, would you write more of
them?"
</p>
        <p>
          <img height="251" alt="unit-tesing-easier" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/unit-tesing-easier_3669eaac-3277-4613-83ee-cdc421a7cdb5.png" width="265" border="0" />
        </p>
        <p>
So, a resounding YES on that. This is great, because as a community we can actually
make this happen.  
</p>
        <p>
A couple years back I threw some code out there under the umbrella of <a href="http://blog.davebouwman.net/SearchView.aspx?q=arcunit">"ArcUnit"</a> -
the files referenced in those posts are now gone, but it was some demo code that showed
how to unit test geometry operations, by serializing geometries and storing them in
the unit test assembly. The <a href="http://svn2.assembla.com/svn/arcdeveloper/TestingUtilities/trunk/">code</a> is
now on Assembla in the ArcDeveloper project, under TestingUtilities. Seeing as there
is interest in this, I'll likely write some more articles on this. 
</p>
        <h2>Unit Testing Frameworks
</h2>
        <p>
Ok - the Java people really ripped on this question. After adding an "Other",
I did tabulate the results for all that as well.
</p>
        <p>
          <img height="261" alt="unit-testing-frameworks" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/unit-testing-frameworks_32bc1d41-01c7-4002-96c4-8a954cdeddc5.png" width="324" border="0" />
        </p>
        <p>
This gets somewhat interesting - 60% of people said they are not using any tools,
but back in the "What percent of your projects use unit testing" only 38%
said "None". I guess some "homegrown" unit testing could explain
a few percent, but... anyhow. Interesting that MBUnit and MSTest are so low. MSTest
is baked into Visual Studio 2008 (Professional and above), and MBUnit is both free
and awesome.
</p>
        <p>
As for the "other", here's how that stacked up.<img height="283" alt="other-ut-frwk" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/other-ut-frwk_2c575cc9-6872-4941-ada0-c6e6a5dd5da3.png" width="472" border="0" /></p>
        <p>
Apparently I could have saved myself a heap of greif if I'd just added jUnit to the
list!
</p>
        <p>
The final Unit Testing question went out to the edge - "What do you think of
Test Driven Development"
</p>
        <p>
          <img height="262" alt="tdd" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/tdd_0205cc4c-9784-4acd-ac6a-57f78739b351.png" width="442" border="0" />
        </p>
        <p>
So at least one zealot in the crowd aims pretty high! For the "No opinion"
crowd, TDD is the practice of writing your unit test before the implementation. The
intent of this is to essentially define the desired behavior in the test, then make
the software behave in that way. No doubt this is difficult, and requires you to be
a total unit testing &amp; pattern guru. I *think* this is possible, even on complex
projects like GIS, but you'd need to be working with a test friendly GIS framework
(as in don't come asking me to build you an ArcGIS Server .NET ADF site using TDD!)
</p>
        <p>
 
</p>
        <h2>Code Refactoring 
</h2>
        <p>
As you write code, there are times when you need to change it's structure - usually
to conform to a pattern, to facilitate extensibility, or just because your function
got long and messy (i.e. you're making maintenance easier!). This is called refactoring.
The first question was related to how often you refactor your code.
</p>
        <p>
          <img height="250" alt="refactoring" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/refactoring_f38322a3-f105-4d5b-a24b-bfa71219b1b0.png" width="353" border="0" />
        </p>
        <p>
The second question related to the use of .NET Refactoring tools. I appologize again
to the non-.NET people, but I don't know of any Java Refactoring tools.
</p>
        <p>
          <img height="270" alt="net-refactoring" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/net-refactoring_5c70c839-461a-4eba-b707-cd7280f09c91.png" width="466" border="0" />
        </p>
        <p>
What's interesting here is that the "Not Refactoring" people are not even
using the tools in Visual Studio. When we were doing a lot of desktop development,
we used RefactorPro - mainly because they had good Visual Basic.NET support. Now that
we're using C# and doing 99% web development, we are finding that the IDE tools /
manual refactoring is sufficient. 
</p>
        <h2>Code Documentation Generation
</h2>
        <p>
This was a quick question on the use of automatic code documentation generators. They
are pretty common in the larger developer community, and relatively easy to bring
into the mix, and spit out some good API documentation. Worth the effort in my opinion.
</p>
        <p>
          <img height="260" alt="doc-tools" src="http://blog.davebouwman.net/content/binary/WindowsLiveWriter/DeveloperSurveyUnitTestingOtherTools_13B3F/doc-tools_8d1cc877-a67a-41d8-ac8e-738874142dc0.png" width="315" border="0" />
        </p>
        <p>
 
</p>
        <h2>Comments
</h2>
        <p>
Fifty-Two respondents left comments at the end of the survey. Most were constructive,
and others... well... lets look:
</p>
        <blockquote>WTF, no C++ on the list of languages? What language do you think the bulk
of geospatial software (from GDAL to ArcGIS) is written in? C# is just a evil marketing
ploy from MS to try to deflate Java's market; nobody is expected to actually _use_
C#.</blockquote>
        <p>
          <strong>Reply:</strong> Not having C++ was an oversight. As for your issues with C#,
can't help you there.
</p>
        <h2>Summary:
</h2>
        <p>
Overall, this was an interesting experience. Clearly I could do a much better job
on the questions, and have a much wider range of options on the answers. I think it
does show that geospatial developers are adopting main stream techniques and tools,
just at a somewhat slower pace. Thoughts?
</p>
        <p>
          <a href="http://www.davebouwman.net/sourcecode/GeoDeveloperSurvey2008.zip">Download
the results</a> (Excel 2007 format)
</p>
        <img width="0" height="0" src="http://blog.davebouwman.net/aggbug.ashx?id=44d75924-dc67-43f0-b940-4f9b45cb435e" />
        <br />
        <hr />
        <hr />
davebouwman.net weblog - copyright 2005-2008 - licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> Creative
Commons License. </a></body>
      <title>Developer Survey: Unit Testing &amp;amp; Other Tools</title>
      <guid isPermaLink="false">http://blog.davebouwman.net/PermaLink,guid,44d75924-dc67-43f0-b940-4f9b45cb435e.aspx</guid>
      <link>http://blog.davebouwman.net/2008/06/04/DeveloperSurveyUnitTestingAmpOtherTools.aspx</link>
      <pubDate>Wed, 04 Jun 2008 13:28:43 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
This is the third and final part of a three part series summarizing the results of
the 2008 Geospatial Developer Survey. For further information, be sure to check out
read &lt;a href="http://blog.davebouwman.net/2008/05/27/GeospatialDeveloperSurveyResults.aspx"&gt;part
one&lt;/a&gt; and &lt;a href="http://blog.davebouwman.net/2008/05/29/DeveloperSurveyDesignPatterns.aspx"&gt;part
two&lt;/a&gt;.&amp;#160; 
&lt;/p&gt;
&lt;h2&gt;&amp;#160;
&lt;/h2&gt;
&lt;h2&gt;Use of Source Control Systems
&lt;/h2&gt;
&lt;p&gt;
This is where we start to see some divergence from the larger developer commun