tags:

views:

39

answers:

2

I'm trying to maintain a collection of objects based on their URI:

public class ConceptCollection : KeyedCollection<Uri, Concept> {
    protected override Uri GetKeyForItem(Concept item) {
        return item.Uri;
    } 
}

However, the URI regularly only differs based on the Fragment of the Uri. So, the following causes an error:

ConceptCollection wines = new ConceptCollection();
Concept red = new Concept("http://www.w3.org/2002/07/owl#RedWine");
Concept white = new Concept("http://www.w3.org/2002/07/owl#WhiteWine");
wines.Add(red);
wines.Add(white); // Error: An item with the same key has already been added.

Per http://msdn.microsoft.com/en-us/library/f83xtf15.aspx:

The Equals method compares the two instances without regard to user information ( UserInfo) and fragment ( Fragment) parts that they might contain. For example, given the URIs http://www.contoso.com/index.htm#search and http://user%[email protected]/index.htm, the Equals method would return true.

I'm resigned to having to hack around this. But why does it behave this way? I can see the logic for user-info, but not for fragment.

A: 

I guess because 2 URIs that are identical apart from the fragment still refer to the same resource, just a different location within the resource.

So if you're asking the question 'are these the same resource?' then you could argue that it's correct to ignore the fragment.

Luke Sampson
Here's a link to W3C description of fragments in URLs: http://www.w3.org/TR/WD-html40-970708/htmlweb.html#h-4.1.1
Luke Sampson
I can see the basic logic. But once you specify a fragment, aren't you specifying only a portion of the resource (i.e. the fragment). E.g. http://me/body#leftHand versus http://me/body#rightFoot.
Adrian
@Adrian: The entire resource must still be retrieved by the user agent and then the fragment can be processed to point the UA to the appropriate section/fragment of the full resource. There is no way to retrieve only part of the resource.
Scott Dorman
+3  A: 

From RFC 2396:

4.1. Fragment Identifier

When a URI reference is used to perform a retrieval action on the identified resource, the optional fragment identifier, separated from the URI by a crosshatch ("#") character, consists of additional reference information to be interpreted by the user agent after the retrieval action has been successfully completed. As such, it is not part of a URI, but is often used in conjunction with a URI.

The emphasis added is mine and is the reason the fragment is not considered in the Uri.Equals implementation.

In your example, the URI for the resource you are retrieving is: http://www.w3.org/2002/07/owl

The fragments are processed by the user agent and have no meaning to or influence on the actual retrieval of the resource.

Scott Dorman
Nicely spotted. I guess my issue now is with the W3C using fragments as unique identifiers when referencing ontology elements. (The samples I used were consistent with their OWL documentation). Cheers.
Adrian
@Adrian: Uri isn't a sealed class. You could accomplish this by deriving your own class from Uri that modifies the Equals behavior to also look at the fragment.
Scott Dorman