May 2010 - Posts

New Software Running ScottOnWriting.NET
27 May 10 10:50 PM | Scott Mitchell | 6 comment(s)

When I started this blog in July 2003 there weren't many available blog engines build atop ASP.NET. One of the more interesting ones at the time was Scott Watermasysk's .Text blog engine (which eventually became part of Community Server. Over the past nearly seven years ScottOnWriting.NET has continued to be powered by .Text, even though the code base was discontinued circa 2004. There were two primary reasons I stuck with .Text for so long:

  1. I could find no easy way to migrate my existing content from .Text into Community Server. I believe there was such a tool created in the early days of Community Server, but I had no luck with it, as I recall. Eventually, this product disappeared and the only migration tools I could find were from older versions of Community Server to newer ones, but none for .Text.
  2. There were URL changes between .Text and Community Server, so switching over would immediately result in a slew of broken URLs. I am a strong believer in URLs as public interfaces and view broken URLs and believe each broken URL makes the Internet that less useful. Plus it makes the Internet Founding Fathers - Tim Berners-Lee, Vint Cerf, and Al Gore - cry. Smile

Well, this week I decided to take the plunge and move ScottOnWriting.NET and its hundreds of posts over to a new blog engine, namely Community Server (albeit an older version of Community Server - when will I learn?). I wrote some custom SQL scripts to (the best of my ability) move over all blog posts and categories (or tags, as they're called now-a-days). I also spent a good deal of time writing some regular expressions and very big switch statements to properly reroute URLs. For example, if you try to visit an old ScottOnWriting.NET URL, like http://scottonwriting.net/sowBlog/posts/145.aspx, you should be automatically redirected to the new URL, http://scottonwriting.net/sowBlog/archive/0000/00/00/162659.aspx. Likewise, if you visit an old category URL or an old moth/year archive URL you should be redirected to the new URLs. If this is not the case, if you find a broken URL or other problem on this site, please let me know.

Note that I did not mention bringing over the past blog comments. I'm still on the fence as to whether I want to spend the time to do this. There were hundreds of comments left over the years, many of them quite helpful and many that added substantially to the discussion. However, I've already sunk a number of hours into this migration and am hesitant to burn too much more time. Plus I still have a number of aesthetic and cosmetic things to do, like update the site's CSS, add in some of the widgets from the original site that aren't part of the default Community Server setup, and so forth. My goal is to eventually import these past comments, but I wouldn't be at all surprised if this is still on my TODO list come 2011.

In closing, please do let me know if you run into any problems with the new blog engine.

Thanks!

Building a Store Locator ASP.NET Application Using Google Maps API
25 May 10 11:39 AM | Scott Mitchell | 6 comment(s)

The past couple of projects I've been working on have included the use of the Google Maps API and geocoding service in websites for various reasons. I decided to tie together some of the lessons learned, build an ASP.NET store locator demo, and write about it on 4Guys. Last week I published the first article in what I think will be a three-part series: Building a Store Locator ASP.NET Application Using Google Maps (Part 1). Part 1 walks through creating a demo where a user can type in an address and any stores within a (roughly) 15 mile area will be displayed in a grid. The article begins with a look at the database used to power the store locator (namely, a single table that contains one row for every location, with each location storing its store number, address, and, most important, latitude and longitude coordinates) and then turns to using Google's geocoding service to translate a user-entered address into latitude and longitude coordinates. The latitude and longitude coordinates are used to find nearby stores, which are then displayed in a grid.

Part 2 looks at enhancing the search results to include a map with markers indicating the position of each nearby store location. The Google Maps API, along with a bit of client-side script and server-side logic, make this actually pretty straightforward and easy to implement. Here's a screen shot of the improved store locator results.

Part 3, which I plan on publishing next week, looks at how to enhance the map by using information windows to display address information when clicking a marker. Additionally, I'll show how to use custom icons for the markers so that instead of having the same marker for each nearby location the markers will be images numbered 1, 2, 3, and so on, which will correspond to a number assigned to each search result in the grid. The idea here is that by numbering the search results in the grid and the markers on the map visitors will quickly be able to see what marker corresponds to what search result.

This article and demo has been a lot of fun to write and create, and I hope you enjoy reading it, too.

Happy Programming!

Filed under:
Resolve a URL from a Partial View (ASP.NET MVC)
11 May 10 12:05 AM | Scott Mitchell

Working on an ASP.NET MVC application and needed the ability to resolve a URL from a partial view. For example, I have an image I want to display, but I need to resolve the virtual path (say, ~/Content/Images/New.png) into a relative path that the browser can use, such as ../../Content/Images/New.png or /MyAppName/Content/Images/New.png.

A standard view derives from the System.Web.UI.Page class, meaning you have access to the ResolveUrl and ResolveClientUrl methods. Consequently, you can write markup/code like the following:

<img src='=<%=Page.ResolveClientUrl("~/Content/Images/New.png")%>' />

The problem is that the above code does not work as expected in a partial view. What's a little confusing is that while the above code compiles and the page, when visited through a browser, renders, the call to Page.ResolveClientUrl returns precisely what you pass in, ~/Content/Images/New.png, in this instance. The browser doesn't know what to do with ~, it presumes it's part of the URL, so it sends the request to the server for the image with the ~ in the URL, which results in a broken image.

I did a bit of searching online and found this handy tip from Stephen Walther - Using ResolveUrl in an HTML Helper. In a nutshell, Stephen shows how to create an extension method for the HtmlHelper class that uses the UrlHelper class to resolve a URL. Specifically, Stephen shows how to add an Image extension method to HtmlHelper. I incorporated Stephen's code into my codebase and also created a more generic extension method, which I named ResolveUrl.

public static MvcHtmlString ResolveUrl(this HtmlHelper htmlHelper, string url)
{
    var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
    return MvcHtmlString.Create(urlHelper.Content(url));
}

With this method in place you can resolve a URL in a partial view like so:

<img src='<%=Html.ResolveUrl("~/Content/Images/New.png")%>' />

Or you could use Stephen's Html.Image extension method (although my more generic Html.ResolveUrl method could be used in non-image related scenarios where you needed to get a relative URL from a virtual one in a partial view). Thanks for the helpful tip, Stephen!

Happy Programming!

Filed under:
More Posts

Archives

My Books

  • Teach Yourself ASP.NET 4 in 24 Hours
  • Teach Yourself ASP.NET 3.5 in 24 Hours
  • Teach Yourself ASP.NET 2.0 in 24 Hours
  • ASP.NET Data Web Controls Kick Start
  • ASP.NET: Tips, Tutorials, and Code
  • Designing Active Server Pages
  • Teach Yourself Active Server Pages 3.0 in 21 Days

I am a Microsoft MVP for ASP.NET.

I am an ASPInsider.