Bug in SharePoint’s Lists Web Service with GetListItems?

I was trying to track down some odd behavior in SharePoint’s Lists Web Service tonight, and I think I’ve found what I can only call a bug. 

Here’s the scenario.  All of these conditions must apply:: 

  • Using the GetListItems operation
  • Querying a list which has a required multi-select column
  • Specifying columns to return in the ViewFields parameter (whether or not the multi-select column above is specified)
  • The multi-select column has more than one value selected in an item (or items)

In this specific case, there are multiple copies of each item returned, one per value which is set in the required multi-select column.

I found two other posts on the Interwebs about this.  In both cases, the writer found the same problem, but was unable to determine the reason or a fix:

Both posts are from 2008, so I’m sure these guys have long since moved on, though I did leave Andy a comment.

It looks like a fix which will work is to not specify the columns in ViewFields.  This will make the GetListItems calls less efficient, of course, but it will make them work correctly.

The other solution, which doesn’t really make any sense, is to include

CAMLQueryOptions: "<QueryOptions><IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns></QueryOptions>",

Setting IncludeMandatoryColumns to FALSE doesn’t do what it it is supposed to do per the SDK, but in this case it serves a useful purpose by eliminating the duplicate items. I worry when I find these seemingly kludgy fixes, but it is *extremely* unlikely that the Web Services are going to change, so I use them anyway.  Even if IncludeMandatoryColumns suddenly started doing what it should, I’d be fine here (and the calls to GetListItems would be even *more* efficient.)

Any other ideas out there?

Here’s an example.  There’s only one item in the States list for Massachusetts.  There’s a column called Staff, which is a Person or Group, allows multiple selections, and is required:

 

In my call to GetListItems, I’m specifying the two columns I would like returned:

CAMLViewFields: "<ViewFields><FieldRef Name='" + opt.relationshipListParentColumn + "' /><FieldRef Name='" + opt.relationshipListChildColumn + "' /></ViewFields>",

GetListItems returns a copy of the item per value for Staff. Note that the Staff column is being returned, even though i am *not* requesting it. (I’m only requesting the Region and State [Title] columns, but the other columns besides Staff come back regardless. Not exactly what I asked for, but it seems to be intentional in all of my experience with GetListItems. They are sort of the “base” columns which you’d need to do anything useful with the items.)

6 Comments

  1. Hi Marc,

    Sorry about the delay responding to your tweet – I’ve been ill, and on holiday.

    That is a weird, kludge of a work around! I can’t see why IncludeMandatoryColumns should do that. Still, if it works … the only thing I’d do is I’d still write my code to check that ID is unique in the results from the web service – that way, if a patch changes this in the future, you’ll still process the items correctly.

    Reply
  2. Hey Marc,

    The bug seems to be exactly that this field is included despite not being on the ViewFields list.

    Apparently, the rationale behind showing copies of the item with various values is that If you look at how LookupMulti and UserMulti fields store data, that’s just semicolon separated IDs like “104;91;98”. In order to get the user friendly value, the web service fetches the LookupField’s value from the referenced list and shows it in a standard way with ID and Value separated with semicolon-sharp sequence (“;#”). That way the response parser doesn’t need any additional logic to split strings. Why duplicating the row and joining values by unique ID was favored over merging with yet another separator is unclear, but it seems to be by design.

    Reply
    • I agree that it may well be by design, but when something like this is undocumented and inconsistent, I tend to think of it as a bug.

      I wish there was a way to push some button to get Microsoft to both acknowledge and document these things, but even after being out for years, the details of the true workings of some of the Web Services is still obscure.

      M.

      Reply
  3. Hi, i was using SPServices0.7.2, here is the code :

    $().SPServices({
    operation: “GetListItems”,
    async: false,
    listName: “{E2A787D9-D9CC-4F3F-A3FC-4EAC004F0A79}”,
    CAMLViewFields: “”,
    completefunc: function (xData, Status) {
    // console.log(xData.responseText);

    var itemCount = $(xData.responseXML).SPFilterNode(“rs:data”).attr(“ItemCount”);

    console.log(itemCount);
    // $(xData.responseXML).find(“[nodeName=z:row]”).each(function(){
    console.log($(this).attr(“ows_Title”));

    //});
    }
    });

    but i am getting “undefined” in console. same works for other list. even i am getting responsetext for this list

    Reply

Have a thought or opinion?