Blog

horizontal line graphic

Subscribe to Kevin Southworth's Blog  Subscribe to my RSS feed | Categories | Search

HowTo: Programmatically Hide a DotNetNuke Module

Friday, May 16, 2008 @ 10:33 AM :: 123 Views :: 0 Comments ::

I needed to programmatically hide a DotNetNuke module today and I couldn't find any examples of how to do it.  So here's how to do it.  This hides the entire module, including the container and title.

In your Page_Init method in your code-behind, use this little baby:

ContainerControl.Visible = false;

30 Days of Motivation - Cycle 1 - COMPLETED - Start of Cycle 2

Tuesday, March 04, 2008 @ 9:56 PM :: 253 Views :: 0 Comments ::

Today marks the end of my first round of "30 days".  My goals for the past 30 days were...

Read the rest of this post...

30 Days of Motivation - Cycle 1 - Week 3 Update

Sunday, February 24, 2008 @ 5:16 PM :: 279 Views :: 0 Comments ::

Today marks the end of "Week 3" for my current set of goals.  I've been doing pretty well with them, I'd say about 95% achievement thus far :)

I'm starting to think about what I should add on for the next "cycle".

30 Days of Motivation - Cycle 1 - Week 1 Update

Monday, February 11, 2008 @ 7:43 AM :: 308 Views :: 0 Comments ::

7 days in, still going strong.  In order to wake up at 5:30 each weekday, I had to move my alarm clock across the room so I'd be forced to get out of bed to turn it off.  As for the fast food thing, I used to eat fast food the most at lunch time for work, my plan so far has been to just pack my own lunch and bring it with me so I won't be tempted by eating out.  So far it's working.

30 Days of Motivation - Cycle 1 - Day 2 Update

Tuesday, February 05, 2008 @ 7:09 PM :: 241 Views :: 1 Comments ::

So far so good!  My 2 goals for the next 30 days are:

  1. Wake up at 5:30 AM every weekday, and at or before 8:00 AM on weekends
  2. No Fast Food

So far I'm 2 for 2 on both of those (started Feb 4th).  I'll be evaluating myself periodically until March 5th.

30 Days of Motivation - Cycle 1

Monday, February 04, 2008 @ 8:21 AM :: 286 Views :: 1 Comments ::

Today marks the start of my first "cycle" of 30 days. I have chosen the following goals for this cycle...

Read the rest of this post...

30 Days Of Motivation - The Cunning Plan

Thursday, January 31, 2008 @ 11:32 PM :: 261 Views :: 5 Comments ::

Starting Monday, February 4th I will be attempting to adopt a new philosophy on my goal-setting, it's called "30 Days Of Motivation" the plan is....

Read the rest of this post...

Structured Wiring

Thursday, November 29, 2007 @ 12:56 AM :: 243 Views :: 0 Comments ::

I'm 9 days away from owning my first house!  One of the cool things about the house is that it's a new construction, built in early 2007.  The builder installed what is called "structured wiring" which is just a fancy way of saying that some rooms in the house have been pre-wired for TV (RG6 Coax), Internet (Cat5) and Phone (RJ11).  Each 2x2 wall plate has 2 coax, 1 phone, and 1 ethernet jack on it, which is very cool since it will save me some time and labor.

I can't wait to get in there, geek out, and hook everything up!

Apple might be winning me over....slowly

Saturday, October 20, 2007 @ 9:43 PM :: 247 Views :: 0 Comments ::

I think Apple might be wearing me down.  So far I haven't really had a reason to invest in a Mac since my professional life is spent developing web applications using ASP.NET and C# (which I enjoy).  However, a lot of people I know (both normal people and developers) have switched over to Macs (or at least bought one to use alongside their PC) and we're thinking of buying one for the office so we can actually have a Mac to test our web applications using the real Safari browser (instead of the Mac screenshot services that we currently use).

 

I also recently watched the Mac OSX "Leopard" video walkthrough of Apple's next version of the OSX operating system.  The one feature that stood out for me was the "Time Machine" feature, it just seemed really intuitive, very useful, without feeling like it's "in the way".  I'm not sure what the overhead is for that feature (i'm assuming it's gotta be indexing the hard disk constantly, which I assume would affect performance?) but it does look pretty slick.

 

Also, I gotta say that the iPhone is a sweet product.  I don't have an iPhone yet, but I have visited the AT&T store twice and played with them.  I just haven't had that event that put me over the edge enough to pay $250 to ditch my current provder (Centennial) and plunk down $400 + 2-year contract with AT&T.  However, Apple recently announced that they'll be providing an SDK for the iPhone in February 2008, depending on what that SDK provides, that might be enough to sway me to the Apple/AT&T side of things.  I've also heard rumors of the next version of the iPhone that might include GPS and 3G, if that's the case then I don't think I'll be able to resist!

 

Retrieving DotNetNuke List Items in Code

Monday, September 24, 2007 @ 12:51 PM :: 407 Views :: 1 Comments ::

Today I needed to grab the contents of a DotNetNuke List (Host Settings -> Lists).  Here's the code to grab the "Country" list and DataBind it to a ListBox:

            Dim listController As New ListController

            Dim listEntries As ListEntryInfoCollection = listController.GetListEntryInfoCollection("Country")

 

            lstCountries.DataSource = listEntries

            lstCountries.DataValueField = "Value"

            lstCountries.DataTextField = "Text"

            lstCountries.DataBind()

1 down, 4 to go: Reasons I don't own an iPhone (yet)

Friday, September 14, 2007 @ 9:43 AM :: 270 Views :: 1 Comments ::

There's just a few things that need to happen before I pick up an iPhone....

Read the rest of this post...

Google Notebook

Tuesday, September 11, 2007 @ 7:51 PM :: 244 Views :: 0 Comments ::

Update: You must be logged in to your Google account to use this feature, which is probably why I didn't notice it before.

I just discovered a cool (new?) feature of Google called the "Notebook".  When you're looking at a list of search results you can "note" individual results and they are...

Read the rest of this post...

Vista Kicked to the Curb

Monday, August 20, 2007 @ 1:14 PM :: 206 Views :: 1 Comments ::

Well, exactly 1 month ago today I posted that I was installing Windows Vista on my reformatted desktop PC.  Today I am announcing that I am going back to Windows XP Pro.

While Vista was pretty to look at, it didn't really offer anything amazing that compelled me to keep it installed.  The constant UAC prompts started to get annoying, plus Visual Studio 2005 really doesn't run correctly in Vista (you have to run it as the "Admin" user for it work correctly).  There were some other issues with VS2005 in Vista as well related to running/debugging projects from inside the IDE.  Those things, along with the fact that my TV capture card (Hauppagge WinTV PVR 250) is not supported under Vista, has led me to go back to trusty old WinXP.

I have now got XP installed again and it feels good :)  All my peripherals are working correctly (I can record TV again!) and since I applied the Zune Windows Theme, I get a little of that Vista feel also :)

ASP.NET on Rails!

Tuesday, August 07, 2007 @ 2:07 PM :: 260 Views :: 0 Comments ::

I finally got around to checking out MonoRail last night and I have to say that I am both impressed and excited that this framework exists.  MonoRail basically brings the Ruby on Rails style of programming to the ASP.NET platform.  With MonoRail, you have no ASP.NET page lifecycle, no WebForms, no Viewstate/ControlState, etc.  That might seem like a bad thing, but once you see how MonoRails works (and enforces an MVC architecture) I think you'll see the benefits.  I started web programming with PHP and MySQL and I loved the flexibility and control that PHP can give you as a web programmer.  A lot of the time the ASP.NET and the WebForm model feel too heavyweight to me.  It feels like it's just getting in the way.  I'm really excited to dive deeper into MonoRail and play around with the OR/M and Scaffolding features.  Check out the Castle and the MonoRail projects.

RSS feed is fixed

Wednesday, August 01, 2007 @ 9:42 PM :: 197 Views :: 0 Comments ::

Had an issue with the latest version of DotNetNuke clashing with my Blog module, RSS feed is now working again.

Simpsonized

Wednesday, August 01, 2007 @ 8:24 PM :: 223 Views :: 0 Comments ::

Simpsonized version of me:

To see the Simpsonized version of yourself go to simpsonizeme.com

Taking the Vista plunge

Friday, July 20, 2007 @ 9:52 PM :: 206 Views :: 2 Comments ::

Well, the motherboard died in my desktop pc last week, so I ordered a new CPU, mobo, and ram.  I was debating what OS to put back on that box (I had Win XP Pro on there before) and my buddy Ryan Doom convinced me to give Vista a shot.  I haven't really had a reason to upgrade to Vista, but since I'm reformatting anyway I might as well go for it.

Windows Vista Ultimate x64 (64 bit edition) is installing as we speak....

Check out my reading list

Thursday, July 19, 2007 @ 4:30 PM :: 212 Views :: 0 Comments ::

Just added a new page to the site that contains my reading list.  Check it out to see books I've read in the past as well as my current queue of books.

Project Downloads have been fixed

Tuesday, June 26, 2007 @ 3:42 PM :: 215 Views :: 0 Comments ::

For those of you that were having issues downloading files from my "projects" page, I have upgraded the module and the downloads should be working correctly again.

Cool Visual Studio Add-in: Regionerate

Monday, June 25, 2007 @ 11:02 PM :: 221 Views :: 0 Comments ::
Saw this today linked from somewhere (can't remember where) but it looks pretty cool.  It's an add-in for Visual Studio that will "region-ize" your code for you automatically (you know, all that stuff you used to manually organize inside #region blocks).
http://www.rauchy.net/regionerate/2007/06/regionerate-101.html

Summer Reading List

Friday, June 15, 2007 @ 10:00 PM :: 238 Views :: 0 Comments ::
I'm always trying to keep up with the latest tools and technologies in the software industry (which is a full-time job in itself!) and I thought I'd post this quick list of my current summer reading material.  It's a mix of general software architecture / design and also some specific .NET stuff.

Currently Reading:
Next up (no particular order):
You can also keep tabs on my Amazon Wish List. It's going to be quite a task to finish these before summer ends, I better get cracking!

New Websites Launched!

Thursday, April 26, 2007 @ 12:28 PM :: 346 Views :: 0 Comments ::

This week Web Ascender launched 2 new websites: www.c21lookingglass.com and www.lansingitcompanies.com

Century 21 Looking Glass is a Lansing Real Estate broker. Their new website allows visitors to search the MLS property database in the Mid-Michigan area, along with the ability to save properties in their "cart" for revisiting later.

LansingITCompanies.com is a website designed to increase the visibility of IT-related companies in the Greater Lansing area.  If your business relies on IT workers and you're located in Mid-Michigan, please add your company to the website!

In soviet russia, jQuery scripts you!

Thursday, April 05, 2007 @ 10:48 PM :: 338 Views :: 0 Comments ::
We have been using the jQuery Javascript Ajax library in our current web project and I must say that it rocks!  The community support behind this project is amazing and is hitting the nail right on the head in terms of plugins and features that just "make sense" for anyone looking to add some Ajax spice to their web pages.  The jQuery website has great documentation, including examples of how to use each method of their API.

I must admit that I used to be a little scared of writing a lot of Javascript code (it has always seemed like a strange beast to me) but after working with jQuery for a few weeks I am hooked!  We've been using it to enhance our ASP.NET pages with some Ajax calls to REST webservices, along with putting pretty borders around photos, and providing in-place popup contact forms.

I'm debating on whether I should dig into Microsoft's ASP.NET AJAX framework because it seems fairly "heavyweight" compared to jQuery's simplicity and small footprint (1 javascript include file).

Where are all the open source .NET projects?

Thursday, April 05, 2007 @ 10:25 PM :: 346 Views :: 3 Comments ::
A colleague and I have been discussing lately the relative lack of open-source software projects that are written in .NET languages (normally C# or VB.NET).  We've been searching for a web-based tool to help us with: task tracking, bug tracking, project management, help desk/support tickets, project scheduling, client/customer interface (where clients can login and check status of their projects).

Searching for these types of open-source projects on Google, Sourceforge, and all the usual places turns up a LOT of PHP, Perl, Python, Java projects, but hardly any .NET projects!  However, just because there are a lot of projects out there in these other languages doesn't mean they are any good (as we're finding out).

My feeling about most open-source projects is that they never really get the "spit and polish" of a commercial application.  Of course there are some outstanding open-source projects that rival many commercial offerings (Apache Webserver, Subversion source control, and the Linux Operating System immediately come to mind) but for the most part the projects you see out there were likely written (or at least started) by one developer who was probably motivated by one of the following:
  • Learning a new programming language
  • Needed a program/application to behave in a very specific way
  • The joy of programming just for the fun of it (yes it can be fun!)
The problem with this is that it seems most open-source projects seems to fall in the realm of that first bullet, where the develope is learning a new language and just needs a project to chew on.  As a result, most of the time these projects are always "in development" or they simply aren't up to par in other areas such as Usability, Reliability, or Feature Set.  Also, most of the time the source code is not something you'd want to touch with a 10ft pole!

However, it's when you combine those last two bullets that you can get some great open-source software like Apache or Linux.  These projects are written by smart and dedicated guys (and gals) who are there for the joy of it.

But back to my original question. Where are all the really cool and blog-worthy open-souce .NET applications?  I know there are some great ones out there (DotNetNuke, NUnit, Commerce Starter Kit, SubSonic) but it pales in comparison to other non-Microsoft languages.

Hmmm...maybe I should shut up and start an open-source .NET project....

Google Webmaster Tools Gets A New Tab

Wednesday, February 07, 2007 @ 11:40 PM :: 692 Views :: 1 Comments ::

Ryan gave me a heads up about a new tab in Google Webmaster Tools called "Links".  I normally login to Google's Webmaster tools about every other day to check on the basic stats of our company website, as well as this site, so I was surprised I hadn't seen it yet.  But sure enough it's there!  This new feature shows you the number of other websites on the Internet that are linking to your site.  You might say, "but kevin I can already get this information by typing in 'link:www.kevinsouthworth.com' into Google's search bar!"  and you would be partially correct ;) When you add the "link:" prefix to your domain searches Google does show you *some* of the incoming links to your site, but not all (Google doesn't really say why they don't show all links this way, but they don't).  The new Google Webmaster Links page shows you the *actual* number of incoming links that Google knows about for your website, which is normally a LOT more than if you just use the "link:" prefix.

Sharing contacts, accounting, calendars in a small business

Sunday, February 04, 2007 @ 8:09 PM :: 476 Views :: 0 Comments ::

Ryan and I decided we needed to find a real solution to our problem of sharing our contacts, calendars, and accounting information between our office computers.  We've already adopted Microsoft Office 2007, which means we're already using Outlook 2007.  Microsoft has a sweet add-on for Outlook called "Business Contact Manager" which adds a lot of CRM-like features to Outlook like accounts, oppotunities, projects.  What's really cool though, is you can connect your BCM (business contact manager) to a remote/network SQL Server 2005 database instance, and then share your BCM data between all you machines.  BCM also installs a local SQL 2005 Express instance to store all of your data when you're offline, and it will sync up with your master network database when you re-connect.  Another cool feature is that BCM can integrate with Microsoft Accounting 2007, a new accounting package for small businesses.

Just recently we setup this whole deal on our office server.  First we installed SQL Server 2005.  Next we installed MS Office 2007.  Next we installed the Business Contact Manager Addon for Outlook 2007, which detected our SQL Server instance and installed it's database there. The last step was to install MS Accounting 2007.  We had been using MS Accounting 2006 for the last year, so we were a little concerned how the upgrade process would be from 2006 to 2007 as far as our data was concerned.  The upgrade went flawlessy, however, and sucked in all our 2006 data.  The really cool part though, was that Accounting detected our BCM database and asked us "Would you like to integrate Accounting with Business Contact Manager?"  That's exactly what I wanted! So I said yes and after clicking through a couple more wizard steps, we had BCM and Accounting running in harmony on the our server.

The last step was to configure all of our Outlook 2007 clients to point at the server's BCM database stored in SQL Server.  The whole thing was actually pretty painless and I'm impressed with the level of integration Microsoft has put in to Outlook 2007, Business Contact Manager, and Accounting 2007.

Now Ryan and I can write invoices, create leads and contacts on our laptops (offline) and then sync up to the server when we get back to the office.  It looks like it's going to be a great solution for us.

SubSonic vs. EntitySpaces – A Battle of OR/Ms

Tuesday, January 30, 2007 @ 11:11 PM :: 4117 Views :: 16 Comments ::

I was quite overwhelmed recently when I started researching  OR/M tools for the latest ASP.NET 2.0 project at work.  There are so many to choose from, all with their own unique take on what it means to be a good object-relational mapping tool.  I only wanted to spend a day or two researching/evaluating OR/M tools, and I narrowed it down to SubSonic and EntitySpaces for my final showdown.

SubSonic

I first heard about SubSonic about 6 months ago from one of the many ASP.NET blogs I subscribe to.  The goal of the project is to bring some of the cool RAD tools from the Ruby-on-Rails world into ASP.NET.  One of the nicest features of SubSonic is that it mostly “just works” without too much effort.  There’s no crazy-complicated XML mapping files (I’m looking at you NHibernate…) or mountains and mountains of auto-generated code to dig through (N-Tiers).  SubSonic utilizes a cool feature of the VS2005 and ASP.NET environment called “Build Providers”. All you have to do is make a few adjustments to your web.config file, add a special file to your App_code directory and you’re done!  Whenever you compile/build your VS solution, SubSonic reads your database schema and dynamically generates Data Access classes.

EntitySpaces

I only recently became familiar with EntitySpaces.  A former co-worker of mine really likes the d00dads architecture, the precursor to EntitySpaces.  EntitySpaces takes the code-generation approach, utilizing the popular free code-generation tool MyGeneration.  EntitySpaces is essentially a few .NET dll’s and some MyGeneration code templates.  You load up MyGeneration, open the Entityspaces templates, point them at your database tables, and MyGeneration will spit out a bunch of Data Access and Biz Logic classes in either C# or VB.NET.  My favorite features of EntitySpaces are it Scaffolding support (to auto-generate administration screens for all of your database tables) and its great support for hierarchical data models.

Shot of a scaffold page (notice the drop-down auto-generated for the FK column)

es2_CropperCapture[1].Jpg

SubSonic

Good Stuff

·         Free and Open Source!

·         Easy to get started / mild learning curve

·         Dynamic Queries

·         Strongly-typed wrapper classes for all your stored procedures

·         Active forums, frequent releases

Chinks in the armor

·         Scaffolding support is buggy

·         Doesn’t handle GUID keys very well

·         Weak support for navigating PK/FK relationships

·         Geared towards ASP.NET only (WinForms is possible)

EntitySpaces

Good Stuff

·         Auto-generated scaffolding is very powerful / time-saving

·         Dynamic Queries

·         Very good support for navigating PK/FK collections in code

·         Able to regenerate Data Access code without affecting your custom business logic

·         Serialization of objects for web services, etc.

·         Active forums / support

Frown Face

·         Not free or open source ($80 for Express edition)

·         No strongly-typed access to stored procedures (it is scheduled for next release though)

Final Thoughts

In the end I chose to drop the $80 for EntitySpaces because of its superior Scaffolding and PK/FK Hierarchical support, both of which have been big time-savers so far, allowing me to focus more on the “real guts” of my application instead of Data Access code.  The addition of stored procedure wrappers in the next version will make it even more attractive in my opinion.   However, I’m definitely going to keep an eye on the SubSonic project, since they are adding features all the time.  The biggest things preventing me from using SubSonic right now are the relatively buggy scaffolding support for GUID data types, as well as the weaker support for navigating hierarchical PK/FK collections in code.

Joined Technorati

Monday, January 29, 2007 @ 11:33 PM :: 281 Views :: 0 Comments ::

Just added myself to Technorati, see how this affects things ;)

Technorati Profile

Reasons to Refactor

Wednesday, January 24, 2007 @ 2:05 AM :: 285 Views :: 1 Comments ::
Checklist of reasons to refactor:
  • Code is duplicated
  • A routine is too long
  • A loop is too long or too deeply nested
  • A class has poor cohesion
  • A class interface does not provide a consistent level of abstraction
  • A parameter list has too many parameters
  • Changes within a class tend to be compartmentalized
  • Changes require parallel modifications to multiple classes
  • Inheritance hierarchies have to be modified in parallel
  • Related data items that are used together are not organized into classes
  • A routine uses more features of another class than of its own class
  • A primitive data type is overloaded
  • A class doesn''t do very much
  • A chain of routines passes tramp data
  • A middle man object isn''t doing anything
  • One class is overly intimate with another
  • A routine has a poor name
  • Data members are public
  • A subclass uses only a small percentage of its parents'' routines
  • Comments are used to explain difficult code
  • Global variables are used
  • A routine uses setup code before a routine call or takedown code after a routine call
  • A program contains code that seems like it might be needed someday
Code Complete, Chapter 24

Custom DotNetNuke Control Panels

Wednesday, January 24, 2007 @ 2:05 AM :: 388 Views :: 0 Comments ::
This is just a quick note for myself, I may do a full blog post on this topic later (since I haven''t found instructions anywhere on how to do this from anyone else).

I was interested in creating a custom control panel for DotNetNuke (the bar at the top with all the page and module functions).

  1. Create a copy of the .ascx / ascx.cs files of one of the existing control panels in the "website/admin/controlpanel" directory
  2. Add a row in the "ModuleControls" table with ControlKey = CONTROLPANEL:XXX where XXX is your custom name and set the ControlType = -3
Step # 2 should make your custom control panel visible in the Host Settings -> Advanced -> Other -> Control Panel drop-down

Best Practices for Variables

Wednesday, January 24, 2007 @ 2:04 AM :: 269 Views :: 0 Comments ::
  • Declare and define each variable close to where it''s first used
    • This applies especially to code setup needed right before a loop
  • Localize References to Variables
    • keep subsequent variable references close together (the number of lines between references is called span)
    • minimize the average span
  • Keep "live" time as short as possible
    • "live" time is the number of lines between a variables first reference and its last reference
    • A variable could have short span, but a long live time
    • Goal is to minimize both span and live time
  • Don''t assign a value to a variable until just before the value is used
  • Always start with the most restrictive visibility, and expand only as necessary
    • Favor the smallest possible scope for a variable: local to a loop, local to a routine, private to a class, protected to a class, package to a class
(Code Complete, Chapter 10)

Inheritance or Containment?

Wednesday, January 24, 2007 @ 2:03 AM :: 260 Views :: 0 Comments ::
I''ve been reading Code Complete lately (which is a great book so far), and the author, Steve McConnell, has some good general advice about when to use Inheritance and when to use Containment when designing your classes:
  • If multiple classes share common data but not behavior, create a common object that those classes can contain
  • If multiple classes share common behavior but not data, derive them from a common base class that defines the common routines
  • If multiple classes share common data and behavior, inherit from a common base class that defines the common data and routines
  • Inherit when you want the base class to control your interface; contain when you want to control your interface

Superstition or Understanding?

Wednesday, January 24, 2007 @ 2:03 AM :: 259 Views :: 0 Comments ::
Reading some more of Code Complete tonight, ran across a nice little blurb about a difference between hobbyists and professional programmers.  If you write code which you "feel" is right, but the compiler or the hardware just isn''t doing it correctly, you''re in the realm of superstition.  If you actually understand every line of your code and what it does, you have an understanding.  95% of the time it''s the programmers code that is wrong, not the hardware or the compiler.

Nothing is ever right just because it seems to work.  If you don''t know why it works, it probably doesn't - you just don''t know it yet!

GUI Architecture

Wednesday, January 24, 2007 @ 2:02 AM :: 335 Views :: 0 Comments ::
Ryan sent me a great link to an article by Martin Fowler on "GUI Architecture".  Martin Fowler is almost THE source for knowledge on application design and methodologies.  This post covers a history of approaches to designing GUI systems, capping it off with Model-View-Presenter.

http://www.martinfowler.com/eaaDev/uiArchs.html

Note to self: read up on Model-View-Presenter (MVP) !

Dynamic controls in ASP.NET

Wednesday, January 24, 2007 @ 2:01 AM :: 281 Views :: 0 Comments ::
The other day I had to figure out how to build a dynamic form using ASP.NET.  We were storing the "form definition" of all the different types of controls we''d be supporting in our SQL Server backend database (so far we only support Textbox, Checkbox, and Label, since that''s all the client needs at this point).  My job was to figure out how we''re going to render the page using these dynamic controls, which the user could choose and redefine dynamically using the administration interface.  After a lot of prototyping and proof-of-concept type applications testing out the ASP.NET event model, etc. it turns out that this isn''t too difficult (which is good news, because in PHP this type of thing is fairly simple to implement)  The key things to remember are:
  • Use a Placeholder control as the container for your dynamic controls / form elements
  • You must load / re-add the dynamic controls on every page load, if you do not you''ll get some strange behavior when trying to retrieve the form values
  • Keep the methods/logic for adding the form controls separate from the methods/logic used to populate the controls with data from the database.  I made the mistake of bundling these two things together, and I eventually ran into all kinds of "duplicate control ID" errors from ASP.NET.  Once I separated them out, things were much smoother

Using the DNN Label Edit Control

Wednesday, January 24, 2007 @ 2:00 AM :: 378 Views :: 0 Comments ::

Nice post from the core team on how to use the relatively new "DNN Label Edit" control, which is utilized in the newest versions of DNN to allow the user to just click and edit the module title in-place.  That control is available for us to re-use in our own modules, which is cool

http://dotnetnuke.com/Default.aspx?tabid=825&EntryID=1048

Custom Module permissions in DotNetNuke

Wednesday, January 24, 2007 @ 1:54 AM :: 242 Views :: 0 Comments ::

Here''s a nice post from the core team on how to implement custom module permissions for your own modules, and hooking them up to the built-in "permissions grid"

http://dotnetnuke.com/Default.aspx?tabid=825&EntryID=1052

ADO.NET vNext

Wednesday, January 24, 2007 @ 1:53 AM :: 259 Views :: 0 Comments ::

I noticed today that the August CTP release of the new ADO.NET vNext is now available for download.  Don''t know much about this platform yet, other than it''s related to the LINQ technology Microsoft is working on.  This is supposed to be Microsoft''s solution to the ORM/ERM tools that have been out there for a while.  The idea of mapping relational data to object-oriented objects, and being able to issue queries based on objects instead of relational data.

You can check out some screencasts from the ADO.NET team blog:

Part 1

Part 2

More info: http://blogs.msdn.com/adonet/archive/2006/08/15/701479.aspx

Send a file from Excel to ASP.NET web service using VBA macro

Wednesday, January 24, 2007 @ 1:52 AM :: 1403 Views :: 2 Comments ::

The other I had the challenge of figuring out how to add a toolbar button to a MS Excel file that would send the current file to an ASP.NET web service.  The web service could then take some action on the file, such as send it as an email attachment, or log it to a database.

You''ll need the following tools/downloads (in addition to MS Excel and Visual Studio 2003/2005)

Microsoft Office 2003 Web Services Toolkit

  1. Create the ASP.NET Web Service to receive the file. I used VS 2005 to create my webservice, but VS 2003 should work fine also.  The key is to have the web method receive a byte[] array as a parameter, since that is what we will be passing from our client-side VBA code.
            [WebMethod]
    public void ReceiveExcelFileBytes(byte[] data)
    {
    Console.Write(data);
    Stream output = new FileStream(
    @"C:\WINDOWS\TEMP\data.xls",FileMode.Create);
    BinaryWriter outputWriter = new BinaryWriter(output);
    outputWriter.Write(data);
    outputWriter.Close();
    output.Close();
    }
  2. The next step is to write our VBA code inside MS Excel. Create a new Excel file and open it. Open the Visual Basic Editor by pressing Alt-F11. Add a new "Module" and type in the code below:
    Dim sMenu As String

    Sub AddCustomButton()

    Dim oCB As CommandBar
    Dim oCtl As CommandBarControl
    Dim newMenu As Object ''CommandBarControl
    Dim ctrlButton As Object ''CommandBarControl

    sMenu = "Send to Webservice"

    On Error Resume Next
    Application.CommandBars("Formatting").Controls(sMenu).Delete
    On Error GoTo 0

    Set oCB = Application.CommandBars("Formatting")
    Set oCtl = oCB.Controls.Add(
    Type:=msoControlButton, temporary:=True)

    With oCtl
    .BeginGroup = True
    .Caption = sMenu
    .FaceId = 197
    .Style = msoButtonIconAndCaption
    .OnAction = "SaveToWebservice"
    End With

    End Sub
  3. Next we need to hook-up our function to the Workbook_Open event. Double-click on "ThisWorkbook" in the VBA Editor and type in the following for the Workbook_Open event handler:
    Private Sub Workbook_Open()
    AddCustomButton
    End Sub
  4. Make sure have installed the Office 2003 Web Service Toolkit, we''ll be using it to generate a VBA proxy for our ASP.NET webservice. Inside the VBA editor, go to "Tools -> Web Service References" menu and add a reference to the URL of your ASP.NET webservice that was created in step # 1 above. This will generate some VBA code that we can use to call our ASP.NET webservice from VBA.

  5. Now we need to connect our custom toolbar button to some code that actually sends the file across the wire. Jump back to the VBA module (where we have our AddCustomButton() method, and add the following code:
    Sub SaveToWebservice()

    On Error GoTo Error_Handler

    Dim backupFile As String
    Dim fhandle As Long
    Dim webservice As New clsws_ExcelWebService

    backupFile = "C:\WINDOWS\TEMP\file_backup.xls"

    '' Save a backup copy to retain our VBA code
    ActiveWorkbook.SaveCopyAs backupFile

    Dim TypeBinary
    Dim oStream As ADODB.Stream

    '' Create the object
    Set oStream = CreateObject("ADODB.Stream")

    '' Open our file
    oStream.Open
    oStream.Type = adTypeBinary
    oStream.LoadFromFile backupFile

    '' Retreive binary data from the file
    Dim dataLong As Long
    Dim dataBytes As Variant
    Dim dataString As String

    dataBytes = oStream.Read

    '' call the webservice
    webservice.wsm_ReceiveExcelFileBytes (dataBytes)

    oStream.Close

    MsgBox ("Successfully sent")

    Exit Sub

    Error_Handler:
    MsgBox Err.Description &
    " (" & Err.Number & ")",
    vbOKOnly + vbCritical
    Exit Sub

    End Sub

 

Smart Clients in .NET 2.0

Wednesday, January 24, 2007 @ 1:51 AM :: 195 Views :: 0 Comments ::

I found a really good article on CodeProject this weekend on Smart Client development. It goes into a lot of detail on how to implement a Smart Client type application, but it also has some good stuff relating to Design Patterns, and how to implement an “Automation” module similar to MS Word. I haven’t finished the whole article yet, but it looks really informative. Plus you can download all the source code for his sample app :)

http://www.codeproject.com/smartclient/SmartClientSOA.asp

Javascript Event Handlers

Wednesday, January 24, 2007 @ 1:51 AM :: 232 Views :: 0 Comments ::

I was looking for a way to attach an event to ALL the input fields on a web page and found this little ditty that lets you attach event handlers to all instances of an element with one call :)

<html>

<head>

<title>title>

<script type="text/javascript" language="Javascript">

function addEvent(obj, evType, fn)

{

    if (obj.addEventListener)

    {

        obj.addEventListener(evType, fn, true);

        return true;

    }

    else if (obj.attachEvent)

    {

        var r = obj.attachEvent("on"+evType, fn);

        return r;

    }

    else

    {

        return false;

    }

}

 

addEvent(window, ''load'', function() {

 var input;

 var inputs = document.getElementsByTagName(''input'');

 for (var i = 0; (input = inputs[i]); i++) {

   addEvent(input, ''blur'', myBlur);

 }

}

);

 

function myBlur()

{

    alert("My Blur");

}

 

script>

head>

<body>

<form name="myform">

header

name: <input type="text" name="fname" /><br>

email: <input type="text" name="femail" /><br>

footer

form>

body>

html>

When the window loads, this code will select all the "input" elements on the page and attach my custom function/event handler "myBlur" to each of them.  Which means that anytime ANY of the input fields loses focus, the myBlur function will be called

Modifying the DotNetNuke SearchResults module

Wednesday, January 24, 2007 @ 1:48 AM :: 268 Views :: 0 Comments ::

Today I was working on a client''s website, trying to integrate an event calendar system that we have with their DotNetNuke site search.  The DNN site search input and search results are actually two different modules.  The problem is that our events system is a separate application with its own database. The challenge was to make the DNN site search include the events from our external system in the search results in such a way that visitors wouldn''t know the difference between DNN results and our event system results.  There are probably numerous ways to accomplish this, but we needed a very quick turnaround time and it had to look like it was still part of DNN.  So here''s what I did:

  1. Created a  stored procedure in the events database that would accept a "searchWords" parameter and would return the relevant rows
  2. Downloaded the "source" version of DotNetNuke 3.2.2 from the dotnetnuke website www.dotnetnuke.com
  3. Opened the VS solution file inside "\Solutions\DotNetNuke.Providers"
  4. Opened "SearchDataStore.vb" inside the "Provider.Search.DataStore" project
  5. Appended my custom search code onto the end of the "GetSearchResults" function (which starts at line 336 of the .vb file) I inserted my code right before the return statement. The basic steps for this part are:
    1. Call your stored procedure or whatever code you''re going to use to do your custom search, passing it the "Criteria" variable (provided by DNN)
    2. Loop through your results and create a "SearchResultsInfo" object for each result and add it to the "Results" collection which is of type "SearchResultsInfoCollection"

    1 // create SqlConnection, SqlCommand, SqlReader, etc.

    2 SqlDataReader reader = new SqlReader()

    3 // Fill your DataReader, other code omitted...

    4 While (reader.Read())

    5     Dim eTitle As String

    6     Dim eDesc As String

    7     eTitle = reader.GetString(4)

    8     eDesc = reader.GetString(1)

    9 

   10     Dim myResult As New SearchResultsInfo

   11     myResult.Author = "Kevin S."

   12     myResult.AuthorName = "Kevin S."

   13     myResult.Guid = "111" //fake/placholder

   14     myResult.Image = 0

   15     myResult.ModuleId = 367 //should be a real moduleId

   16     myResult.Description = eDesc

   17     myResult.Occurrences = 1

   18     myResult.PubDate = reader.GetDateTime(2)

   19     myResult.Relevance = 1000

   20     myResult.TabId = 36 // should be a real tabId

   21     myResult.Title = eTitle

   22 

   23     Results.Add(myResult)

   24 End While

You''re done!  DNN will use the info you specify for each SearchResultsInfo object to build a URL and link your search results to the Tab you specified automatically.  As you can see a lot of the values I used are just placeholders/filler in this case, since my custom search results don''t really pertain to a particular "tab" or "moduleid".  I''m sure there are more "provider-like" ways to customize the DNN search without modifying the DNN core source code, but this was the quickest way I found today :)

SQL Server 2005 "COALESCE()" Function

Wednesday, January 24, 2007 @ 1:47 AM :: 1463 Views :: 0 Comments ::

The COALESCE() function in SQL Server 2005 is cool.  Say you have a database schema as follows (primary keys highlighted in bold):

Widget
widgetId
widgetName

Category
categoryId
categoryName

WidgetCategories
widgetId
categoryId

According to the schema, one Widget could be in zero or more categories. Of course we can write queries to return rows of widgets, and we can write queries to return WidgetCategories for a specific Widget. But what if we wanted to select 1 specific widget by widgetId, and in that row have a column called "categories" that held a comma-separated list of categories that the widget is in?  This might be useful for some kind of summary page where you would want to see all the categories a widget is in, in ONE QUERY.

Enter the COALESCE() function!  Check out the SQL Function below and the SELECT query after it:

    2 CREATE FUNCTION dbo.fWidgetCategories

    3 (@widgetId int)

    4 RETURNS varchar(5000) AS

    5 BEGIN

    6  DECLARE @list varchar(5000)

    7         SELECT @list = COALESCE(@list + '', '','''') + Category.[categoryName]

    8         FROM Category C INNER JOIN WidgetCategory WC

    9         ON WC.widgetId = C.widgetId

   10         WHERE WC.widgetId = @widgetId

   11       RETURN @list

   12 END

The SELECT query:

    2 SELECT W.widgetName, dbo.fWidgetCategories(W.widgetId) AS categories

    3 FROM Widget W

These two things will accomplish exactly what we are looking for and return:

widgetName                    categories
widgetA                           sprockets, rockets
widgetB                            gizmos, gadgets

Very cool!  I believe the COALESCE function is present in SQL Server 2000 also.

on-site hacking

Wednesday, January 24, 2007 @ 1:46 AM :: 206 Views :: 0 Comments ::

Something caught my attention on the show "Excavators" on the Discovery Channel tonight.  I don''t watch this show regularly, but sometimes I just leave the Discovery Channel on in the background at home and then pay attention when something interesting comes on.

Anyway, the show is about these HUGE excavating machines that are used in massive open-air mining operations to shovel earth into really big trucks that haul it away and process it.  I don''t know all the exact specs of the machine because I just caught the last third of the show, but if you stood next to one of its caterpillar tracks your head would only be about halfway to the top of the track!

In addition to all of the mechanical complexities of the shovel, it also had an extensive amount of electrical sensors and circuitry (I think they said something like 1 million feet of electrical wire!) all controlled by a central computer.  The operator of the rig has a monitor with a custom GUI on it that is used to control the digging operations and the movement of the rig in general.

Now, the show was mainly about the assembly of this thing at the dig site (since they''re too big to transport in one piece) and how they had these teams of mechanical engineers and electricians assembling this thing on-site over a period of about 8 months.  The show really focused on the problems that arose in the last 7 days before the "launch date" (the date in which it was scheduled to start digging).  Once the electricians had run all the wires and connected everything, it was time to do some test runs with the digger and the caterpillars, and this is where it caught my attention.

Since the entire excavator is controlled by a central computer (called the "Centurion" system) it makes sense that they would have the software guys on-hand.  The crew ran into a couple very major problems:

  • A software bug was preventing the main drum (the part that raises and lowers the digging arm) from turning/moving at all
  • A software "typo" (as described by the software engineer working on-site) was preventing the excavator from moving its caterpillar tracks (preventing any movement at all of the rig)

What was astonishing to me was the WAY in which these guys went about debugging:

  1. Plug in a laptop to the excavator''s computer system
  2. Open up some kind of IDE (couldn''t tell what it was or the language from the TV screen)
  3. EDIT THE CODE DIRECTLY ON THE EXCAVATOR
  4. Compile
  5. Test if the code change fixed the specific problem (it did)
  6. Fix other problems that arose as a result of the first code fix (there were several, including one that could cause one of the motors to catch on fire!!)
  7. Call it good and continue

Now, these guys were in a time crunch with a $10 million piece of equipment and they had to get it done, but I have to say: Where''s the rigorous QA process?

At my place of work, we try to avoid the scenario of making code changes on a live/production system because you never know the full ramifications of any change you make.  Even after extensive testing in a staging environment, critical bugs can still arise.

It was just kind of a shock to me that:

  1. These guys had such serious/critical bugs that they didn''t know about (they gave me the impression that they had just written the code that morning!)
  2. They (and their customer) were totally comfortable with making changes right on the live system

This kind of thing makes me think a lot harder about industries where software plays a much more critical role, such as medical monitoring systems and equipment...  "Sorry about the defibrillator that fried your heart, turns out we put that damn decimal place one spot too far to the right...."

 

Old School AJAX

Wednesday, January 24, 2007 @ 1:44 AM :: 229 Views :: 0 Comments ::

I''m working on a project right now for a client that uses what I consider to be "old school AJAX" for Classic ASP pages (before .NET).  The main function for AJAX enabled applications utilizes a Javascript function called "XMLHTTPRequest".  The Classic ASP version of XMLHTTPRequest is called RSExecute and let me tell you, it is one tough mother to debug!  Luckily the MSDN documentation provides some help in tracking down Remote Scripting errors, but I was still reduced to healthy amounts of alert() and MsgBox() statements in order to get things working.

It''s interesting to see the progression and history of so-called "new" technologies like AJAX, especially when in this case the functionality has been there for several years (it just needed a cool techie name in order to become more popular).  Microsoft has gotten on-board the AJAX train in .NET using what they call "Client Callbacks" in ASP.NET 2.0.  I''m hoping that Microsoft''s newest API for doing client-side remote scripting is easier to use that RSExecute!

DotNetNuke E-Commerce / Store modules

Wednesday, January 24, 2007 @ 1:42 AM :: 250 Views :: 1 Comments ::

Why hasn''t anyone made a decent e-commerce / store module for DNN? I''ve been looking for one for about 2 months now that is easy to use (from both an admin and shopper standpoint) and has support for the popular payment processors such as Authorize.net and PayPal, and has an option for manual payment processing (just storing the credit card info for offline processing).  So far I have not found anything that satisfies all of those criteria.  The only one that comes close is the PortalStore module from www.dnn-modules.com It''s got a lot of features, but the UI is terrible and the interface is a bit clunky for both the admin and the shopper.

If I could find the time I''d sit down and write one myself, but I''m just too busy right now.  I guess I''ll have to add it to my never-ending list of projects....

DotNetNuke Module Development

Wednesday, January 24, 2007 @ 1:39 AM :: 233 Views :: 0 Comments ::
I wish someone could explain to me why the DotNetNuke module framework only allows ONE "View" control for each module.  I''m working on a module right now that needs 3 different view controls, but anytime I try to load one of the non-default (according to the module definition) view controls DNN forces the admin skin on it and I lose the other panes.  Why can''t I just load a specific view control for my module and have it keep the other panes!  aaahh!  The only solution I''ve found that other people have used is to implement a dynamic control injection scheme using the query string and a big switch statement inside their one default view control which dynamically loads other view controls as needed in-place.  Unfortunately, when you do that you lose a lot of features like module actions per view control and design time event assignments to your buttons, datagrids, etc. on each page.  Say it isn''t so!  Someone please tell me there''s a better way......