Shopping Cart? Remove ALL hurdles for Higher Sales.

I just ordered a lens for my camcorder. I rarely order anything (apart from eyeglasses) from stores other than Amazon. I’ve had my issues with Amazon in the past, but realistically, with a recurring Amazon Prime membership, I’m pretty much “all-in” for them.

So today, when ordering from another store, I expected the hurdle I always come across — creating a profile just to place an order. I grudgingly started the process and BAM! just as I expected it, there it wasn’t.

So thrilled was I, that I nearly decided to create an account! Talk about little things meaning a lot. I immediately felt an affinity towards this company and even bypassed my typical finger-floating-over-the-mouse-button routine while I hem and haw about whether or not I really want the item in question.

All said and done, it’s ordered –something that may not have happened had I been forced to create the dreaded profile.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • bodytext
  • del.icio.us
  • Facebook
  • Google
  • Reddit
  • StumbleUpon
  • TwitThis

Why the hell am I still forced to type runat=”server” after all these years?

We’ve all seen the Microsoft guys stumble over this time and time again in demos. Why are we still forced to add this? I mean, if it’s a server control (the control starts with “<asp:”) it should be assumed — or added automatically by the Visual Studio IDE. What is this, the fourth version of Visual Studio for .NET?

Why is runat=”server” not the default condition?

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • bodytext
  • del.icio.us
  • Facebook
  • Google
  • Reddit
  • StumbleUpon
  • TwitThis

Using Email Templates With ASP.NET

Somedays working with ASP.NET can be a treat. Especially on those days when you stumble upon some functionality you had no idea existed.

It seems like every website has some need to generate emails for things like order confirmation, password resets, or news updates. System.Net.Mail provides excellent functionality for building email messages and communicating with SMTP servers. But it is up to the developer to build the actual content of the message programmatically, usually by using a StringBuilder to concatenate a bunch of user-specific and common strings.

Turns out there is class and technique that can simplify that code quite a bit. MailDefinition is a class that allows you to build email templates and easily update the dynamic parts.

Check out the following code:

public void GenerateOrderEmailCustomer(Order order)
{
   try
   {
      MailDefinition template = new MailDefinition();
      template.BodyFileName = "~/templates/CustomerOrderConfirmation.html";
      template.From = order.Store.Retailer.ApplicationConfig.EmailOrderFromAddress;

      Dictionary<string, string> data = new Dictionary<string, string>();
      data.Add("<<order.OrderNumber>>", order.OrderNumber.ToString());
      data.Add("<<order.Store.Name>>", order.Store.Name);
      data.Add("<<order.Status>>", order.Status.ToString());
      data.Add("<<order.FirstName>>", order.FirstName);
      data.Add("<<order.LastName>>", order.LastName);
      data.Add("<<order.Address1>>", order.Address1);
      data.Add("<<order.Address2>>", order.Address2);
      data.Add("<<order.City>>", order.City);
      data.Add("<<order.State>>", order.State);
      data.Add("<<order.Zip>>", order.Zip);
      data.Add("<<order.PaymentMethod>>", order.PaymentMethod.ToString());
      data.Add("<<order.Payment.CardHoldersName>>", (order.Payment != null) ? order.Payment.CardHoldersName:"n/a");
      data.Add("<<order.Payment.CardType>>", (order.Payment != null)? order.Payment.CardType:"n/a");
      data.Add("<<order.Payment.CreditCardNumber>>", (order.Payment != null) ? order.Payment.CreditCardNumber.Substring(0, 4) + " **** **** ****" : "n/a");

      string detailTable = "";
      foreach (OrderDetail detail in order.Details)
      {
         detailTable += string.Format("<tr><td>{0}</td><td>{1}</td></tr>", detail.Quantity, detail.Name);
      }

      data.Add("<<order.Details>>", detailTable);
      data.Add("<<url>>", "http://www.wineconnect.com/");

      MailMessage message = template.CreateMailMessage(order.Email, data, new LiteralControl());
      message.IsBodyHtml = true;
      message.Subject = string.Format("Order Confirmation: {0} ({1})", order.Store.Name, order.OrderNumber.ToString());

      SmtpClient client = new SmtpClient(order.Store.Retailer.ApplicationConfig.EmailServer, order.Store.Retailer.ApplicationConfig.EmailPort);

      //Enable SSL
      client.EnableSsl = order.Store.Retailer.ApplicationConfig.EmailEnableSsl;

      client.UseDefaultCredentials = false;
      client.Credentials = new NetworkCredential(order.Store.Retailer.ApplicationConfig.EmailUsername, order.Store.Retailer.ApplicationConfig.EmailPassword);

      client.SendCompleted += new SendCompletedEventHandler(MailDeliveryComplete);
      client.SendAsync(message, message);
   }
   catch (Exception ex)
   {
      _log.Error("Error caught while sending customer order confirmation", ex);
   }
}

Combined with this template:

<html>
<head>
<title>Order Confirmation</title>
</head>
<body>
<table width="400" border="1" cellpadding="4" cellspacing="0" bordercolor="EDF5E3">
<tr bgcolor="#999999" >
<td align="center" style="height: 16px"><span color="#FFFFFF">Order Confirmation (<<order.OrderNumber>>)</span></td>
</tr>
<tr><td>
<<order.FirstName>>,<br><br>
This email confirms your order: <br>
Store: <<order.Store.Name>><br><br>
Order Status: <<order.Status>><br>
<br>Billing Information: <br>
Customer: <<order.FirstName>> <<order.LastName>><br>
Address1: <<order.Address1>><br>
Address2: <<order.Address2>><br>
City: <<order.City>><br>
State: <<order.State>><br>
Zip: <<order.Zip>><br>
<br>Payment Method: <<order.PaymentMethod>><br>
Card Holder: <<order.Payment.CardHoldersName>><br>
Card Type: <<order.Payment.CardType>><br>
Card Number: <<order.Payment.CreditCardNumber>><br>
Order Information:
<table class="messageTxt"><tr><td>Qty.</td><td>Item</td></tr>
<<order.Details>>
</table><br/>
Your order number is <strong><a href='<<url>>/OrderSummary.aspx?OrderNumber=<<order.OrderNumber>>'><<order.OrderNumber>></a></strong>.
Please feel free to contact us with any questions or visit our website if you need directions to our store.<br><br>
<a href="<<url>>"><strong><<url>></strong></a><br><br>
Thank you,<br><br>Wine Store Dudes<br></td></tr>
</table>
</body>
</html>

It generates this email:

CropperCapture[43]

Good Stuff:

Using this technique I was able to get rid of a bunch of string concatenation and string.Format code. The template should be much easier to maintain going forward.

Lame:

The way MailDefinition replaces the dynamic tokens is nice but a bit limiting. It might be fun to try using a Server.Execute method to pick up other ASP.NET goodness like data binding and advanced logic.

The CreateMailMessage function also requires a OwnerControl to be passed in. They could have given us an overloaded version that didn’t require this because I doubt anyone ever uses it.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • bodytext
  • del.icio.us
  • Facebook
  • Google
  • Reddit
  • StumbleUpon
  • TwitThis

The ASP.NET Wiki. Microsoft Doesn’t Get It.

I fired up the quite excellent Visual Studio today to do a little of what I do every day. In this case, as I was waiting for my project to load I noticed a link to “New Updates to the ASP.NET Wiki”. It’s been awhile since I visited the ASP.NET Wiki (likely around its February 2008 release) and this seemed like something I should at least take a look at again.

…and it was almost exactly what I expected. Generic, awful-looking crap — with ads. It couldn’t be any more proto-typically Microsoft if they’d attached a signature 2007 or two-alpha-character suffix. I’m sure someone lobbied for Wiki.NET 2007 NT.

I’m a bit more keen on design aesthetics than most hard-core developers. Just a bit more interested in the user’s perspective and the utility of an application than whether it is using straight ADO.NET, the (dated) Data Access Application Block, nHibernate, or any other ORM to get data to user (and back again). As long as it works, isn’t too messy, and is snappy enough to deal with the load, I’m fine with it.

So, I start digging through and like most of the Microsoft properties, there is some good stuff in here. Much of the content is really solid and functionally, it’s worthy of a passing grade — if I could just see my red pen through the blood pooling in my eyes. I start to feel a bit congested and my blood-pressure starts to rise searching for content. There are navigation elements, and lists of links sprayed all over the page like… have you ever tried that acoustic ceiling spray in a can? If you have, you know what I mean. If you haven’t I beseech you to give it a try (NOTE: heed ALL warnings on the can).

But I digress. Here is a screenshot of the ASP.NET Wiki:

asp.net wiki

Right off the bat, the ads are both offensive and totally out of place. Maybe it’s me, but any time I see a graphical smiley, in the wild or in an ad, I immediately think I entered the wrong URL into the browser. It’s shocking. The disregard for white space is apparent throughout, but not so much as on the asp.net homepage.

If you’re running your browser at less than 1080 pixels wide, you’re going to see the following start to happen. I initially thought it was me and gratuitous use of the Firefox browser, but no, you’ll see the same thing in IE7. God help you if you’re stuck on that piece of garbage, 1024 x 768 development laptop you’ve been assigned at Super GloboMax Worldwide Incorporated (or Target Corporation).

asp.net wiki smashing

Again, the content is decent — if you can work your way through the phlegm.

Straight out of MinneRails, er, I mean Minnebar last weekend, I thought to myself, “Self, I wonder what the Rails Wiki looks like.”

rails wiki

It’s as good as the ASP.NET one is bad. Simple, elegant layout. Easy to navigate. The internal pages are even better.

rails dev

One step further and you see what the actual content looks like.

rails wiki content

There is the information I want. The sparseness is wonderful, isn’t it? I want to cuddle with this ad-free, feature-rich, information-packed, easily-navigable, simple wiki — and I don’t do Rails.

I have three things to offer to Microsoft, the team behind the ASP.NET wiki (Scott Hanselman, Telligent), and really anyone trying to build a community around a product they are selling or supporting. First, just because you are a for-profit entity, doesn’t mean you need to monetize every single page of your content with banner ads or the google equivalent. Communities work better and (maybe this is where Microsoft is missing the boat) feel more natural if as a member you’re not constantly being marketed to. Secondly, use the right tool for the job. I know SharePoint and the .NET-based portals are going to be your first choice based on the user base, but are they the best bet? Not by a long shot for something like this. Thirdly, I see (the very google-esque) “beta” in the wiki title. Please consider some serious changes before this becomes “production code”.

Maybe a tool like ScrewTurn Wiki is a better option. At the very least it would be a refreshing change to this nightmare.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • bodytext
  • del.icio.us
  • Facebook
  • Google
  • Reddit
  • StumbleUpon
  • TwitThis

Minnebar 2008

Jim and I went to Minnebar this morning at Coffman Union on the campus of the University of Minnesota — 398 geeks and us. We hit three sessions and then went to the “State of the State” panel discussion with Jamie Thingelstad (former Dow Jones), Robert Stephens (Geek Squad), Dan Grigsby (Unpossible), Matthew Downquast (Crashplan), Douglas Olson (Microsoft), and Michael Gorman (Split Rock Partners).

They’re all really smart guys who are uniquely qualified to speak on the state of software in Minnesota, even if they did contradict themselves on one key point. They were all in agreement that Minnesota is a great place to build a development team — that it has a great community of developers and that our Midwestern work-ethic and loyalty are things that contribute to that, that we tend to be more thoughtful and risk-adverse. Only moments later, talk shifted to the need for developers as entrepreneurs to take the chances to start the next start-ups. Apparently our weakness needs to be our strength. All that considered, I could have listened to these guys for two or three hours.

It’s been many years since I first sat in a room listening to Robert Stephens talk about geek squad — back when they had the place in the Warehouse district. If you ever get a chance to hear him speak, take it. Actually, if you ever get a chance to hang out with any of these guys and listen to them, drop what you’re doing and make it happen.

One more point that hit home with me is that the University of Minnesota is a great school, but that it’s our duty collectively to do what we can to improve the state of the Computer Science and Business programs through mentoring, offering internships and with our wallets.

It’s amazing how prevalent the Rails stuff has gotten. Every session we attended had a Rails tie-in it seemed. Open-source is the buzzword with the development community to be sure. Everyone is looking to maximize the dollars spent on tools with the excellent free offerings.

All in all, I wish I had been able to stay for the entire event, but holding the whole Mother’s Day weekend thing (and my mom’s birthday) threw a monkey wrench into the works.

Good stuff. Thanks to Ben and all who helped organize this thing.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • bodytext
  • del.icio.us
  • Facebook
  • Google
  • Reddit
  • StumbleUpon
  • TwitThis

Microsoft Citizen Service Platform

I spent the morning at the local Microsoft office in Bloomington to hear about and see some demos on the Citizen Service Platform — based on SharePoint, Microsoft Dynamics CRM, and Microsoft Live. It’s essentially a bundling of existing tools, with a number of templates that act as a start in developing further tools and templates based on the platform.

I guess this is a logo?

Microsoft isn’t exactly changing their marketing approach. You’re not going to see Microsoft itself horning in on businesses like Avenet’s GovOffice — yet, but you will see any number of Microsoft Partners looking for ways begin integrating the public-facing and city-management sides of the equation in some pretty sexy ways. This is the kind of thing that has the chance of bringing municipal websites to the level of technology of today’s (and not 1998’s) hottest commerical web ventures.

I filled four pages in my notebook sketching out ideas that I — thanks to nearly six years servicing this market — think would make loads of sense for me as a citizen of the World, the United States, Minnesota, Eagan, and School District 196.

Let’s see if I can decipher it and separate it from the alphabet soup that appears to have been spilled throughout the same pages..

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • bodytext
  • del.icio.us
  • Facebook
  • Google
  • Reddit
  • StumbleUpon
  • TwitThis

Instant (and Effortless) Googlization of Your Latest Blog Post

I’ve exclaimed my great satisfaction to friends recently as I’ve written blog posts on just how quickly they seem to appear in the Google indexes. And by “quick”, I mean almost instantly. Click the “Publish” button in WordPress and BLAMMMMMMO! Instant street cred. I wondered to myself, after it happened the first few times, “Self? How did that happen?”

It didn’t take very long to track down the “Update Services” section in the WordPress Admin (available at the bottom of the “Settings > Writing” page). Looks a bit like this:

WordPress \

Essentially, when a user hits “Publish”, an XML-RPC ping is sent to the services listed in the textarea above. There are dozens of these services with a lot of overlap, but just adding a few to this can help you spread the glory of your most recent post quickly and effortlessly.

What does this all mean to you? Traffic (and attention), like right now.

We’d love to help you come up with a blogging setup and blogging strategy for your company or organization. It’s an incredibly powerful medium. Check out our contact information at freemind.net for more information on what we can offer you.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • bodytext
  • del.icio.us
  • Facebook
  • Google
  • Reddit
  • StumbleUpon
  • TwitThis

Minneapolis ALT.NET User Group Starting

Freemind Solutions is excited to announce the start of a Minneapolis ALT.NET User Group. It’s open to anyone in the industry, whether you’re in Minneapolis or not — even if you beckon from Woodbury or Shakopee. The informational Wiki is located at http://www.mplsalt.net/.

There is a Yahoo! Tech Group started here as well.

What exactly is ALT.NET?

So you’re a .NET developer or architect using the amazing tools that Microsoft has given us, but there are certain areas that you tell yourself, “there has to be a better way.” Maybe you’ve taken to using an ORM such as nHibernate or Castle. Perhaps your unit-testing process relies heavily on nUnit or you tore out the last bit of your hair over remotely using Visual Source Safe and finally signed up for that hosted Subversion repository. Maybe you’re just a huge fan of all of the open-source options available to you now as a Microsoft developer.

Whatever your reasons, you’re using alternatives to the standard Microsoft toolkit. You’re alternative and more interested in getting things done than prescribing to what “the man” pushes on you.

If you live within driving distance (and with gas prices being what they are, that range is surely shrinking) of the Twin Cities, check us out. We should have more information in the next week or two about a date and time for the first meeting.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • bodytext
  • del.icio.us
  • Facebook
  • Google
  • Reddit
  • StumbleUpon
  • TwitThis