Creating a simple dynamic menu in ASP.NET MVC

Menus are one of the most basic elements on any website, but there’s not a simple dynamic menu out of the box in ASP.NET MVC.  There are several third party solutions you can add as an HTML helper or in a controller, but in several projects I’ve needed a simple and quick way to generate a menu.  Here’s an updated version of something I wrote a while ago in just such an occasion.

We’ll use VS 2010 and the new jQuery Menu widget for the UI (the standard menu CSS won’t work).  You can use any CSS or JavaScript menu UI you want to–I’m using jQuery because it’s free and easy.  You can find the Git repo for this project at https://bitbucket.org/rjdudley/simple-dynamic-menu-in-mvc.

1. Start by creating a new ASP.NET MVC 4 Internet Application.

2. The default template installs jQuery 1.7.1 and jQuery 1.8.2, but the menu widget was released in jQuery 1.9 and jQuery UI 1.10.  The easiest way to update jQuery and jQuery UI is via NuGet.  Install both the latest jQuery and jQuery UI.

One glitch in this sample is the jQuery menu widget–this is a vertical menu.  A horizontal menu will be in the menubar widget, which has not yet been released.  It was supposed to be in 1.9 but didn’t make the cut.  Not a big deal, since this isn’t a post about the UI, but fair warning.

3. Let’s make the jQuery menu work first.  Open Content/Site.css, and find around line 180 where the menu styles are.  Comment out all of the menu styles, it should be about 25 lines of code total.  These styles will conflict with the jQuery menu.

4. To help prevent page flash oafter loading and to make sure all CSS elements are in place before a script is executed, we load CSS files at the top of the page.  Just below the Styles.Render directive, add links for jquery.ui.core.css, then jquery.ui.menu.css.  The code should look like this:

@Styles.Render("~/Content/css")
<link href="../../Content/themes/base/jquery.ui.core.css" rel="stylesheet" type="text/css" />
<link href="../../Content/themes/base/jquery.ui.menu.css" rel="stylesheet" type="text/css" />
@Scripts.Render("~/bundles/modernizr")

5. Next, open up layout.cshtml and scroll down to the bottom of the file. Add a Scripts.Render directive for jQuery UI underneath the one for jQuery, then a small script block to call the jQuery menu function.  The code should look like this:

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryui")

<script>
$(document).ready(function () {
$("#menu").menu();
});
</script>

@RenderSection("scripts", required: false)

 

(If you want to see how these bundles are defined, open up App_Start/BundleConfig.cs.  Later on you may want to configure all of these scripts and CSS into a bundle)

6.  If we load and run the page now, we should now have a fully functional vertical menu.  Good enough for this demo.

7. We need a model for a MenuItem, so create MenuItem.cs with the following code:

using System;
using System.Collections.Generic;

namespace SimpleMenuSample.Models
{
public class MenuItem
{
public MenuItem()
{
this.ChildMenuItems = new List<MenuItem>();
}

public int MenuItemId { get; set; }
public string MenuItemName { get; set; }
public string MenuItemPath { get; set; }
public Nullable<int> ParentItemId { get; set; }
public virtual ICollection<MenuItem> ChildMenuItems { get; set; }

}
}

 

 

8. Now we need a model for the Menu, so create menu.cs with the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SimpleMenuSample.Models
{
public class Menu
{
public Menu()
{
Items = new List<MenuItem>();
}

public List<MenuItem> Items;
}
}

 

 

9. Now that we have our models defined, it’s time to add a controller method to generate the menu.  Normally you’d do some data access, but we’re going to hard code the menu items here for the sake of simplicity.  Open HomeController.cs and add the following code:

[ChildActionOnly]
public ActionResult Menu()
{
var _menu = new Menu();

// Normally you'd do some data or cache access to build/retrieve the user's menu
// then you're loop through the results and build the menu object
// we're hard coding for the sake of simplicity

var _google = new MenuItem()
{
MenuItemName = "Google",
MenuItemPath = "http://google.com/",
};

_google.ChildMenuItems.Add(new MenuItem()
{
MenuItemName = "Google Images",
MenuItemPath = "http://google.com/images/"
});

var _bing = new MenuItem()
{
MenuItemName = "Bing",
MenuItemPath = "http://bing.com/"
};

_bing.ChildMenuItems.Add(new MenuItem()
{
MenuItemName = "Bing Images",
MenuItemPath = "http://bing.com/images/"
});

_menu.Items.Add(_google);
_menu.Items.Add(_bing);

return PartialView("_Menu", _menu);
}

 

 

10. Now that we have a model and a controller, we need a view to display our menu.  Create a shared view named _Menu.cs with the following code:

@model SimpleMenuSample.Models.Menu
<ul id="menu">
@foreach (var item in Model.Items)
{
<li><a href="@item.MenuItemPath">@item.MenuItemName</a>
@if (item.ChildMenuItems.Any())
{
<ul>
@foreach (var subitem in item.ChildMenuItems)
{
<li><a href="@subitem.MenuItemPath">@subitem.MenuItemName</a></li>
}
</ul>
}
</li>
}
</ul>

 

11. One final change is to call the menu from _Layout.cshtml.  Change the nav element to look like the code below:

<nav>
@Html.Action("Menu","Home")
</nav>

 

And that should be a bingo!  When you run the project, you should see a (rather ugly) vertical menu (seen below).  Hovering over one of the options should cause the child entry to appear.

image

Hope this helps!

An Unofficial Guide to CodeMash

Preface: Be excellent to each other.  Please, just be excellent to each other, and have a good time.

In the last few years, I’ve been a sponsor/exhibitor/speaker/attendee at CodeMash, and it truly lives up to the hype of being one of the greatest conferences you can attend. The organizers do an incredible job running the event and choosing the speakers, ad the Kalahari provides a great atmosphere. It’s a large conference, with around 1300 attendees, plus speakers, volunteers and exhibitors. I’m always trying to recall all the good information I mean to tell people when I try to explain CodeMash to first time attendees, so I’m putting it here for future reference.

There are changes from year to year, and I’ll try to keep this post updated from year to year as I attend. Please leave comments if I miss something.

CodeMash is special because it’s unique. They don’t franchise or have regional events (and the organizers request you please stop asking). Enjoy the uniqueness of CodeMash, it’s not your usual conference.

Join the Google Group!

If you’re interested in CodeMash but haven’t joined the CodeMash Google Group, you need to do so. There is a little activity through the year, but starting a couple weeks before speaker submissions, traffic picks up.

In addition to all the information around the conference, this is also the best place to find rides to share, tickets for sale and so on. Activity is high in the two weeks prior to CodeMash with offers to tranfser tickets and rooms.

If you got a ticket/room, but can’t go

First of all, bummer. You can cancel your ticket via EventBrite for a refund, or you can post a ticket in the Google group for someone to buy your ticket (how they pay you is up to you). You can directly transfer your ticket to someone else via EventBrite.

If you had a room at the Kalahari, don’t cancel it. Instead post it in the Google group. The Kalahari will transfer rooms between attendees. There may be a $25 charge for this, I’m not sure, I’ve never done this. If there is, you’ll have to work out how the person pays you. Usually, PayPal is used.

If you don’t get a ticket

CodeMash sells out fast–within minutes of tickets going on sale. Lots of people don’t get tickets. It’s OK, your life isn’t over. Don’t panic, put yourself on the waiting list and monitor the Google group. Tickets are handled via EventBrite, and there is easy functionality to transfer a ticket from one person to another.

If you can’t get a room

Not only does the conference sell out quickly, so does the Kalahari. The organizers have additional arrangements with nearby hotels for pricing and shuttle service (by now you can guess where the details will be posted). Parking is free and plentiful at the Kalahari, so if you’re driving in and staying offsite, consider driving over and offering a ride to others.

There is a cheerleading competition the weekend following CodeMash. When you make your reservation, if you want your family to come that weekend, factor that in. It might be easier to have the family come before the conference, rather than stay after.

The Kalahari provides regular shuttle service to some of the other nearby hotels for CodeMash, information is posted in the Google group ahead of time and is available at registration once you’re there.

Getting there

The Kalahari is in Sandusky, OH, near Cedar Point. It’s not in Cleveland. In fact, it’s a nearly 45 minute trip from the Cleveland airport to the Kalahari. No better from Akron/Canton or Toledo. I live about 2.5 hours from Sandusky, so I just drive over, and I’m not familiar with the transportation from the airport. You’re looking at a pricey cab ride though (roughly $130, plus tip). The Kalahari has shuttle service to/from the airport for about $85 (and $25/person after the first), or you can arrange with one of the local airport shuttles or town car services. Many attendees have used Toms Cruz. Not to sound like a broken record, but the Google group is a good place to find people arriving about the same time and wanting to share a ride.

Weather/News Alerts

CodeMash wouldn’t be CodeMash without some sort of blizzard.  Depending on when and how you’re arriving, you may be significantly affected.  CodeMash 2.0.1.4 saw a Level 3 snow emergency on Monday prior, which means you could be arrested if you’re on the roads.  Here are some resources to watch for local travel conditions (remember the Kalahari is actually in Erie County, OH):

http://www.erie-county-ohio.net/(specifically the Sheriff’s office page)

http://www.toledonewsnow.com/

http://www.sanduskyregister.com/

http://www.northwestohio.com/weather/

http://www.northwestohio.com/weather/contents.aspx

http://fox8.com/

While you’re there

The Kalahari in January is basically a bio-dome (if you like stupid movies, that’s a great one). The place is massive and self-contained. If you’re staying there, expect to walk a lot and get lost frequently. Elevators are usually jammed, so knowing where the stairs are is helpful. People with Fitbits or pedometers report walking a couple miles each day! The last couple years have featured a blizzard, which adds to the excitement of being self contained.

The conference supplies WiFi, which can get crushed. Don’t be a hog, only connect the devices you need connected. Once the conference starts, most of the chatter happens on Twitter. It’s where you’ll find rides, dinner offers, parties and so on. Make a column for a search on #codemash. If you’re not on Twitter, you will miss out on the unofficial side activities.

CodeMash has started to use EventBrite as its app.  Additionally, session data are provided via an API and attendees can go to town.  There are apps for iOS, Android, WP8 and Win 8, plus the dead tree version at registration.  There are multiple simultaneous events, so the schedule is something to keep an eye on. Last minute changes are communicated on signs near the registration desk.

Bring business cards or personal cards. Take Moo or VistaPrint up on an offer of free or cheap cards. Few people care about your physical address anymore, but be sure to put all your social contact on there (LinkedIn, Twitter, Facebook if you’re so inclined). You’ll use these to enter sponsor raffles as well as an easy way to exchange contact information with new friends. These are especially nice if you have a name or social ID which is difficult to spell or remember. If you can, put a vcard as a QR code or Microsoft tag on there.

Your cell phone will die during the day, so pack and plan to carry your charger with you.

What to wear

It’s January on the shores of Lake Erie. Although you’re basically having a grown-up lock-in, a warm jacket and clothes are necessary. There will be probably be times where you’re heading to a nearby restaurant or something, and you’ll get to experience Lake Erie weather (think Edmund Fitzgerald). Otherwise, during sessions, flip flops, shorts and a Hawaiian shirt are perfectly acceptable (not kidding). If you get cold easily, you may want to wear jeans and keep a sweater handy–the air conditioning in the rooms is either too cold or too hot, and everyone’s opinion differs.

According to Keith Elder (2013’s emcee):

Wear whatever is comfortable or that is *you*. If you dress up too much you’ll probably feel over dressed and out of place.

You’ve heard the saying “He/She was dressed to the 9’s” ?

For Codemash you want to dress to the 4’s – 6’s. Hit that sweet spot of comfort-ability, individuality, and geekiness.

Jason Follas (one of the organizers) recommends:

You would be in good company wearing jeans and a t-shirt… Though, it sometimes gets chilly, so having a sweatshirt/sweater can be useful.

You’ll see some people in shorts and Hawaiian shirts. Others will be business casual. I’m betting there will be one guy wearing a bow tie (seriously).

The most important thing is to be respectful of others (i.e., no profane slogans on T-Shirts, or swimwear in the conference area, etc.) and to be comfortable with whatever you wear.

In addition to the bow tie, you’re also likely to see a kilt or two.

Remember those two miles or more of walking each day? Wear good walking shoes, too.

T-shirts from sponsors will be plentiful on the first day. Of course, you’ll want a bathing suit, too, for the party in the waterpark. And, obviously, always pack your towel.

Eating

CodeMash provides breakfast and lunch on Tuesday, Wednesday and Friday, and breakfast, lunch and dinner on Thursday only. Highlights of the food include the bacon bar and bring-your-own-hot-sauce table. If you have a favorite hot sauce, bring a bottle and share it. If you enjoy hot sauce, this is a treat.

The Kalahari has several restaurants on-site, but they get full and are resort pricing. If you have the means to travel (either your own wheels or new friends), there are a number of restaurants a mile or two north (take a right from the Kalahari entrance) on the main road. These include a Buffalo Wild Wings, Olive Garden, Ryan’s Steakhouse, Outback, Chili’s, Applebee’s and Panera. One we found that’s about 15-20 minutes away is the Angry Bull Steakhouse. Spectacular bacon wrapped filet mignon. ’nuff said.

You’re not actually going on safari, although the Kalahari decorators might appreciate you thinking so.  There is a Wal-Mart and other grocery stores a little north of the Kalahari, right around the Routes 2/250 interchange, and you can stock up on supplies once you arrive.

Most rooms have a small coffee maker, and there is a coffee shop on site. However, the coffee shop does not scale well. Regular coffee and tea is available at times during the day, but you’re own your own for other refreshments. There is a Starbucks a couple miles up the road near the other restaurants if you’re dying for your Mochacocoafroppaccinno.

Most rooms also have a small fridge (the suites have a real kitchen), and there is a Wal-Mart and a grocery store a couple miles up the road also. You can stock up on some essentials there.

Remember to hydrate! Bring a favorite water bottle, or maybe you can find a swag one. You will get thirsty with the dry air and moving around.

Social Activities

Outside of normal conference activities, there is an official game room, with dozens of games brought by attendees (bring your favorite), and both an acoustic and electric jam session. Bring your favorite instruments, or the conference supplies some.

In 2013, the Kalahari opened a new bar named Longnecks in the conference center, which will be open for CodeMash each night. Room parties are plentiful, and some sponsors also host activities.

The conference itself

The almost exact session schedule will be available via the apps or (usually) printed in your swag bag. Last minutes changes will be posted by registration and announced at meals. The 30,000′ view for 2013 is posted at https://groups.google.com/forum/?fromgroups=#!topic/codemash/m_zHu0TePpY.

You will not be able to attend all the sessions you want to–there are too many good ones. The law of two feet applies. If you find a session isn’t what you thought it was, move to a different one. Speakers know this too, no big deal. Just don’t make a ruckus as you depart.

In addition to the sessions, there is KidzMash, the unbelievably entertaining Pecha Kucha talks, the game room, Magic the Gathering tournament and the jam session. Plus parties.

Don’t forget to visit the sponsors and thank them! CodeMash wouldn’t happen without them. In addition to cool prizes, they have products which may help you in your daily life, and many sponsors are recruiting talent. You may find an awesome new job there.

Save the WiFi!

One of the complaints about every conference is the WiFi is slow.  CodeMash and the Kalahari have made great improvements but we the attendees need to do our part.  CodeMash has stats on what the largest bandwidth hogs are (and reserves the right to block these).

Please be sure to turn off the following things while you’re here (you’ll be back to civilization in a couple days, and you can resume your normal bandwidth consumption then):

  1. Automatic updates
  2. Carbonite/Mozy backups
  3. Torrents (both downloading content and service as a torrent host)
  4. Streaming radio or video
  5. Tor relays
  6. et cetera.  Be respectful of your fellow attendees.

Additionally, if you know you’ll be in a session with prerequisites, please make sure you download and install these before you leave for the conference.  CodeMash does have an onsite server for prereqs also, so if you find something you missed you can access that.  Information is in the conference book you get at registration.

How to behave

Be comfortable in your own skin. Too often at conferences I see people afraid to interact because they may not be as knowledgeable as the other attendees and they’re afraid they’ll be judged. That’s never the case, especially at CodeMash. What you know has value, what you don’t know is a topic for conversation. Being at a conference is as much about sharing as it is absorbing what is being shared.

CodeMash is not a stuffy, tightly wound conference. The organizers have a sense of humor. Don’t be afraid to relax and be yourself (even if being yourself means you’re tightly wound). You’ll see all kinds of silly things around the conference, enjoy the atmosphere.

One great advantage of being at the Kalahari is the social interaction, so if you’re staying offsite, plan to hang around the Kalahari and socialize. Talk to speakers and other attendees. Everyone is available, and you’ll have plenty of chances between sessions, during meals and at the social activities. The sessions are great, but the hallway sessions are often the best. We’ve come up with all kinds of crazy ideas and brilliant solutions around a packed dinner table covered with wings.

To foster an environment of sharing, the organizers have a strict policy against making people feel bad. Briefly, “Be excellent to each other, and party on, dudes!”

Officially, to quote the CodeMash Anti-harassment Policy:

CodeMash is dedicated to providing an outstanding conference experience for all our attendees, regardless of gender, sexual orientation, disability, physical appearance, body size, race, religion, financial status, hair color (or hair amount), platform preference, or text editor of choice.

We do not tolerate harassment of conference participants in any form, and we would like to take this opportunity to remind all attendees of the basic premise CodeMash was founded on: passionate, but respectful dialog between our attendees. Please treat your fellow attendees with respect, regardless of the context you’re interacting with each other.

Harassment is not appropriate for any conference venue. Conference participants violating these rules may be sanctioned or expelled from the conference, without a refund, at the discretion of the conference organizers.

When you arrive, check you ego and judgment at the door. Enter with a wide eyed sense of wonder, you’re going to learn some awesome things. CodeMash is a great opportunity to learn from others, so take the opportunity to learn something new and different. IMHO, if you don’t leave planning to try something totally new, and knowing where to start, you did it wrong.

Thank the organizers, volunteers and Kalahari!

CodeMash is entirely run by a team of volunteers, and make sure to thank them for a job well done. From trying to narrow down thousands of submitted talks into around 200 sessions, to arranging hotels, food and transportation, sponsors, A/V and more, the organizers put in a tremendous amount of time and effort. In 2013, expenses for CodeMash were around $610,000 and income from sponsorships and registration was around $640,000, leaving a very tight margin for anything last minute. All the little things add up, so you can see the job in enormous. If you’re so inclined, a hugboard has been set up at http://www.hugboard.com/eacd3af021/contribute.

Also, be cool to the Kalahari staff. They work overtime to ensure a great conference, and it’s a very stressful week for them.

In conclusion

The hallmark of a great conference is one you’re sad to leave, and anxious to come back to. CodeMash provides a great environment, but it’s up to you to make it awesome for you. Participating and interacting are key to making your CodeMash experience awesome. The secret sauce of CodeMash is partly organization, partly Kalahari, but mostly attendees.

FAQs

1. Do I get waterpark party passes if I have a CodeMash ticket but am staying offsite?

Yes!  The waterpark party is a conference event, not a hotel event.  Kalahari guests do have access to the waterpark at all times, which offsite attendees do not, but that mostly benefits guests with families along for the ride.

Billy Hollis and the .NET Rocks Road Trip in Pittsburgh

The .NET Rocks Road Trip is coming to Pittsburgh, with special guest Billy Hollis! The crew will be here on October 11, 2012 from 6-10pm at the Sheraton Station Square.

For anyone not in the know, .NET Rocks is perhaps the longest running podcast for developers, with over 800 weekly episodes. Billy Hollis is a well known speaker, author, consultant and trainer. I’ve seen Billy speak on a number of occasions, and he is a very engaging and informative speaker. This is a great opportunity to see all three of these guys in one place.

Fajita dinner will be served starting at 6, and the festivities will begin promptly.

Here’s how the evening shakes out:
Intro by Carl and Richard (10 mins)
Carl builds a Windows 8 application (60 minutes)
Richard demonstrates DevOps toolchain with VS2012 and SCOM (60 minutes)
Billy’s talk, whatever is on his mind (15-20 minutes)
Billy, Richard and Carl record a DNR based on Billy’s talk (45-60 minutes)
Swag!!!!

For more details on the evening, and registration, go to http://pewee.ws/5m

Packt Publishing reaches 1000 IT titles and celebrates with an open invitation

As a Packt author, they asked me to help share the great news—Packt is about to publish its 1000th book!  To celebrate, everyone who registers on at http://packtpub.com/ by September 30 will receive a free gift.  Here is their press release:

Birmingham-based IT publisher Packt Publishing is about to publish its 1000th title. Packt books are renowned among developers for being uniquely practical and focused. Packt books cover highly specific tools and technologies which IT professionals might not expect to see a high quality book on.

Packt would like you to join them in celebrating this milestone with a surprise gift – to get involved you just need to have already registered, or sign up for a free Packt account before 30th September 2012.

Packt published their first book in April 2004. One of the most prolific and fastest growing tech book publishers in the world, they now have books on everything from web development to web graphics, e-learning to e-commerce, IT architecture to games, and app development.

Packt supports many of the Open Source projects covered by its books through a project royalty donation, which has contributed over £300,000 to Open Source projects up to now. As part of the celebration Packt is allocating $30,000 to share between projects and authors in a genuinely unique way, soon to be disclosed on their website.

Dave Maclean, founder of Packt Publishing explains, “At Packt we set out 8 years ago to bring practical, up to date and easy to use technical books to the specialist tools and technologies that had been largely overlooked by IT publishers. Today, I am really proud that with our authors and partners we have been able to make useful books available on over 1000 topics and make our contribution to the development community.”

For more information about Packt, the kind of books they publish, and to sign-up for a free account before the 30th of September, 2012, please visit their website: www.PacktPub.com.

My Take on Metro JavaScript Apps

(Preface: This post is my opinion only.  It represents some thoughts I’ve had rolling around in my head for a while.  To free up some space in my brain, I’m draining this thought pool now.  I’m in no way trying to tell anyone what’s “right” or “wrong”—those are decisions based on your own set of circumstances.  I could be totally wrong here.  Wouldn’t be the first time, won’t be the last time.  Feel free to leave polite comments.)

Since last October I’ve been giving a talk on using jQuery in a Metro JavaScript application.  It’s been well attended and well received, and it gave me a good opportunity to work with Win 8 through its various releases.  After we first finished the sample, I sat there and thought “that’s cool, but who would do this?”  Let me explain.

It’s not that I think Metro is going to flop.  I don’t—I think consumers, especially those with a Win 8 tablet, will go nuts for Metro apps.  Enterprises overall will be slower to adopt Metro, but you can bet we’ll see the best of the best as we approach RTM and GA.  I just think most of the Metro apps will be written in XAML, not JavaScript.  Microsoft did a fine job with the capabilities of WinJS libraries (especially feature parity between XAML and JS), and when combined with the tooling, Metro JS app development is relatively painless.  I proffer two reasons why I feel adding a JavaScript option isn’t as important as it first seemed.

First, there are far fewer web devs in the world than people think.  Most of us who call ourselves web devs actually are writing native applications, the UI of which is merely a final output which is displayed in a browser.  Most of us have a heavy reliance on a server side framework, be it ASP.NET, Ruby, PHP, Java or whatever.  In Metro apps, there is no server framework available to us.  I consider “pure” web development to be based on client side Ajax calls and DOM manipulation, coupled with SOA, which is the architecture of a Metro JavaScript app.  Ironically, some of the “purest” “web development” you would ever do is writing a native Windows (Metro) app.

Secondly, I’m of the opinion that web devs don’t write native apps not because they can’t, but because it offends the sensibilities that their app won’t (at least in theory) run everywhere.  It’s not enough that an app will work on all Windows machines—there are Macs, Linux, tablets and (with a little extra work) smartphones out there.  One codebase to rule them all!  Remember, web devs obsess over a 1 pixel difference in how FireFox and IE render inputs.  To us, the browser is the OS, and is the device.  We care not whether Chrome is running on Mac, Windows or Linux (as Chromium).  In fact that’s what we find appealing.  While an attractive option at first, I think the realization that these are OS-specific apps will slow the adoption of Metro JavaScript.

None of this is not to say that there won’t be some great JavaScript apps produced for Windows 8.  There will be.  I’m just of the opinion that over time the numbers will favor XAML apps.

How we did EDI via AS2 with /n software’s AS2 Connector and BizTalk 2009

Two “lives” ago, I led the team of enterprise developers.  We did everything from the data warehouse/BI to LOB apps to systems integration.  It was good times, we kept busy.  It is an amazing company, small with people but with big revenues and big needs.  As our trading partners and services grew, we needed to significantly upgrade our EDI capabilities, including AS2.  After several months of evaluating solutions, we settled on BizTalk, because it was very flexible with EDI mapping, could multicast documents (which we needed to do), and would handle other types of messaging as well (we had a requirement for XML between several systems).  We settled on BizTalk 2009, which as it turned out had its share of issues and limitations we found out later.

One of the limitations of BizTalk’s AS2 connector is that it had to run on the same machine as BizTalk (I don’t know if this has changed or not).  This meant either having a second license of BizTalk just for AS2 (cost prohibitive), putting a production server in the DMZ (stupid) or poking a hole into our internal network (over the network admin’s dead body).  Time to find a new, simple, cost-effective solution.

This time the decision was significantly easier.  We looked at a number of options, from hosted solutions to AS2 apps, but /n software’s AS2 Connector was exactly what we needed (they moved the current version of the connector to their RSS Bus product line, so don’t panic since the company brands don’t match).  Just to clarify, /n software’s EDI integrator is a component for building your own AS2 solutions.  The AS2 Connector is a pre-built application with most or all of the functionality you need–this is what fit the bill for us.

In a nutshell, here’s what we did:

1. Installed the AS2 Connector on a web server in our DMZ.  Since we had several web servers already, and AS2 is pretty low bandwidth, nothing additional was required here besides the SSL certificate.  Setup and config was insanely easy on our IIS box.

2. The version we used dropped all the AS2 files into one folder. To make it easy for BizTalk’s processing rules, we needed to sort them by trading partner.  The connector did have the ability to call a batch file after a receive was complete.  We wrote a PowerShell script (called by a BAT file) to read the ISA line, and move the files to a folder named for the trading partner ID.  We also had T and P folders, based on the test indicator.  This was back in 2009–I think the current version does this now without needing a “sorting hat” script.

3. On that same web server, we had a TFTP server set up.  We secured it to only accept connections from a particular IP (corresponding to our BizTalk server), and had a specific firewall route exclusive for the BizTalk server into the DMZ.

4. We scheduled BizTalk to check the folders every few minutes.  One of the downsides to this approach is that you lose BizTalk’s file system watcher capabilities.  BizTalk picked up the files via FTP and processed them per the rules we had configured.

What we ended up with was a very flexible system that was easy to expand as we brought on new trading partners, and we could meet all kinds of crazy new requirements.  We actually started to become the go-to integration partner because of how fast we could adapt to changes and the processing we could do on the received information.

Of huge importance for a couple of our trading partners we brought on later was having a Drummond Certified solution.  Fortunately, the AS2 Connector was (and still is) Drummond certified.

Something to remember that AS2 is not EDI–AS2 is just a way of transferring files.  You can send nearly any file type via AS2.

The one where I’m now a free agent

Suffice to say, this isn’t a blog post I thought I’d be writing at this time.  As of July 2, 2012, I am no longer a ComponentOne employee.

I truly enjoyed working there.  I gave my heart and soul to the company, and no one could miss my enthusiasm for my coworkers or our products.  I have many good friends at ComponentOne, and I’ll miss seeing them and working alongside them daily.

My time at C1 was amazing.  I learned so much, and I met so many wonderful people I would not have met otherwise.  Obviously I won’t be traveling nearly as much as before, but I still want to get to one or two good events each year.  I’m leaving behind a good legacy—I’m the #1 blogger at the company, I’ve delivered dozens of talks at dozens of events across the country, and there’s no doubt my efforts are a huge reason why ComponentOne is back in the consciousness of the community.

I’ll miss my friends—both in C1 and the community, but the timing was good for me.  Two years ago when I was hired, I said this would be a two year role for me, and if my future beyond that was at C1, then great, otherwise, it was a good run but no hard feelings.  It’s a statement I’ve repeated several times since then.  The grind of travel and writing talks was wearing me down, and I was really feeling it this year.  I was missing my family more and more with each trip.  Although the reason and timing weren’t exactly of my choosing, it’s not far off from when I would be making the same call.

It’s been a crazy couple of weeks since CodeStock.  I was accepted into ASP Insiders, and Pluralsight commissioned me to develop courses.  The next few weeks I’ll be working on some back-burner projects, which is very exciting.  It’s time to reinvigorate this blog.  And, I’m looking forward to my exciting _________ career.

If I was in the middle of doing something with you, you’ll need to get in touch with Kevin Griffin (keving@componentone.com) to pick up where we left off.

It’s been an awesome run, I look forward to the next time we meet.  Whenever that is, remember Russ or Kevin is buying now.

Moving A WordPress Blog To A New Host

I facilitate several WordPress blogs, several of which I installed on DiscountASP.NET.  I wrote a blog about the process, and then as now it felt like I had to shoehorn WordPress onto their system.  I, as well as others, began to have problems administrating our blogs (notably, difficulties adding plugins or upgrading versions).

I’ve also hosted a number of domains with Applied Innovations, and I knew they added some new capabilities and a crazy new plan for Webmatrix hosting, especially ensuring the right capabilities for WordPress and other WAMP stack applications (such as Joomla, Drupal, and so on).  Better pricing and the right features-it was time to migrate.

I migrated two blogs today using the steps below, and I’m going to migrate a couple others as their current hosting nears expiration.  Moving a WordPress blog involves moving both files and a database; each has its own method.

There are a number of ways to backup and restore a WordPress blog.  The official documentation is http://codex.wordpress.org/WordPress_Backups and http://codex.wordpress.org/Restoring_Your_Database_From_Backup.  There are several plugins you can install which will backup your blog on a schedule—it’s not a bad idea to use these.  I think the method below is pretty easy and effective for a migration, but isn’t necessarily a process you want to repeat every week as part of a regular backup (unless you script it, which is possible).

Step 0: Get The Tools

I used two tools to migrate my blogs—FileZilla, to transfer the files, and MySQL Workbench to migrate the databases.  Both are free and widely available.

Step 1: Prepare Your New Host

Before you do anything, make sure your new hosting is set up, that you can log into your control panel, and you have both a new website and database set up.  On some hosts (such as AppliedI), the FTP login is the root folder, but the WWW service points to s subfoler—make sure you know where to put the files.  Keep track of your passwords!

Step 2: Clean Up Any Messes

Migration will involve exporting data from your current blog’s database, then importing all of it again into your new blog’s database.  This process, on both ends, can take some time, so obviously the less data you try and move the easier it will become.  This is the time to log in to your control panel, empty all the spammy and trashed comments, clear out posts which haven’t been published if you don’t plan on finishing them, etc.  Also, if you have any custom DNS entries made on your current host’s nameservers, such as redirecting email to GMail or Hotmail, copy those settings.

Step 3: Download The Blog Files

Log in to your current blog, and download all the files.  You’ll need everything in your blog root, as well as the three subfolders (wp-admin, wp-content and wp-includes).  Download these to your local machine, because you’ll need to edit one of them.  Don’t delete anything from your current site, just in case you need something again.

Step 4: Export Your Blog’s Data

This step requires the most explanation.  It’s not difficult, there are just a number of small things which need to be done.

Start up MySQL Workbench; the Workspace area is divided into three columns, the far right of which is Server Administration.  Below this listbox, click New Server Instance.

image

Choose the Remote Host option, and enter the name of your current blog’s MySQL Server, then click Next.

image

Give this connection a better name in the Connection Name box; this will populate a connection in the SQL Development column.  Change the Username if necessary (it probably is).  If you want/can store the password in MySQL Workbench, click the Store in Vault button next to Password, and enter the password in the dialog.  If you don’t store the password, you’ll be prompted when you try to connect.  If you need to, adjust other settings, but you probably won’t need to.  Click Next.

image

The database connection settings will be tested.  If Workbench cannot connect, you’ll need to fix whatever is wrong before you can continue.  Click Next once everything is OK.

image

Remote management takes some additional configuration, and it’s not something we’re going to do here.  If you want to use MqSQL Workbench to manage your database, you can set this up, but it’s not necessary to export/import data.

image

A bunch of intermediate steps will be skipped, and we then assign a useful name to the new Instance.  Clicking Finish here will close the wizard and create the connection and the instance.

image

Select the new instance with a single click, then choose to Manage Import/Export.

image

You may be prompted to choose the connection.

image

This is the most important set of our export.  Select your database with a single click, then choose which items correspond to your blog.  In a WordPress database, there are only tables, and by default they are prefaced with “wp_”.  The image below shows a default install, for reference.  To make the import easier, choose to Export to a Self-Contained file.  For most blogs, this will be OK, but for very large blogs, you can choose to export individual tables into separate files.

image

The export will take a few minutes—watch the progress indicator.  When complete, you can close the Import/Export window.  We need to make a couple small edits to the export file before we can use it.  If you exported to multiple files, you’ll need to make this change to all of them.

About 22 lines down is the command to create a database if it doesn’t exist.  Since our user probably doesn’t have the correct permissions to do this, we need to commend this out by adding two dashes and a space at the beginning of the line (the space is necessary).  A couple lines further down is the USE directive.  This needs to be changed to the name of our new blog database.

image

image

Step 5: Import Your Blog’s Data

If you haven’t done so already, make sure your new blog database is set up, and has a login user ID created.

Back in MySQL Workbench, under the SQL Development column, click the New Connection link.

image

Just as before, give this connection a useful name, then update the Hostname and Username (if necessary).  Again, if you want/can store your password in the vault, do so.  Once everything is correct, click OK.

image

When all is well, we’ll have a new entry in the Connections listbox.  Double-click the new blog entry to open the SQL Editor.

image

In the SQL Editor, open the dump file you created above, double-check you made the minor (but important) edit above, and run the script.  The tables should be created and populated.  If you dumped to multiple files, you’ll need to repeat this process for every file.  When all the scripts have been run, you can expand Schemas >> [your database] >> Tables and see the WordPress tables.  If you’re familiar with SQL, you can query some data at this point, too.

image

Step 6: Upload Blog Files (edit the config first!)

Before we do anything, we need to modify the database connections in our downloaded wp-config.php to point to our new host’s database and server.  These are the first four settings in the file.

image

Save this file, and upload all the files to the new host.  Make sure you’re in the right folder, whether it’s the root or a subfolder.  Once this is complete, you should be able to view your blog through a temporary URL, or your actual URL, depending on how your site is configured at this time.

Step 7: Update Nameservers

Since you’ve moved to a new host, it’s now time to update the nameservers for your domain.  This is now a good time to download any email you want to keep from your host’s email system.  You’ll probably need to update your email clients, too.

Congrats!  You should soon have your blog completely set up on your new hosting service.  Remember to cancel your old service!

Another Solution To “The list cannot be displayed in Datasheet view”

I have a fair amount of information in SharePoint 2010 (just as I did in MOSS 2007), and for speedy editing of a lot of the entries, there is no beating the datasheet view. For some time now I have been getting the following error when I tried to edit the list in datasheet view:

The list cannot be displayed in Datasheet view for one or more of the following reasons: A datasheet component compatible with Windows SharePoint Services is not installed, your browser does not support ActiveX controls, or support for ActiveX controls is disabled.

There are a lot of answers on the interwebz, none of which solved the problem for me in the past.

Recently, though, I found an answer accidentally. I was trying to import some data from an Excel spreadsheet into a SQL Server database using the Import Data task. It was throwing an error that I was able to track down to having Windows 7 64-bit. My Office 2010 is 64-bit, and the import data wizards were 64-bit, also. However, Access and Excel importers are 32-bit only, and unless you knew to select 32-bit wizards also during installation, you don’t have them on a 64-bit machine.

Finally I found a form post that pointed me to the Office 2007 Data Connectivity Components (formerly known as the Access Database Engine). Installing these solved my data import, but also fixed my datasheet view!

Now that I can load the datasheet view, this makes a lot more sense. The Access icon is clearly in the upper left corner, and the status bar says “For assistance with Access Web Datasheet, see Help.”

So, if you’re getting the same error in SharePoint, and you’re running the 64-bit version of Office, and nothing else has worked, try the Data Connectivity Components from http://www.microsoft.com/download/en/details.aspx?id=23734.

A SQL Script to generate a 4-4-5 Mon-Sun calendar table

In a previous life, I did A LOT of BI reporting, and everything we did was based on the company’s 4-4-5 fiscal calendar, and a Mon-Sun work week.  Adding to the fun was the mutant Julian style date JD Edwards uses internally.  This system violated every known calendaring convention, but “that’s how it’s set up in JDE”, and if you’re a JD Edwards shop, you know that argument renders all others invalid.  Oh yeah, the fiscal year started on a different day every year.

To make our lives easier and our apps and reports more performant, we utilized calendar tables.  Problem is, every couple years, we had to add more dates to the tables.  When this duty fell onto me, rather than being The Last Person, and spend all day fiddling with Excel and a subsequent import, I spent part of a day writing a simple script that can be run whenever necessary to add more dates.

Because we were integrating information from a number of systems (WMS, TMS, LMS and payroll, notably), all with their own equally mutant calendaring systems, we have a fairly wide table with all kinds of date indicators in it.  This script is kind of a recursion hell, but it needed to be in order to iterate all of the output columns correctly.

Below are the comments from the SQL file; you can download the entire script from this link: 4-4-5 Calendar

/*

This script is meant for a 4-4-5 calendar, Mon-Sun week. Every leap year introduces an extra week, which we add in November.

User Variables

FiscalCalendarStart = The date on which a fiscal year starts. This is used as the base date for all calculations

EndOfCalendar = The date on which the calendar should end. This does not have to be the end of a fiscal year, but if it’s not, you might have to run the script again to get to the end of the fiscal year.

RunningDaySeed = Usually 1, this is used to measure the number of days since the calendar began, often used for depreciation

RunningPeriodSeed = Usually 1, the number of fiscal months since the original calendar began

RunningWeekSeed = The number of fiscal weeks since the original calendar began

FiscalYearSeed = The starting fiscal year

Iteration Variables–don’t mess with these

JdeJulian = the date expressed in JDE’s Julian format

CurrentDate = The calendar date being calculated against

WorkWeekSeed = Fiscal Week

WorkPeriodSeed = Fiscal Month

WorkQuarterSeed = Fiscal Quarter

WeekOfMonth = Rolling week of month

FiscalWeekEnding = Last day of the fiscal week

WorkPeriodSeed = Some legacy thing we must have or the world will end.

But, used to assign where the extra “leap week” goes. Based on the 4-4-5 calendar.

IsLeapYear = 29 days in February extra week in November?

 

Output Columns (most of these exist to make reports easier)

DateSID = JDE’s Julian Date

CalendarDate = the date, duh

Sysdate = YYYYMMDD, based on calendar date

RunningDay = the number of days since we installed JDE

WorkPeriod = roughly correlates to the fiscal month

RunningPeriod = the number of fiscal months since we installed JDE

WorkWeek = The fiscal (Mon-Sun) week of the year

RunningWeek = the number of fiscal weeks since we installed JDE

FiscalYear = The numeric fiscal year

FiscalYearLabel = the pretty field used on a report

WorkQuarter = The fiscal quarter

FiscalQuarter = Another representation of the fiscal quaruer

FiscalQuarterLabel = used on reports

FiscalPeriod = YYYY + WorkQuarter + WorkPeriod (zero-padded)

FiscalPeriodLabel = used on reports

FiscalWeek = YYYY + WorkQuarter + WorkPeriod (zero-padded) + week of the fiscal month

FiscalWeekLabel = used on reports

CalendarYear = calendar year, duh

CalendarQuarter = the traditional definition of a quarter

CalendarQuarterLabel = used on reports

CalendarMonths = the traditional calendar month

CalendarMonthLabel = used on some reports

WeekEnding = the last day of the calendar week (Saturday)

FiscalWeekEnding = the last day of the fiscal week (Sunday)

FiscalMonth = Based on the fiscal calendar, relates to the WorkPeriod somehow

FiscalMonthLabel = used on some reports, based on the FiscalMonth

*/