<CharlieDigital /> Programming, Politics, and uhh…pineapples

28Mar/13Off

Why Your CAML Query Might Be Returning No Results

Posted by Charles Chen

A curious thing.

We were working on a custom view for one of our lists and found that we were not able to retrieve a list item using a CAML query that should have worked.

After spending quite a bit of time studying the query itself, I decided to look at the actual SQL that was being generated.

This list has a large number of columns and SharePoint was wrapping the rows according to the boundary conditions.  For example, when you have 16 integer or user fields, the 17th field of this type will force the row to wrap into a second row.

When this occurs, in the AllUserData table, you will see multiple rows for the same item, each with a different tp_RowOrdinal. Looking in the table, it was clear that the value was in the table, but it was not on the first row (tp_RowOrdinal="0").

The problem with this is that for some odd reason, the SQL query that gets generated when you query on the field that has wrapped onto the second row inexplicably only queries the first row.

In the generated SQL, I found the following:

...AND (UserData.tp_RowOrdinal=0) AND ((UserData.[int10] = N''34'') ...

In this case, "34" represents the ID of a user and "int10" represents the column that the data is in.  But the key is that even though this data occurred in the row with ordinal 2, the SQL will filter only on the row with ordinal 0.

This is kind of inexplicably bad but not all is lost.

The dirty workaround is that you can do one of two things:

  1. If you are adding the columns manually or in a single content type, you need to ensure that the field(s) that you want to query against appear earlier in your content type definition or they get added earlier.
  2. If you are adding the columns via content types in a Schema.xml file, you need to ensure (1) above and that you add that content type to the list earlier in the XML.

There is an MSDN discussion on this, but Microsoft seems to claim that this is not a "bug" (it most certainly is).

Filed under: SharePoint No Comments
10Oct/12Off

SharePoint DirectoryNotFoundException (0×80070003)

Posted by Charles Chen

I've been dealing with an interesting SharePoint error for the better part of a day-and-a-half now and I thought it was worth sharing.

The error surfaced was a DirectoryNotFoundException (0x80070003) when attempting to call BreakRoleInheritance in an asynchronous event receiver.

The purpose of the receiver was to read a set of rules which specified how to configure permissions for objects based on metadata and content type. However, this would fail with the aforementioned error, but only for folders.

Of course, this was a weird error because I could certainly see the folder in the list.

It turns out that the root cause is how we were setting the titles/names on our folders.  One issue with folders is that depending on how you add the list item, you may have to go back and rename it.  Otherwise, it gets a title based on its ID.

Our original logic looked like this (note the use of the Name property) and it was raised after the item was created in the list:

if (entity.ContentTypeId.StartsWith("0x0120")) // Only for folders
{
    item = list.GetItemById(item.ID);
    item["Name"] = entity.Title;
    item.SystemUpdate(false);
}

(Assume that entity is simply a container that describes the list item to create.)

The exception occurs in the case where the rename executes before the asynchronous event receiver finishes executing, thus the directory -- as originally named -- no longer exists since it's been renamed by the code above.  This caused random errors on our systems based on the order of execution and of course, when the debugger is attached, it works perfectly fine (I think because it changes the threading model).

We've changed our code now to something like this instead:

private SPListItem AddItem<T>(T entity, SPList list, string parentFileRef) where T : CtmoModelBase, new()
{
    if (string.IsNullOrEmpty(parentFileRef)) //Add to sub-folders
    {
        parentFileRef = list.RootFolder.Url;
    }

    _log.DebugFormat("Saving object to container URL: {0}", parentFileRef);

    try
    {
        Web.AllowUnsafeUpdates = true;

        if (entity.ContentTypeId.StartsWith("0x0120"))
        {
            // Add a folder (same in all cases)
            return list.AddItem(parentFileRef, SPFileSystemObjectType.Folder, entity.Title);
        }

        if (list.BaseType == SPBaseType.DocumentLibrary)
        {
            // Add a file to a document library.
            SPFolder parentFolder = Web.GetFolder(parentFileRef);

            return parentFolder.Files.Add(entity.Title, entity.BinaryContents, true).Item;
        }
        else
        {
            // Add a list item to a custom list.
            return list.AddItem(parentFileRef, SPFileSystemObjectType.File, entity.Title);
        }
    }
    finally
    {
        Web.AllowUnsafeUpdates = false;
    }
}

Which has solved the issue as the name of folder and items created from folder based content types no longer need to be updated to set the display name.

Filed under: SharePoint No Comments
16Aug/12Off

SharePoint ListData.svc 500 Error

Posted by Charles Chen

If you're fighting with the SharePoint ListData.svc with an odd error:

An error occurred while processing this request.

And you are using an OData operator like endswith, you may encounter this error and be puzzled with why it works for some fields but not others.

Tried various theories -- indexed column?  use the column in a view?  maybe error with the column? -- with no love until Rob thought that it might have to do with empty values.

Turns out that the underlying implementation of ListData.svc doesn't quite like it if you have un-set or "null" values in your text fields.  So a query like this:

http://collab.dev.com/_vti_bin/ListData.svc/Test?$filter=endswith(PrimaryFaxNumber, '6481099') eq true

Will fail if there is an item in the list with an empty value for PrimaryFaxNumber.

However, using a nullity check will fix the issue:

http://collab.dev.com/_vti_bin/ListData.svc/Test?$filter=PrimaryFaxNumber ne null and endswith(PrimaryFaxNumber, '6481099') eq true
Filed under: .Net, SharePoint No Comments
14Jun/12Off

Working With Folder Specific Views in SharePoint Lists

Posted by Charles Chen

One neat feature in SharePoint that I recently discovered is the ability to specify views specific to folder based content types in a list.

What's great about this is that if you're building a hierarchical store in a list with folder based content types, then you can have each level of the hierarchy display different views.

As an example, consider a school district.

They may map their classes like this:

  • School A (Folder based CT)
    • Grade A1 (Folder Based CT)
      • Class A1.1 (Folder Based CT)
        • Student A1.1.1 (Item Based CT)
        • Student A1.1.2
      • Class A1.2
    • Grade A2
  • School B
    • Grade B1
    • Grade B2

Now for each of the folder based content types, you can specify a view specific to that content type by using the DefaultViewForContentType="TRUE" and ContentTypeID attributes of View.  For example, on the Grade level view, when a user selects a Grade, I would want to show a column called "Teacher" because in this view, I'm showing Class items.  However, at the School level, "Teacher" doesn't make sense as a column.

Now none of this is all very difficult to figure out, however there are a few notes:

  1. To get this to work, you have to specify these values for EVERY view.  If you don't, you will see that at each level of the hierarchy, you will have the view available, but the navigation will not automatically select that content type specific view.
  2. For the default view, you need to add it as 0x012001.

This is a great tip as it creates for a much better end-user experience by allowing them to have contextual views based on the current content type.

Filed under: SharePoint No Comments
13Jun/12Off

Interviewing for SharePoint

Posted by Charles Chen

Yet another post on interviewing :)

As both an interviewer (mostly) and an interviewee on topics of SharePoint, I've been working on refining my questions and technique here to get right to the core of understanding a candidate's suitability.

As a general rule, I never start with "factoid" type questions and almost never bring them into an interview in the first place.  I don't believe in quizzing on facts unless there is a very good reason since nowadays, unknown facts can be googled instantly anyways.  Oddly enough, I only end up on factoids when I'm interviewing a very strong candidate.  I generally run interviews with a "choose your own adventure" type of style -- no two candidates ever get the same exact questions.  It works for me because I like to talk about technology and design in general.

That said, I've pretty much boiled it down to a very small set of questions that I start with to determine a candidate's level of expertise and suitability for a given role.


What do you think are some of the more interesting/significant/useful features in SharePoint 2010 compared to SharePoint 2007?

This is an open ended question and what it measures is a candidate's suitability for an architect or lead type role.  The function of an architect or lead is to understand the platform and tool as a whole so thus they need to know what they can do with the tool and understand how to compose the components and capabilities into a set of solution patterns.

With this one question, you can pretty much weed out anyone who is not suitable for an architect or a lead.  A good answer will run down a list of the core feature changes in 2010 compared to 2007 and a strong candidate will be able to identify 2-3 which she thinks are significant in her view.  

The exact ones don't matter as it's a matter of opinion, but a strong candidate will be able to talk about it with detail.  I will note that the ones that a candidate picks will help expose their strengths and leanings (enterprise content management, custom development, configuration, etc).

This question alone can carry you for 20-30 minutes of discussion.

Consider a scenario where you are developing a product that integrates with SharePoint and has a number of ASPX pages.  You would like to implement a license check on every page to ensure compliance and show an error message if the license is invalid or not found.  Give a high level design of how you would implement this.

Again, there are multiple ways to implement this but some ways are clearly better than others.  What I'm looking for here is for the candidate to expose how she thinks about SharePoint as a platform.The first sub-question is where would she propose the license be stored?  It can be stored in SharePoint itself, in the web.config, in the hive, as a persisted object, etc. -- but it is up to the candidate to justify and explain their choice.  Whatever they choose, I point out a weakness and see how they respond :)  Strong candidates can defend their position or can see the weakness and will propose a workaround.  Weak candidates get thrown off pretty easily.

The second sub-question is how the candidate would get the functionality on every page.  The best and most straightforward answer is to create a base page which implements the license check and all pages inherit from the base page and automatically get the license check capability.  There are other ways (perhaps an HttpModule?), but the point here is to see if they naturally think of inheritance to coalesce common functionality.  It's really an inheritance question put into the context of a realistic scenario -- if you understand the goal, then you can create variations of this question that suit your use cases.

Consider a scenario where you develop a component and it requires modifications to the web.config file to work (i.e. custom HttpModule, custom HttpHandler, third party library).  Can you propose a way to manage this at deployment time?

Again, a question with a lot of possible answers, but really only two optimal ones (SharePoint itself offers at least two ways of doing this and automatically propagating those changes across all servers in the farm).  The key here is that most answers will be "I'd update it manually" but this is clearly a sub-optimal solution as a farm may have multiple servers in it and each will have to be updated.  But I like this question because it's a "thinking" question, even if they don't know the answer from the framework perspective, you can tell if they are thinking about the question because some will realize that this is not manageable with a large farm and prone to errors (say 8 servers).


Of course, there are other more specific technical questions that I ask that are feature and role specific, but these three are really my "go to" questions.  What do you think?  Any other questions that you've found to be useful in interviewing for SharePoint candidates?

8Feb/12Off

Folders and Nested Folders in ListInstances

Posted by Charles Chen

This took me about 3 hours to figure out so I figure it was worth sharing.

First, I assumed that it was possible given that the .stp file export of a custom list with folders and nested folders seem to work fine.  Online, the feedback seems to be a bit different and my early results seemed to confirm it.  However, I persisted and after several (and I mean several) tries, I finally got it working.

So I share with you the magic sauce for those times when you want to seed your deployment with hierarchical data.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ListInstance Title="Seed Data"
      OnQuickLaunch="TRUE"
      RootWebOnly="TRUE"
      TemplateType="10000"
      Url="Lists/SeedData"
      Description="Seed data">
      <Data>
          <Rows>
              <Row>
                  <Field Name="ID">1</Field>
                  <Field Name="ContentType">Country</Field>
                  <Field Name="Title">USA</Field>
                  <Field Name="FSObjType">1</Field>
              </Row>
              <Row>
                  <Field Name="ID">2</Field>
                  <Field Name="ContentType">State</Field>
                  <Field Name="Title">New Jersey</Field>
                  <Field Name='FileDirRef'>USA</Field>
                  <Field Name="FSObjType">1</Field>
              </Row>
              <Row>
                  <Field Name="ID">3</Field>
                  <Field Name="ContentType">County</Field>
                  <Field Name="Title">Mercer</Field>
                  <Field Name="FileDirRef">USA/New Jersey</Field>
                  <Field Name="FSObjType">0</Field>
              </Row>
          </Rows>
      </Data>
  </ListInstance>
</Elements>

Yes, it was a pretty painful experience to get this figured out, but it was definitely worth it.

Filed under: SharePoint 2 Comments
16Dec/11Off

Force File Name in SharePoint 2010 Search Results

Posted by Charles Chen

There are a few resources on this for 2007, but I thought I'd add a small update for 2010.

First, start by following the instructions in the links above for the IsDocument property.  You can get to it from the search service administration and it's under Metadata Properties:

Find the IsDocument property in here

Now go to your site and create a new web part page (header, left nav, right body) and call it CustomSearchResults.aspx (or whatever you'd like).  On the right hand side, add a " web part and on the left hand side, add a Refinement Panel web part.

Search web parts available - add Search Core Results and Refinement Panel

Now you need to edit the results web part.

  1. Under the Core Results settings panel, expand the Display Properties sub-panel.
  2. Uncheck Use Location Visualization to enable the Fetched Properties and XSL Editor options.
  3. Modify the Fetched Properties XML string to include <Column Name="Filename"/> (strongly recommend copying the string out and editing it in a text editor).
  4. Click the XSL Editor button to modify the XSL.  Again, I strongly recommend copying the XSL out to a text editor.
  5. Around line 206-207, you should see the following line:
    <xsl:template match="Result">
        <xsl:variable name="id" select="id"/>
  6. Modify it to look like so:
    <xsl:template match="Result">
        <xsl:variable name="id" select="id"/>
        <xsl:variable name="filename" select="filename"/>
        <xsl:variable name="isdocument" select="isdocument"/>
  7. Next, around (new) line 324, you should see the following XSL:
    <xsl:otherwise>
        <a id="{concat($currentId,'_Title')}">
            <xsl:attribute name="href">
                <xsl:value-of  select="$url"/>
            </xsl:attribute>
            <xsl:attribute name="title">
                <xsl:value-of select="title"/>
            </xsl:attribute>
            <xsl:choose>
                <xsl:when test="hithighlightedproperties/HHTitle[. != '']">
                    <xsl:call-template name="HitHighlighting">
                        <xsl:with-param name="hh" select="hithighlightedproperties/HHTitle" />
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="title"/>
                </xsl:otherwise>
            </xsl:choose>
        </a>
    </xsl:otherwise>
  8. Update this to the following:
    <xsl:otherwise>
        <a id="{concat($currentId,'_Title')}">
            <xsl:attribute name="href">
                <xsl:value-of  select="$url"/>
            </xsl:attribute>
            <xsl:attribute name="title">
                <xsl:value-of select="title"/>
            </xsl:attribute>
    
            <xsl:if test="$isdocument">
                <xsl:value-of select="filename"/>
            </xsl:if>
            <xsl:if test="not($isdocument)">
                <xsl:choose>
                    <xsl:when test="hithighlightedproperties/HHTitle[. != '']">
                        <xsl:call-template name="HitHighlighting">
                            <xsl:with-param name="hh" select="hithighlightedproperties/HHTitle" />
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="title"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:if>
        </a>
    </xsl:otherwise>

Now hook up your custom search results page by clicking on Site Settings and then Search Settings. In the Site Collection Search Results Page text box, enter the full relative path to your page (including sub-site paths and such).  For example: /sites/site_xyz/pages/mycustomsearchresults.aspx.

That should do it.  Unfortunately, I haven't figured out how to turn on hit highlighting for the file name yet.

Filed under: SharePoint No Comments
28Sep/11Off

SharePoint 2010 Service Applications Thoughts

Posted by Charles Chen

I can't say that I can add much more to the tutorials and articles already out there on the Net on this topic, but I'd like to point to the definitive example of how to implement one: http://msdn.microsoft.com/en-us/library/gg193964.aspx

David Taylor's blog also has a good 10 part walkthrough with a bit more explanation; however, I would caution that the example he provides is broken as heck and was part of the problem that it took me a good part of 3-4 days to get something so simple to work right.

One bit of knowledge that I'd like to impart is that you will -- more than likely, 99.99% guaranteed -- run into errors with WCF.  In these cases, the errors will:

  • Not show up in any level of detail in the SharePoint logs
  • Not show up at all in the system event logs
  • Not show up in the IIS logs with any level of detail

You'll want to use SvcConfigEditor to enable tracing and of course, SvcTraceViewer to view your logs.  Part of my problem was that I had an error in the configuration file for the service and part of the problem was that I had an error in the VirtualPath of the service in my service application.  I was only able to track these two down through the usage of the aforementioned WCF utilities so keep them handy!

Filed under: Dev, SharePoint, WCF No Comments
13Sep/11Off

Lesson Learned on SharePoint Service Applications

Posted by Charles Chen

If you're setting out on writing your own SharePoint service applications, there is an important lesson that you should keep in mind (instead of learning it the hard way): ensure that all of your proxy, application proxy, service, service application, and service instance classes have public parameterless (default) constructors.

Otherwise, you'll have a heck of a time starting, instantiating, and uninstalling services with lots of MissingMethodExceptions and "{class} cannot be deserialized because it does not have a public default constructor" error messages.

Oddly enough, one thing I've learned from this is that the STSADM commands are often more "powerful" than the equivalent Powershell commands.  For example, Remove-SPSolution, even with the -force parameter, still failed with the aforementioned exceptions.  On the other hand, stsadm -o deletesolution {name} -override seemed to work fine.  Puzzling, for the moment, but it got the job done.  Similarly, stopping a service application that's AWOL (stuck on the processing screen) can be accomplished with stsadm -o provisionservice. Deleting it can be done using stsadm -o deleteconfigurationobject (though this one does seem to have side effects...).

Seems that Powershell is still a second class citizen when it comes to basic SharePoint command-line management.

But in any case, if you set out building your own service applications (<rant>and damn it Microsoft, can't you put some better examples out there?!  Even the few that are out there are convoluted, missing key details, hard to follow...</rant>), be sure to include public, default, parameterless constructors.

Filed under: .Net, Rants, SharePoint No Comments
23Aug/11Off

Damn It, Microsoft (SharePoint)

Posted by Charles Chen

Came across an interesting quirk today with regards to AddFieldAsXml in the SharePoint API.

It turns out that SharePoint doesn't really give a damn what you want to call your field when it adds it to the list; it's going to damn well do whatever it damn well pleases!

You see, in the MSDN documentation, it implies that you can specify the display name and the internal name (just look at that sample code).

However this isn't the case and, as Bill Simser points out, this has been an issue going back to 2005.

Thankfully, as commenter Morten Bundgaard Pedersen points out, you can use the SPAddFieldOptions.AddFieldInternalNameHint option to force SharePoint to use the name value that you specify in the XML.

Seems kind of silly to me given that this is the most likely use case and should be enabled by default given that the intent -- in specifying the Name and StaticName fields would be to, you know, use them when creating the field.

Damn it, Microsoft.