Try-Catch-FAIL

Failure is inevitable.

Microsoft Chart Control for ASP.NET and WinForms

clock November 26, 2008 00:42 by author Matt

Microsoft has apparently decided that we need another charting control.  Actually, I think this is pretty cool, I just wish it had come out before I was tied in to another vendor's control.  :|  In any case, you can see some pretty pictures, read documentation, and download some samples here. I wonder if this works with ASP.NET MVC...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


A long time ago, in a GridTreeView far, far away…

clock November 18, 2008 15:37 by author Matt

Some of you (and by some, I mean two) have been axiously awaiting the release of the code for the GridTreeView that I described a while back. Thanks to the generosity of my current employer, I’m happy to present the code, a compiled DLL, and a demo ASP.NET MVC site that you can use to test out the GridTreeView.  Enjoy!

Binaries

Source Code

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Creating a reusable grid tree view with ASP.NET MVC and jQuery

clock October 8, 2008 08:45 by author Matt

I think it is a safe assumption that every web developer has had to display tabular data at one point or another.  Tabular data is easy with ASP.NET: bind a GridView to a data source, and you're all set.  But with ASP.NET MVC, things are a little trickier.  We don't have access to all the nice WebForms controls.  Still, it's fairly easy to do: just write a for-loop, or better yet, use the grid helper from MvcContrib.

Things get a trickier though if your tabular data is also hierarchical.  Typically, we display hierarchical data in a tree of some kind, but trees really aren't great for tabular data.  What would be great is to combine the two somehow.  Fortunately, there's a nice plug-in for jQuery that does just that: ActsAsTreeTable.  It's easy enough to use; all you have to do is embed ID's and CSS class information in your table rows, and the JavaScript does everything else.  Here's a simple example from the docs:

   1: <link href="path/to/jquery.acts_as_tree_table.css" rel="stylesheet" type="text/css" />
   2: <script type="text/javascript" src="path/to/src/jquery.acts_as_tree_table.js"></script>
   1:  
   2: <script type="text/javascript">
   3:     
   4: $(document).ready(function()  {
   5:     $("#your_table_id").acts_as_tree_table();
   6: });
</script>
   3:  
   4: ...
   5:  
   6: <table id="tree">
   7:   <tr id="node-1">
   8:     <td>Parent</td>
   9:   </tr>
  10:   <tr id="node-2" class="child-of-node-1">
  11:     <td>Child</td>
  12:   </tr>
  13: </table>

We can now combine this with the grid from MvcContrib to produce a collapsable Grid Tree View.  This example is encapsulated inside a view user control so that it can be used on any page.  It displays imaginary "widgets" in a tree.  The widgets aren't really hierarchical, so I've fudged it by making it appear that each widget is a child of its predecessor in the table.

First, let's create the grid:

   1: <%
   1:  Html.Grid(GetWidgets(), new Hash(id => ClientID, style => "width:100%"), 
   2: column =>
   3:       {
   4:           column.For(w => w.Name);
   5:           column.For(w => w.Description);
   6:           column.For(w => Html.TextBox("Description_" + w.Id, c.Description), "Editable").DoNotEncode();
   7:       },
   8: sections =>
   9:     {
  10:         sections.RowStart(c =>
  11:                               {
%> <tr class="child-of-node-<%=w.Id - 1%>" id="node-<%=w.Id%>"> <%
   1:  
   2:                               });
   3:     }    ); 
%>

That probably looks horrendous, so let's walk through it.  GetWidgets() is a method on the view user control that grabs widgets from wherever (in practice, probably the model or view data).  Next, the Hash just contains key/value pairs that are embedded in the opening table tag; here, we've specified the table's ID (by using ClientID, it will have the name that ASP.NET gives to the user control), and we've specified that it should be 100% wide.  Next, we define the columns using lambda expressions.  The first two columns simply display the widget's name and description.  The last column is a little more complicated.  It creates a text box using the TextBox helper method.  Since the column contains HTML that shouldn't be encoded, we call DoNotEncode on it.  Finally, we use a lambda expression to override how rows are created.  The code here populates the row with the 'child-of-node-#' class and the id attribute, both of which are needed by ActsAsTreeTable.  It may look intimidating, but it's actually nice once get comfortable with the syntax. 

The last thing we need to do is spit out the JavaScript to turn our gird into an ActsAsTreeTable:

   1: <script type="text/javascript">
   2:         $(document).ready(function()  {
   3:             $("#<%=ClientID %>").acts_as_tree_table();
   4:         });
   5: </script>

If you set everything up correctly, you should now have a working "grid tree view".  In a future article, I'll introduce a new Html helper that does all the heavy lifting for you.

Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


The pain and horror of web deployment projects

clock October 3, 2008 00:24 by author Matt

I've spent the better part of a day now wrestling with web deployment projects, and I am ready to conclude that they are too rigid to be useful for practical scenarios.  Here's what I wanted to do:

  • Create a directory structure for my web app and all its dependencies.  This means not just the folder for the virtual directory, but a folder for log files, a folder for the DAL plug-in, a folder for scripts, and a folder for misc. other things.
  • Compile my web app, copying all the necessary ASP.NET files and DLLs to a folder in the directory structure I created.
  • Move (manually for now) this directory structure to production.
  • Drop in the necessary resource files and other config changes.
  • Actually use the web app without it exploding.

That last part is where things went wrong.  Not only could I not use my web app, but it did actually explode in a mess of "You can't have an App_GlobalResources folder!" and "I found ProfileCommon in two DLLs because I'm st00pid!"  Fun, fun.  Turns out all this headache is caused by how Web Deployment Projects do the precompile.  Even if I tell it that I want the site to be updatable, it still won't let me change something as simple as my resource files.  I also can't change App_Code (doesn't happen often, but we have dropped hotfixes in to production from time to time).

I tried to fix things by editing the WDP's MSBuild script, but that was an epic failure.  The thing exposes a few points for you to extend, but they're nothing more than pre/post build events.  I can't actually fix it no matter what combination of settings I try, either.

Instead, I'm going to just create my own MSBuild script to do all this from scratch.  In the end, I think it will be much less painful.  Check back on Monday for the first part of the script.

PS: No new "How to run a software development company (INTO THE GROUND)" this week, sorry!  I've got plenty of things I *could* say on the topic, but they're less on the funny side and more on the sad, depressing side and not very entertaining.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Web.config magic: configSource and file attributes

clock September 25, 2008 03:04 by author Matt

Many of the web applications we create are deployed many different times, providing many different instances.  Each instance is slightly different, but only in terms of configuration: they use different databases, possibly different sitemaps, different themes, and different terminology (via resource files).  Aside from those things though, the applications are exactly the same.  We want to be able to refresh deployed systems quickly and easily without having to do a lot of manual file manipulation.  In this post, I'll discuss how we addressed the problem for one specific source of configuration information: the web.config file.

If your custom configuration is just stored in a web.config file, why not just leave the old web.config file in place when you're deploying changes?  That would be great, but the fact is that the web.config stores much more than instance-specific information.  It also stores a lot of "global" information that applies to all instances of the application.  What happens when you need to deploy changes that were made to that "global" information?  Previously, our solution was to painstakingly merge the changes in to each web.config file.  We probably could have automated this by creating and applying diffs, but that's only a minor improvement.

A better solution is to refactor your web.config file using the 'configSource' and 'file' attributes.  Per the MSDN documetation, the 'configSource' attribute allows you to move the definition of a configuration section to an external file.  This attribute is inherited by all configuration section elements, so it works fine even with 3rd party configuration, like log4net.  Here's an example web.config file before:

   1: <configuration>
   2:     ...
   3:     <connectionStrings>
   4:         <add name="SqlServer2005" 
   5:             connectionString="Data Source=.;Initial Catalog=Inst1;Trusted Connection=true"
   6:             providerName="System.Data.SqlClient"/>
   7:     </connectionStrings>
   8:     ...
   9: </configuration>


Notice how the web.config is referencing an instance-specific database?  Well, we can move that to an external file using the 'configSource' attribute:

   1: <configuration>
   2:     ...
   3:     <connectionStrings configSource="Custom\connectionStrings.config" />
   4:     ...
   5: </configuration>


For the 'appSettings' element, you can also use the 'file' attribute.  Unlike 'configSource', which requires that the element be exclusively defined in the external file, the 'appSettings' element in the web.config file can extend or override the settings defined in the external source reference by the 'file' attribute, like so:

   1: <configuration>
   2:     ...
   3:     <appSettings file="Custom\appSettings.config">
   4:         <add key="OverridenKey" value="NewValue" />
   5:     </appSettings>
   6:     ...
   7: </configuration>


By combining these techniques, we were able to remove all instance-specific code from our web.config files and consolidate everything into a single folder called "Custom".  The files in "Custom" contain only the things that vary from instance to instance, so all we have to do during an update is leave the existing "Custom" folder in place.  Much, much easier than managing things by hand!

There's still more to do, like figuring out how to deal with sitemaps, resource files, etc, but I'm still working on that.  If I find anything cool, I'll be sure to post about it.

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Useful Info: Running x64 and x86 IIS Worker Processes Side-By-Side

clock July 29, 2008 02:50 by author Matt

On a (somewhat) related note, there's a nice new feature in IIS 7.0 that allows you to run both x86 and x64 worker processes side-by-side.  This wasn't possible with IIS 6/Windows Server 2003.  For details, check out rakkim's post on the subject.  This will be handy for me since one of the apps I maintain has a single web service that is dependent on a 32-bit COM component.  On IIS 6, that meant everything had to run as 32-bit, but with IIS 7, I can segregate that service into its own 32-bit app pool while leaving everything else in 64-bit goodness.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


About Matt

I am an overworked (and apparently overpaid) software developer that moonlights as a graduate student in computer science. I started off coding in C over a decade ago.  Since then, I've migrated from C to C++ and branched out to C#, PHP, VB.NET, JavaScript, and worked with a wide assortment of other languages that I hope to never deal with again (I'm looking at you, COBOL). Oh, and yes, I've written some Java.  Does that make me a bad person?

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in  anyway.

© Copyright 2008

Sign in