SharePoint, why is listdata service using strange names?

The wonders and pains of Microsoft.SharePoint.Linq.Util.GetFriendlyName

I'm doing some more work with SharePoint as a Single Page Application (spaspa.codeplex.com) and realized that when you are using the REST interface via _vti_bin/listdata.svc, the names of the list it generates are extremely strange.  That is, it doesn't map nicely to anything from the client object model.

Take for example, the out of the box Shared Documents library in a team site.

The URL is: /Shared%20Documents/

The display name is: Shared Documents

The list GUID is: {DEB93E69-7EDE-4AA0-974D-C05FCCCCE619}

But in ListData.svc,

The REST URL is: /_vti_bin/listdata.svc/SharedDocuments/

If you try to use any of the following, you'd get an error:

  • /_vti_bin/listdata.svc/Shared%20Documents/
  • /_vti_bin/listdata.svc/shareddocuments/
  • /_vti_bin/listdata.svc/{DEB93E69-7EDE-4AA0-974D-C05FCCCCE619}/

 

If you are coding to specific lists, this is probably not a big issue, since you'd target the list you want directly.  But for a project like SPASPA, where I am making no assumptions about what the names of the list actually looks like - this is very strange, and very difficult to work around.

Furthermore, if you are trying to mix and match REST service API with Client Object Model - you can't map them.  They have different names.  The client object model does not return SharedDocuments anywhere.

At a glance, you think - oh it's no big deal, just take the URL and strip out the spaces.

Ah ha, that's where you'd fail terribly.

It's almost like when Microsoft implemented the LINQ interface, they decided to make up their own names - and there's some sort of pattern:

  • If you have a lowercase list URL at: /doc/
  • The listdata.svc URL will be: /_vti_bin/listdata.svc/Doc/

Yep, magically capitalized.

  • And if you go crazy and create a list URL at: /my%20test%20lisT/
  • Then rename the title to: my test lisTT
  • Guess what's the listdata.svc end point?  /_vti_bin/listdata.svc/MyTestLisTT/

So, not just magically capitalized, camel-cased too, and it seem to be generated from the Title, disregarding the URL.  Crazy.

And you say oh that's easy, just split by spaces and turn it into CamelCase.

  • Enter foreign characters: My Test ïist  (that's a lowercase i with tréma: ALT+139)
  • Listdata.svc says: /_vti_bin/listdata.svc/MyTestÏist/  (capitalized: ALT+0207)

 

At some point, you decided that the only way forward is to read the listdata.svc code.

Here's the gem:

Microsoft.SharePoint.Linq.Util.GetFriendlyName

 

// Microsoft.SharePoint.Linq.Util
internal static string GetFriendlyName(string name)
{
    string[] array = Regex.Split(name, "[^\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}\\p{Cf}]", RegexOptions.Compiled);
    for (int i = 0; i < array.Length; i++)
    {
        if (!string.IsNullOrEmpty(array[i]) && char.IsLower(array[i], 0))
        {
            array[i] = char.ToUpper(array[i][0], CultureInfo.InvariantCulture) + ((array[i].Length > 0) ? array[i].Substring(1) : string.Empty);
        }
    }
    name = string.Join(string.Empty, array);
    if (string.IsNullOrEmpty(name))
    {
        throw new InvalidOperationException(Resources.GetString("CannotConvertNameToValidIdentifier", new object[]
        {
            name
        }));
    }
    if (Regex.IsMatch(name[0].ToString(), "[^\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}]", RegexOptions.Compiled))
    {
        name = "_" + name;
    }
    if (name.Length > 128)
    {
        name = name.Substring(0, 128);
    }
    return name;
}

 

Why you should always go to the source

 

There are some surprising bits in here, for example:

  • If your Title starts with a number, the function prepends an underscore.
    • Title: 1My Test ïist
    • REST: /_vti_bin/listdata.svc/_1MyTestÏist/
  • And if it exceeds 128 characters it is truncated.  I think this one is very unlikely, but may be people do go crazy with their list title.

 

Food for thought

A consequence of this kind of renaming, is that now there's a new problem.

Take two lists:

  • List 1 title: shared documents
  • List 2 title: SharedDocuments

The listdata service gives you:

  • /_vti_bin/listdata.svc/SharedDocuments/
  • /_vti_bin/listdata.svc/SharedDocuments0/

 

Which is what list?  Who knows!

SharePoint Saturday Brisbane 02-June-2012

In little more than 3 more days, we'll be meeting up again in SharePoint Saturday Brisbane! 

I'll be presenting again on the Developer track on how to build custom webservices within SharePoint, and consuming them using JavaScript AJAX. 

On the side, I've been having a lot of fun with KnockoutJS, Client Object Model, REST and even building a Single Page Application for SharePoint on codeplex. 

There's a bunch of InfoPath people and solutions that I'd love to meet and see again.

Overall, I'm looking forward to meeting all the SharePoint people up in Brisvegas and geeking out for a whole day!

There are some talks of having a dedicated time where we can answer lots of questions from the attendees - so if you have any curly problems within your SharePoint, bring your question along and we'll try to help out.

One final reminder:

02 June 2012.  Register http://sharepointsaturday.org/brisbane/default.aspx

SharePoint in a single page, now with List Item edit

 

Here's the latest screenshot from this project on http://spaspa.codeplex.com

 

 

I've put in buttons that allows you to edit a list item, and that drops the item into edit mode.

Here I'm modifying the Title field.  When you hit Save, it will commit the changes back to SharePoint.

Twitter Bootstrap UI turns out to be really good at guessing screen sizes and adapt.  Here's the page in landscape mode.

image

VS.NET 2008, VSeWSS 1.3 and SafeControl

Oh VSeWSS how I've NOT missed you. 

I was compiling an old solution package for SharePoint 2007, this solution has 6 web parts but the WSP package's manifest only has SafeControl lines for 4 of them.  Somehow, it is discriminating against my newest 2 additions to the family.

In VS.NET 2010, the settings for whether a web part feature should be included in SafeControl is off the WSP Package view.  It automatically adds the current DLL, as well as giving us an option to add more additional assemblies (via the special package solution designer).

image

 

In VS.NET 2008 and SharePoint 2007, the way it determines whether or not to include a Web Part when it generates the manifest file seems...  almost, bizarre and magical.

 

This is how it works

  1. During packaging, VSeWSS reads the DLL to determine if there are web parts within it that needs a SafeControl line.
  2. When it finds them, it modifies a temporary file that it uses during packaging, under project\bin\Debug\solution\manifest.xml
  3. The packaging process than packs up everything under \solution\ into a WSP file, and the manifest file is stored within the WSP file.
  4. What's confusing, is that VSeWSS is not reading the right DLL that's compiled from this project, instead, if you have an older copy of the DLL in the GAC, it will actually read the GAC version over your newly built DLL.

    The end result, is that you think you are crazy and you don't understand why it's arbitrarily deciding to add 4 SafeControl lines, but not all 6.

 

Fix

The fix is pretty simple, if you manually deploy the DLL to the GAC first, then repackage again, it'll pick up the additional web parts within the DLL and add them to your SafeControl list.

 

Why have I never seen this before

If you are deploying to the local machine for testing, you actually may not even see this error - since when you deploy the currently built solution to the local machine it also puts the new DLL into the GAC. 

SharePoint Single Page Application day 4

Did a bit of clean up and finally I've got what I can call the first awesome screen shot.

This is a Single Page Application deployed to SharePoint, and talks to SharePoint via the Client Object Model as well as the REST interface.

The page does not Postback.  It always talk to SharePoint via AJAX.

 

So far:

  • Package 1 ASPX page in a solution package
  • Reference jQuery, Knockout
  • Layout using Twitter's Bootstrap
  • Grabs lists via Client Object Model
  • Grabs list items via REST interface
  • The darn thing is beautiful

 

To come next:

  • CRUD for list items
  • Document download
    • Document upload?
  • List paging
  • Use different icons for lists and document libraries on left navigation
  • A favicon
  • An actual Title for the page
  • Site navigation (this will do post back - since we'll be navigating between say http://server/ to http://server/publishing/ ).
  • Quick search / filter
  • An interesting picture thumb-nail viewer

 

Check it out on http://spaspa.codeplex.com/ and let me know what you think!