Friday 13 November 2009

CMYK .jpg images don’t render in IE and Firefox

For the second time in recent memory I was today faced with a "broken" image in IE 8 and Firefox 2.x due to the image being saved using the CMYK colour mode instead of RGB. Interestingly, Chrome was quite happy to display the image as it was; I had to open it in Photoshop, change the mode to RGB, and save it back for the other browsers to respond. Apparently saving for web does the same thing.

Here’s the image in CMYK:

CMYK And here it is again in RGB:

RGB

My Network Places in Windows Server 2008

Where has My Network Places gone in Windows Server 2008? I'm not quite sure but you can add a new network place by right-clicking on Computer in Windows Explorer and selecting Add a Network Location from the context menu. For example, connect to a picture library in a SharePoint content database using this address: http://my_site:30000/Lists/MyPicturesList

Add a Network Location in Windows Server 2008

After stepping through the wizard, the network location will appear alongside your other mapped drives, etc.

 

Wednesday 11 November 2009

After Event Receiver Doesn't Fire

Here we go again... note to self: because "after" events like ItemAdded and ItemUpdated fire asynchronously, testing the receiver wiring by doing something with a side effect (like throwing an exception) won't have any visible result within the context of the site (do check the event log though!).

Throwing within a before event like ItemAdding will bring the operation to a screeching halt.

Tuesday 10 November 2009

Adding the Edit Control Block (ECB) to an additional/different list column

This is how I add the ECB menu to a different column. All changes are made within the context of my list's Schema.xml file.

To start, I already have a custom text field defined within the Fields element:

<Field
Description="$Resources:Field_Caption_Description;"
DisplaceOnUpgrade="TRUE"
DisplayName="$Resources:Field_Caption_DisplayName;"
Group="$Resources:Group_DefaultName;"
ID="{1ac83cea-5b25-4e2f-ae43-5116e005ca97}"
Name="Caption"
Type="Text"
/>

To this I add a new computed field that references the existing field:

<!-- Edit Control Block (ECB) Context Menu -->
<Field
AuthoringInfo="(with menu)"
ClassInfo="Menu"

DisplaceOnUpgrade="TRUE"
DisplayName="$Resources:Field_Caption_DisplayName;"
DisplayNameSrcField="Caption"
ID="{09868F6C-7419-4db3-9C1A-434598ABE010}"
Group="$Resources:Group_DefaultName;"
Name="CaptionContextMenu"
ReadOnly="TRUE"
Type="Computed"
>
<FieldRefs>
<!-- First FieldRef points to parent field -->
<FieldRef ID="{1ac83cea-5b25-4e2f-ae43-5116e005ca97}" Name="Caption" />

<FieldRef ID="{3c6303be-e21f-4366-80d7-d6d0a3b22c7a}" Name="_EditMenuTableStart" />
<FieldRef ID="{2ea78cef-1bf9-4019-960a-02c41636cb47}" Name="_EditMenuTableEnd" />
</FieldRefs>
<DisplayPattern>
<Field Name="_EditMenuTableStart" />
<HTML><![CDATA[<a onfocus="OnLink(this)" href="]]></HTML>
<URL />
<HTML><![CDATA[" ONCLICK="GoToLink(this);return false;" target="_self">]]></HTML>
<!-- Points to parent field -->
<Field Name="Caption" />

<HTML><![CDATA[</a>]]></HTML>
<Field Name="_EditMenuTableEnd" />
</DisplayPattern>
</Field>

Note DisplayNameSrcField points to the original field, as does the <Field> element in the DisplayPattern section.

Finally in my view's ViewFields element, I modify the FieldRef pointing to my original field to point to my ECB column:

<FieldRef Name="CaptionContextMenu" />

A few things to note:

  • When I first tried this with the original field set as type HTML, it didn't work; I ended up changing the field to a text field. I haven't tried other field types.
  • /_layouts/sitemanager.aspx presents the view in a similar but slightly different way to that presented by the list itself (e.g. /Lists/MyList/AllItems.aspx); Site Manager tends to always add the ECB on the second column whereas the latter tends to do a better job doing what you tell it to do. [Update: I use the DocIcon field in position #1 to work around this issue... it shows up as a little document icon with a column name of Type--which I haven't been able to hide. It's clickable in the AllItems.aspx-style view at least so not completely useless and it obviously shoves the ECB to a potentially meaningful field in the second position (you can alternatively use ID but this may not not make sense if you're ordering list items).]

Monday 9 November 2009

ContentTypeRef vs ContentTypeBinding

There seems to be some uncertainty around the use of the ContentTypeRef element in Schema.xml and the ContentTypeBinding element in your elements file. The master—Andrew Connell—indicates both should be used but various discussions (see links below) suggest

you can use the ContentTypeRef to create a list with a content type, or you can use a ContentTypeBinding to add it later.

I personally found this discussion somewhat hard to follow and Andrew's post just says DO IT without any additional explanation; this post documents my own findings around the why.

While I always use ContentTypeRef in my Schema.xml files because my custom lists are backed by a custom content type, I hadn't come across ContentTypeBinding in a list context until recently—or if I had, I assumed it was unnecessary since everything just works without it. My understanding of content types leads me to believe each list has its own internal content type or at the very least, its own set of fields (the latter is certainly evident in the duplication of fields in Schema.xml and the file used to provision custom fields).

All's well, or so I thought until I had to programmatically enumerate a list item's fields: I noticed my custom fields were listed twice. Creating a new list from the Custom List template and assigning my custom content type did not result in this duplication so I knew something was up with my custom list definition. For some reason, the problem was not evident when inspected using my best friend SharePoint Manager 2007.

As expected, removing the fields included in Schema.xml that are duplicated in my custom content type/fields broke the list.

It seems telling Schema.xml about my custom content type in the ContentTypeRef doesn't cut it—the ContentTypeBinding element is required to effectively map the list fields against the fields referenced in the content type. After adding a ContentTypeBinding element and enumerating a new list instance, the duplicates are gone.

Like Andrew illustrates, I add the ContentTypeBinding element to my ListDefinition.xml file between the ListTemplate and ListInstance elements (your file may be named differently):

<ContentTypeBinding ContentTypeId="0x0100CB568E1363E18245810A4EF25B057CCE" ListUrl="Lists/MyList" />

All's well once again... until next time!

Ps. Andy Burns asks himself:

I wonder what happens if you try to create a list definition without a content type reference?

Andy, you can’t leave me hanging like that man!!! I dropped the ContentTypeRef element from my Schema.xml file and while no errors were reported and a list instance only reported using the custom content type specified in ContentTypeBinding, NewForm.aspx was a dog’s breakfast with some aspects of the content type ignored. For example, I’ll often hide the Title field in my list definitions and yet there it was (sure, ShowInNewForm/ShowInEditForm might address this but that’s not the point). Fields also weren’t ordered the way they were in the content type definition.

Links

Thursday 5 November 2009

Sorting and filtering doesn't work on custom HTML list field

After deploying a custom list today I noticed, much to my annoyance, list items were not respecting the OrderBy FieldRef specified in my view and sorting the list manually in either direction on the field in question had no effect. Worse, the Show Filter Choices menu item led to the display of a #Render Failed error message in the central pane and the Application event log and SharePoint logs reported the following:

Unknown SQL Exception 306 occured. Additional error information from SQL Server is included below.  The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator.  The ntext data type cannot be selected as DISTINCT because it is not comparable.

The #Render Failed issue seems to be a fairly well-known bug and was apparently been fixed in the June 2009 WSS Cumulative Update although it's unclear whether that problem is related to my general sort/filter problem.

The problem field did have an edit control block attached in my case and while I expected that to be the culprit, changing the field type from HTML to text resolved the problem for me. Not my preferred approach but acceptable in this particular case.

Wednesday 4 November 2009

ListTemplate Name attribute doesn't resolve $Resources

Further to my previous 0x81070215 post, I've since discovered this error code also crops up when specifying an invalid ListTemplate value for the Name attribute.

In my case I was attempting to supply the value from a .resx file something like Name="$Resources:List_Name;". While resources are successfully resolved on other ListTemplate and List attributes, this doesn't seem to be the case with Name and its value must be specified explicitly; incidentally, the Name must match the name of the folder containing the list definition. The OOB 12-hive examples I've cross-checked also specify a literal value.

While this error code was presented in the UI, the SharePoint log files revealed how SharePoint was parsing the attribute value:

Cannot open "schema.xml": no such file or folder.
Failed to retrieve the list schema for feature {1B3FC94C-2FC6-4528-B968-4E91843C2005}, list template 13133; expected to find it at: "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Template\Features\TeMCorporateBannerListFeature\$Resources:List_Name;".
Unknown SPRequest error occurred. More information: 0x81070215

No biggie since DisplayName does handle resources for localisation however in this case I'm attempting to use resource files for consistency and to simplify maintenance across my list definition.

For reference, 0x81070201 seems to mean about the same thing (a similar error message I received after reverting the Name value to a literal with a typo).