views:

1346

answers:

5

I'm doing a custom 404 page for a large website that's undergoing a redesign. There are about 40 high-use pages that customers may have bookmarked, and our new site structure will break these bookmarks.

On my custom 404 page, I want to alert them to the new URL if they attempt to navigate to one of these high-use pages via its old URL. So I have a couple of dynamic controls on the 404 page, one for a "did-you-want-this?" type of dialog, and another for a "if-so-go-here (and update your bookmark)" type of dialog. That's the easy part.

To suggest a new URL, I'm looking at the requested URL. If it has key words in it, I'm going to suggest the new URL based on that, and them I'm firing off the appropriate did-you-want..., and if-so... suggestions on the 404 page as mentioned above.

So I want to store these 40-ish key/value pairs (keyword/new-URL pairs) in a data structure, and I'm not sure what would be best. Dictionary? IDictionary? What's the difference and which is more appropriate?

Or am I totally on the wrong track?

Thanks for your time.

+1  A: 

You could use NameValueCollection.

Craig
+1  A: 

Dictionary would be fine. Wether you store it as the interface type IDictionary or Dictionary itself wouldn't matter much in this case as it's not going to be passed much around, besides on the 404 page itself.

Have you considered doing some URL rewriting to still support the old URLs?

Mark S. Rasmussen
+4  A: 

I would use the Dictionary<T,T> from the System.Collections.Generic namespace.

tvanfosson
+1  A: 

You can consider writing your own class logic and then assign that to a List data structure as following:

public class KeyValuesClass
{
    private string a_key;
    private string a_value;

    public KeyValuesClass(string a_key, string a_value)
    {
           this.a_key = a_key;
           this.a_value = a_value;
    }

    public string Key
    {
        get{ return a_key; }
        set { a_key = value; }
    }

    public string Value
    {
        get{ return a_value; }
        set { a_value = value; }
    }

}

somewhere in the code

List<KeyValuesClass> my_key_value_list = new List<KeyValuesClass>();
my_key_value_list.Add(new KeyValuesClass("key", "value");

But you can consider Dictionary as our fellow programmer mentioned it above :)

milot
Why would you ever make your own KeyValuePair class when the framework provides a perfectly good generic version?
Mark S. Rasmussen
If you need more data in it, for e.g you have four fields, x1, x2, x3 and x4 and you write your own logic for those and you handle differently.
milot
+1  A: 

Maybe this is overkill for your use case, but I'd probably allow for multiple keywords per Uri, and a relative weight score. Then, dynamically score the keywords that match.

class UriSuggester {
   private List<SuggestedUri> Uris { get; set; }

   Uri[] GetSuggestions(Uri originalUri) {
      var suggestionHits = new Dictionary<SuggestedUri, int>();
      foreach (var keyword in KeyWords.Parse(originalUri)) {
         // find suggestions matching that keyword
         foreach (var suggestedUri in Uris.Where(u => u.Keywords.Contains(keyword)) {
           // add a hit for keyword match
           suggestionHits[suggestedUri] += 1;
         }
      }
      // order by weight * hits
      return suggestionHits.Keys
        .OrderBy(s => s.Weight * suggestionHits[s])
        .Select(s => s.Uri)
        .ToArray();
   }
}

class SuggestedUri {
   public Uri Suggested { get; set; }
   public int Weight { get; set; }
   public Keyword[] Keywords;
}

class Keyword {
   public string Value { get; set; }
   public static Keyword[] Parse(Uri uri);
   override Equals;
   override GetHashCode;
}
Mark Brackett