SharePoint Development from a Documentation Perspective
(Cross-posted from the SharePoint Developer Documentation Team blog.)
By now you’ve probably been hearing some of the big news coming out of the SharePoint Developer Conference being held this week in Las Vegas. Doubtlessly, there’ll be tons more great information coming out of the Conference over the next four days concerning what’s new and notable in SharePoint Foundation 2010 and SharePoint Server 2010. But if you weren’t lucky enough to make it to Vegas this year, or are there but can’t wait for the session on your favorite area of SharePoint development, then have we got something you’ll want to take a close look at:
Introducing the SharePoint 2010 (Beta) Developer Center
That’s right, this morning we launched the SharePoint 2010 (Beta) Developer Center on MSDN. We’re using this new, combined Developer Center to give you your first detailed, public technical information and instruction around both SharePoint Foundation and SharePoint Server 2010. This new sub-site of the revamped SharePoint Developer Center highlights some early videos, documentation, and hands-on lab walkthroughs to introduce you to the exciting developer features on both SharePoint Foundation 2010 and SharePoint Server 2010.
But that‘s not all: we’ve also published a Beta release of the combined SharePoint 2010 SDK!
You’ll definitely want to spend some time on the site, getting ramped up for when the SharePoint 2010 Betas are released in November.
Learn SharePoint from the Ground Up
Of particular interest to developers new to SharePoint will be the Get Started Developing on SharePoint 2010. We’ve put together a series of 10 modules to help you get your feet wet on some of the main areas of SharePoint development, including:
· Building Web Parts
· What Developers Need to Know About SharePoint 2010
· Building Blocks for Web Part Development
· Accessing Data and Objects with Server-Side APIs
· Accessing Data and Objects with Client-Side APIs
· Accessing External Data with Business Connectivity Services
· Developing Business Processes with Workflows
· Creating Silverlight User Interfaces
· Sandboxed Solutions for Web Parts
· Creating Dialog Boxes and Ribbon Controls
Each module includes multiple video lessons, as well as code samples and hands-on lab walkthroughs, to give you a firm grounding in the topics covered.
Even experienced SharePoint developers will want to take a look at the modules that cover brand new development areas, like the client-side APIs, Silverlight user interfaces, sandboxed solutions, and the new ribbon user interface.
Get Your First Look at What’s New for Developers in SharePoint 2010
For an even deeper look at what’s new and notable in SharePoint Foundation and Server 2010, we’ve posted a Beta version of the combined SharePoint 2010 SDK. It’s packed with conceptual, procedural and reference material covering the major developmental areas of both Foundation and Server. All in all, it’s almost half a million words detailing how to develop SharePoint solutions.
For example, take a look here for what’s new in SharePoint Foundation 2010, including:
· Alerts Enhancements
· Business Connectivity Services
· Client Object Model
· Events Improvements
· Microsoft Synch Framework
· Mobile Device Development Enhancements
· Query Enhancements
· Sandboxed Solutions
· Service Application Framework
· Silverlight Integration and the Fluid Application Model
· UI Improvements
· Windows PowerShell for SharePoint
· Workflow Improvements
And take a look here for what’s new in SharePoint Server 2010, including:
· User Profiles and Social Data
· Business Connectivity Services (BCS)
· Enterprise Content Management (ECM)
· SharePoint Enterprise Search
· PerformancePoint Services
· Excel Services
Some other places you might want to start:
· If you’re newer to SharePoint development, you might want to spend some time in the Getting Started and Building Blocks sections of the SDK, getting a firm grounding in the basics.
· If you’re coming to SharePoint from an ASP.NET development background, but sure and check out the Glide Path for ASP.NET Developers section, which is specifically aimed at developers transitioning from ASP.NET development to development on the SharePoint Foundation platform.
Let Us Know What You Want
Now, this SDK is a Beta release, so you’ll likely see some rough edges. But we’ve combined this SDK to cover both SharePoint Foundation and Server, and restructured it to present the continuum of SharePoint development in as logical and intuitive a way as we could. We then packed it with new and updated conceptual, procedural, and reference material.
We’d love to hear what you think of what we’ve done. As always, as you read through the SDK, if you spot issues, don’t see the information you need, or have suggestions, please drop us a line and let us know how we can improve our developer documentation. It’s easy; just do one of the following:
· Enter a comment in the MSDN ratings box
· Email us directly at docthis (at) Microsoft.com
· Email us through this blog
Be sure and check the SharePoint Developer Documentation Team blog often (or even better, subscribe to its RSS feed), as we plan on using the blog to preview draft versions of additional SDK content as it gets written.
For the last several weeks, I’ve been experimenting with using mind maps, both as a way of brainstorming about developer content, and as a possible way of presenting content in a less-structured way than a typical (linear) table of contents. In regards to that last goal, I really liked how mind maps let you graphically lay out a content area, and draw non-linear relationships between various nodes. I could see how this could be a much more intuitive, discoverable way of presenting content, especially for a technology as complex and interrelated as Windows SharePoint Services. I was using an application called MindManager (from Mindjet) to create my mind maps, and was generally pretty happy with the results.
There was just one problem: in order to share a fully-functioning map with anyone else, they needed to have the same software (or at least a downloadable viewer) installed. Sure, Mind Manager let me save a given mind map as a image map or static PDF, but each of those formats ruled out one of the main selling points on the mind maps themselves: the ability to collapse/expand various nodes on the map, and thereby control the level of information you were looking at. Without that interactive ability, it really seemed like the value of using mind maps as content/resource maps was fairly restricted.
Perhaps MindJet thought the same thing, because the new version of MindManager now lets you save your mind maps as interactive PDF files. Now anyone who can view PDFs can also interact with your maps, and customize the view by collapsing/expanding the nodes of their choice.
So I’ve created an interactive mind map as another way of presenting some of the information we currently have on MSDN, and I’ve love to know what people think of it. Basically, I’ve taken some of the content links present on the Workflow Resource Center and restructured them as a mind map. Rather than present the content based on content type or source, as the Resource Center does, I’ve tried to present the content grouped to present a workflow development overview, as well as by developer tool. Icons next to each link display what type of content I’m linking to (SDK topic, blog, multimedia, etc.); the text color denotes whether the link applies just to Windows SharePoint Services (green text) or Office SharePoint Server as well (blue text).
I’m hoping you’ll take a few minutes and download the map, play with it, and let me know what you think, even if you don’t have any interest in workflow development. More than just does this specific map meet your needs, I’ve love to hear whether you think using such maps in general is a useful/worthwhile way to present developer documentation. Leave a comment after the post or ping me directly through the blog; I’d love to hear from you.
(One minor drawback I can see is how much saving as an interactive PDF bloats the size of the file: this download, of a fairly small map, is 1.5M. Now if we could just get them to add a ‘Save as Silverlight’ feature…)
(Cross-posted from the SharePoint Developer Documentation Team Blog.)
By now you’ve no doubt heard that SP1 for Windows SharePoint Services 3.0, Office SharePoint Server 2007, and Office SharePoint Designer are now available. (And if you haven’t heard, go here to get all the important details before you download and install the Service Packs.)
For a complete listing of the documentation available for SharePoint SP1, check out the What’s New in SharePoint Server 2007 Service Pack 1 page on MSDN, which includes information resources for both WSS and MOSS SP1.
I’m happy to announce that as part of the SP1 push, we’ve again updated the WSS and MOSS SDKs on MSDN:
· Windows SharePoint Services 3.0 SDK (December 2007 Refresh)
· Office SharePoint Server 2007 SDK (December 2007 Refresh)
Here’s a quick run-down of additions and updates we’ve made to the WSS SDK:
New and Updated Material in the Windows SharePoint Services 3.0 SP1 SDK
New conceptual sections and topics that detail new features in Windows SharePoint Services 3.0 SP1 include:
· ASP.NET AJAX in Windows SharePoint Services
This section provides overview information, installation instructions, and programming examples that introduce you to how Microsoft ASP.NET AJAX interacts with Web Parts. Topics include:
· Overview: ASP.NET AJAX and Web Parts in Windows SharePoint Services 3.0
· Installing ASP.NET 2.0 AJAX Extensions 1.0 in Windows SharePoint Services Version 3.0
· Walkthrough: Creating a Basic ASP.NET AJAX-enabled Web Part
Other new conceptual sections and topics include:
· Workflow Actions Schema Overview
The section discusses how to use the Workflow Actions schema to create and deploy custom workflow actions. The section includes reference topics for each of the 14 elements in the schema, as well as an example .ACTIONS file:
· .ACTIONS File Example (WorkflowActions)
· Alerts in Windows SharePoint Services
This section provides 8 new topics of overview information and programming tasks to help you work with Windows SharePoint Services 3.0 Alerts.
Significantly revised sections and topics include:
· Custom Field Types
This section has been expanded with nine new topics, including the following new walkthrough:
· Walkthrough: Creating a Custom Field Type
In addition, reference material for all base field-rendering control types, and most derived types, in Microsoft.SharePoint.WebControls has been expanded.
· Mobile Development
This section has been expanded with 6 new conceptual topics, including the following new procedural and walkthrough topics:
· How to: Customize Mobile Home Pages
· How to: Customize Mobile List View and Form Pages
· How to: Customize Field Rendering on Mobile Pages
· Walkthrough: Customizing Item Titles on a Mobile Display Form
· Walkthrough: Creating a Custom Field Rendering Control for Mobile Pages
In addition, reference material for all types in the Microsoft.SharePoint.MobileControls namespace has been added or expanded. The types in this namespace are now fully documented.
· Working with Site Templates and Definitions
Several topics have been expanded.
· All types in the Microsoft.SharePoint namespace that connected to auditing are now fully documented.
· More than 80 code samples rewritten to adhere to the best coding practices as described in the following articles:
· Best Practices: Common Coding Issues When Using the SharePoint Object Model
· Best Practices: Using Disposable Windows SharePoint Services Objects
· Greatly expanded reference material for 39 types in the Microsoft.SharePoint.Utilities namespace.
This update also includes numerous other updates and revisions to existing SDK content.
And as for the SharePoint Server 2007 SDK, we’ve added and revised quite a bit of material there as well:
New and Updated Material in the SharePoint Server 2007 SP1 SDK
New and Improved Features in Office SharePoint Server 2007 SP1
· Support for Custom HTTP and SOAP Headers
New Conceptual Topics and How Tos
· SharePoint Products and Technologies Customization Best Practices
· Modeling Web Service Systems
· Modeling Database Systems
· Document Converter Framework Sample
· Working with Menus and Navigation Objects
· Modifying Navigation Settings Through the UI
· Customizing Navigation Controls and Providers
New Web Services and Class Library Reference Topics
· Microsoft.SharePoint.UserProfiles (56 classes)
· User Profile Web Service (14 classes)
· User Profile Change Web Service (2 classes)
· Exception classes (multiple classes in various namespaces)
· Internal only classes (multiple classes in various namespaces)
· WCM Document Converters Code sample
· Workflow Collect Feedback ASPX sample
Check it out, and as always, let us know what you think—either through rating our content, entering a comment on the topic online, or pinging us with an email through our blog.
Now that I’m managing a documentation team, I just don’t get to blog about SharePoint developer issues nearly as often as I’d like. In part to help remedy that, we’ve launched the SharePoint Developer Documentation Team blog. In the coming months, the programmer-writers for Windows SharePoint Services and Office SharePoint Server will be posting on a range of developer issues, information, and best practices. Our goals with the new blog are several:
· Present “draft” versions of SDK content before it’s available in the SDKs themselves. These drafts are tech-reviewed content that will end up in the SDKS; this is just our way of getting the information out to you as quick as we can.
· Promote content that we publish on MSDN. This includes giving you the latest news on new technical articles, SDK updates, code samples or tools downloads, and anything else new and noteworthy we think you’ll want to take a look at.
· Blog about the developer documentation we produce, and why. Ever wonder why we document what we do, in the way we do? In future posts we’ll explore the decisions we make when planning SharePoint developer documentation, and the data we base those decisions on.
· Engage with users, and find out just how developers are using (or would like to use) the documentation we produce.
· Experiment with presenting developer documentation in new and different formats.
Already, in the few weeks it’s been live, we’ve posted extensive information on extending workflow actions in SharePoint Designer, as well as the basics of content deployment. And i
So go check it out. Subscribe to our RSS feed. Even better, drop us a line and tell us what you’d like to see on the blog, or in our developer documentation.
I’m happy to announce that the Windows SharePoint Services 3.0 SDK has been updated online on MSDN!
What’s new in the April update of the WSS 3.0 Online SDK:
New conceptual sections:
Change Log and Synchronizing Applications
Creating Declarative, No-Code Workflow Editors
How to: Create a Custom Field Type and Field Control
How To: Extend the STSADM Utility
Schema reference topics for the following schemas:
Content Migration XML Schema Reference: Contains over 180 element topics that detail the eight migration schemas
Workflow Configuration Schema
Greatly expanded reference material for over 300 types in the following namespaces:
As well as expanded reference material for the following Web Services:
· Authentication Web Service
· Copy Web Service
This update also includes numerous updates and revisions to existing SDK content.
Note: The WSS 3.0 SDK download will be updated with the next online update, currently scheduled for the end of June.
I want to thank everyone who contributed their time and effort to making this update possible. We’ve added an immense amount of detailed technical content, with more to come. Check it out!
OK, we're back. Since it's now officially 2007, it seemed appropriate to focus my first entry of the New Year on Office SharePoint Server 2007, and Office InfoPath 2007.
Shortly before the holidays, someone asked me if I had any guidance for customers who wanted to set up workflow tasks to be bulk editable. To which I promptly replied:
You can do what?
I swear, there's so much functionality crammed in this product that sometimes I think it's going to take me the next two product cycles just to cover it all properly. I had no idea you even could edit workflow tasks as a group.
So, without further ado, here's the scoop:
In Office SharePoint Server 2007, you can define workflow tasks as bulk editable, and provide a custom InfoPath form view to enable users to edit workflow tasks as a group.
Bulk editable tasks are workflow tasks that can be edited as a group. All the tasks must be of the same task type, and from the same workflow association. For example, a user might want to mark all tasks of a certain type as 'complete' for a given workflow association.
In addition, by using an InfoPath form as the workflow task edit form, you can include logic in the InfoPath form to switch form views depending on whether the user is editing an individual task or bulk editing tasks.
Workflow tasks are displayed in task lists, just as any other tasks. When the user navigates to the task list, the tasks are displayed based on the View selected, and the access control list rights (ACLs) of the user. A workflow may have several different types of tasks, but all the tasks from a given workflow association are contained on the same task list. However, a given task list can contain the tasks for multiple workflow template and associations.
Developers can include elements in the workflow template definition that define task types as bulk editable.
For workflow tasks, users can select to process workflow tasks in bulk. Office SharePoint Server then displays a list of the workflow tasks types on that list that are bulk editable, sorted by workflow template. When the user selects a task type from a given workflow template, Office SharePoint Server displays the task edit form for that type. Developers can include logic in their InfoPath task edit forms that changes the form view based on whether the user is editing tasks individually, or in bulk.
The user can then edit the tasks as a group. The workflow task edit form need not contain any special logic to bulk edit the tasks; this is completely handled by Office SharePoint Server. When the user submits the task edit form, Office SharePoint Server writes the submitted data to each task of that task type for that workflow template for all associations of that template, as a timer job.
For information on specifying InfoPath workflow task forms, see Specifying InfoPath 2007 Forms for Workflows.
So, here's how it looks in the user interface, from the user's perspective:
1. Navigate to the task list that contains the workflow tasks you want to bulk edit.
The workflow tasks are displayed based on the View selected, and the your ACLs.
2. From the Actions menu, select Process all tasks.
Office SharePoint Server displays the Bulk Task Selection page. This page lists each task type on the list that is bulk editable. Task types are sorted by workflow template. Workflow associations are listed in parenthesis after the task type name.
3. Select the task type for the workflow template you want to bulk edit, and click OK.
Office SharePoint Server displays the task edit form. If you've included the proper logic in your form, MOSS displays the bulk edit view of the task edit form.
4. Enter your edits, and click Submit.
Office SharePoint Server writes the submitted data to each task of that task type for that workflow template, as a timer job.
Note Because the timer job updates each task, any custom code you have included in an OnTaskChanged event for that task type while run on each task as well.
To define a task type in a given workflow as bulk editable, you add two elements to the workflow template definition.
Add the following two elements to the MetaData element in the workflow template definition, where N represents the task type number:
· TaskN_IsBulkActionable Optional Boolean. TRUE to define the task type as a task type that can be edited in bulk.
This element is optional. Office SharePoint Server treats task types that are not explicitly defined as bulk actionable as not bulk actionable.
This element defines the task type as bulk editable for this specific workflow template only. Therefore, can use the same task type in multiple workflows, and decide on a per workflow basis whether the task type is bulk editable.
All tasks of a given type are either bulk actionable or not, within a given workflow template.
· TaskN_BulkActionableFormName Optional Text. The task name to display for this task type in the Office SharePoint Server 2007 user interface. Users click this name to display the workflow bulk edit form.
For more information on workflow template definitions, see Workflow Definition Schema.
The following example has been edited for clarity.
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright (c) Microsoft Corporation. All rights reserved. -->
Using InfoPath forms, you can provide a custom form view to enable users to edit workflow tasks as a group. When the user selects the task type they want to bulk edit, Office SharePoint Server displays the task edit form for that workflow task type, passing context data to the form. This context data includes an attribute, isBulkMode, which designates whether the task form is being called for bulk edit operations. Developers can include logic in their forms to specify different views based on whether the isBulkMode attribute is set to TRUE or FALSE.
We recommend that the task edit form for each workflow task type you define as bulk editable contain two views:
· One for individual task editing.
· One for bulk editing of tasks.
The bulk edit view should not load data from any particular task upon load, since Office SharePoint Server applies the data the user submits to every task of that type for the selected workflow association.
· Include logic in the form that parses the context data passed to the form on load. This logic should include having the form display the bulk edit view if the isBulkMode attribute of the context data is set to TRUE.
Note To add the workflow context data to the form, you must first create an XML file that represents the context schema, and then import that file into the form as a secondary data source. For more information, see the Adding Workflow Context Data as a Secondary Data Source section of How to: Configure a Contact Selector Control on Your InfoPath Workflow Form.
For more information on using InfoPath forms with Office SharePoint Server workflows in general, see InfoPath Forms for Workflows.
Ever find something wrong/incomplete with an SDK topic on MSDN, and wish you could slap a Post-It Note with the correction right on the topic? Or come up with the perfect code sample for an object model reference topic, and wish you could annotate the topic with your masterpiece?
Well, now you can. Say hello to the MSDN Wiki.
This new functionality lets members of the community append selected topics on MSDN with their own comments, corrections, and code samples. Now you can share your hard-earned tips, tricks, best practices and gotchas with other developers, and learn from their experience as well. All this without leaving the MSDN library, or even the topic you’re in.
And the best part of it is: the MSDN Wiki is now part of every topic in the Windows SharePoint Services 3.0 and Office SharePoint Server 2007 SDKs.
Here’s how it works:
Every topic in the WSS 3.0 and MOSS 2007 SDKs now has a Community Content section append to the end of the topic. Anyone with a Windows Live account can log in and add content to this section. Got a great tip for a topic? Add it. Want to share a particularly cool piece of code? Add it to the relevant topic. You’ll retain ownership of your content; we only ask for a non-exclusive license so we can share your content with others.
As you can probably tell, I’m pretty jazzed about this. I think this is a great way to harness the power of the SharePoint developer community to help people create the solutions they want. It’s going to be fascinating to see how this evolves.
Just as important to me, personally, is that it gives us SDK writers an avenue to get our content out to the community that much faster. Now, instead of making a correction/addition to an SDK topic and then waiting months until the next SDK republish, I can add my additions directly to the Community Content section and get that information directly in front of our users nearly instantaneously. This is one of the things I had been using my blog for in the past, but this is even better, in that the new information will be presented directly within the relevant topic itself.
So look for us—we’ll be identified by the MSFT designation by our names.
Now that we’ve managed to get the Windows SharePoint Services and Office SharePoint Server SDKs out the door, I’ve had a chance to catch my breath and do a couple of one-off side projects. One of which is (big surprise) another poster highlighting the developer functionality in WSS 3.0.
This time around I’ve focused on the Information Rights Management framework in WSS. In WSS 3.0, administrators can now apply IRM to document libraries and item attachments. IRM lets you create a persistent set of access controls that live with the content, helping you control access to files even after a user downloads them. And if you’ve got custom file types, you can create IRM protectors: custom assemblies that plug into the IRM framework and control the conversion of those file types to and from their encrypted, rights-managed formats.
WSS gives you the choice of creating two types of custom protectors:
· Integrated protectors, which use Windows SharePoint Services to access the Windows Rights Management Services (RMS) platform in order to generate protected versions of files, and to remove protection from rights-managed files.
· Autonomous protectors, on the other hand, configure and execute the entire rights-management process by themselves.
The poster illustrates how the two types of protectors fit into the IRM framework in WSS 3.0, and how WSS uses each to rights manage documents during file upload and download process.
To download the poster, just click on the attachment at the end of this post.
You can read all about the IRM framework in WSS starting here.
Something you might have noticed as you perused the updated Windows SharePoint Services or Office SharePoint Server SDKs--or any MSDN technical article in the last week or so--was that the familiar ratings system has been replaced. Since the new ratings system may not be immediately discoverable or intuitive, I figured it was worth taking a few minutes to show you how to rate an article or provide feedback using the new system.
The first thing you'll notice is that MSDN's standard 9 point ratings scale has been replaced by a five star scale. The rating scale now appears on the article menu bar, right underneath the MSDN menu bar:
If an article hasn't yet been rated, all the stars are white, as in the screenshot above. (And I, for one, will not miss the 'Be the first to rate this page!' message on unrated articles. As a technical writer, nothing was more lonely than checking on your article weeks after it had been published and seeing this auto-generated plea for someone, anyone, to rate your article. But I digress.)
Once an article's been rated, colored stars represent the article or topic's current rating. The article pictured below, for example, has a current rating of four out of five:
So, how do you actually rate the article and enter feedback using the new system? Simply mouse hover over the stars themselves. You can then click on the star that represents the rating you'd like to give the article. The stars then turn red to reflect the rating you're chosen (and they stay that way until you submit your rating). However, you can change your rating up until you submit it.
In addition, the Optional Feedback form opens, enabling you to send us detailed comments on the article.
When you're done, just click the Send button to submit your rating and comments.
As under the old system, you only get to rate an article once. If you hover over the rating on an article you've already rated, you'll get a tooltip to that effect.
One thing I do wish MSDN had retained from the old system was the graph at the end of each article that told you how many people had rated the article, and showed their raw rating scores. As an MSDN user, I found this information very helpful in deciding whether or not to invest my time in reading longer articles.
After all, this:
Tells a much different story than this:
Even though they both result in an article rating of 4.5 (under the old scale). The first tells me that only two people rated the article, one of whom was very pleased with it (and one who might just be a troll rating everything a 1.) The second tells me that a statistically significant number of people found the article of limited utility. This could be good information for a reader to have before reading a 20 page article.
In any case, another cool new feature is the improved 'breadcrumb' functionality. (The term 'breadcrumb' refers to the hierarchical list of pages/nodes you've had to traverse to get to your current location in the MSDN library.) Now, if you hover over an entry in the breadcrumb, you'll get a hot-linked list of the topics/nodes at that same level in the MSDN library table of contents. I think this is going to make our SDK content a lot more discoverable/navigable in the future.
I'd be interested in what you all think of the new system.
So now that you've downloaded Windows SharePoint Services 3.0, you're ready to get serious about creating SharePoint solutions, right? If so, let me direct you to another developer tool you'll want to download:
Visual Studio 2005 extensions for Windows SharePoint Services 3.0
The extensions (as they're known to their friends) were designed specifically to jumpstart developers creating SharePoint solutions in Visual Studio. They include project and item templates for essential SharePoint building blocks like Web parts; team sites, blank sites, and list definitions; custom fields, content types, and modules. Each template includes functionality that makes coding, testing, and deploying these items easier than ever before. If you intent to develop in the SharePoint environment using Visual Studio, this download is for you.
And, if you're planning on using the Web part project template, check out the accompanying article, which provides a quick rundown on how it's done:
Creating a Windows SharePoint Services 3.0 Web Part Using Visual Studio 2005 Extensions
And, as always, if you read the article, please take a minute and rate it. Thanks.
So by now you no doubt know that Windows SharePoint Services 3.0 is available for download. But something you might have missed is the fact that we have updated the Windows SharePoint Services 3.0 and Office SharePoint Server 2007 SDKs on MSDN.
You can find the WSS SDK here.
And the MOSS SDK here.
These latest updates represent the "official" (that is, non-Beta) release of both SDKs. We've tried to provide the highest-priority developer information, as completely and accurately as we can. While there are definitely areas of the SDKs we plan on expanding in future updates, if we've done our job then you should have plenty of detailed technical information to get you started developing solutions in the SharePoint environment.
As you go through each SDK, don't be shy about letting us know what works (or doesn't) for you, and what types of information you'd like to see in future updates. I can tell you first hand that the comments you type in on MSDN don't just go into a black hole somewhere; they do indeed make it back to the correct documentation team. And you can always contact me through this blog as well, and I'll try and route your comments to the appropriate person (requests for money or free Zune players will be ignored.)
Just for the sake of completeness, here are the various downloads for WSS:
Windows SharePoint Services 3.0
Windows SharePoint Services 3.0 Language Pack
Windows SharePoint Services 3.0 (x64)
Windows SharePoint Services 3.0 Language Pack (x64)
For these four entries, I’m going to go over in detail how to construct and register a custom parser that enables you to promote and demote properties between your custom file types and Windows SharePoint Services.
Read part one here.
Read part two here.
Read part three here.
Today, I’ll round out the document parser information I’m presenting by talking about how to register your custom parser with WSS. I’ll also give you a quick overview of the ISPDocumentParser interface, which your parser needs to implement to communicate with WSS.
To register a custom document parser with WSS, you must add a node to the document parser definition file that identifies your parser and the file type or types it can parse.
You can specify the file type or types a document parser can parse either by file extension, or file type program ID.
WSS stores the document parser definition file, DOCPARSE.XML, at the following location:
Web Server Extensions\12\CONFIG\DOCPARSE.XML
The document parser definition schema is as follows:
Following is a list of the elements in the document parser definition schema.
Required. Represents the root element of the document parser definition schema.
Required. Each docParser element represents a document parser and its associated file type. This element contains the following attributes:
· Name Required string. The file type associated with the parser. For docParser elements within the ByExtension element, set the Name attribute to the file extension. For docParser elements within the ByProdId element, set the Name attribute to the program Id of the file type. To associate a parser with multiple file types, add a docParser element for each file type.
· ProgId Required string. The program ID of the parser. This represents the ‘friendly name’ of the parser. This enables you to upgrade a parser without having to edit its document parser definition entry in the DOCPARSE.XML file. However, this prevents you from installing different versions of the same parser side-by-side.
Below is an example of a document parser definition file.
<docParser name="abc" ProgId="AdventureWorks.AWDocumentParser.ABCParser"/>
<DocParser name="AWApplication.Document" ProgId="AdventureWorks.AWDocumentParser.ABCParser"/>
In order for a custom document parser to perform document property promotion and demotion in WSS, it must implement the following document parser interfaces. These interfaces enable the document parser to be invoked by WSS, and send and receive document properties when so invoked.
Represents a custom document parser. This class includes the methods WSS uses to invoke the document parser.
Represents a property bag object used to transmit document properties between the document parser and WSS. Includes methods that enable the document parser to access the content type and document library schemas for the specified document.
Represents an enumerable document property collection. Includes methods the document parser can use to enumerate through the document property collection.
Represents a single document property. Includes methods for the document parser to get and set the document property value and data type.
When WSS invokes a document parser to promote document properties, the parser writes all document properties to a property bag object. WSS then determines which of these document properties to promote to matching document library columns. If the document has been assigned a content type, then WSS promotes the document properties that match the columns included in the content type.
Using the document parser interface, document parsers can access the content type assigned to the document, and, if desired, store the content type in the document itself. If, when WSS invokes the parser to parser a document, the parser writes the document’s content type to the property bag object as a document property, WSS compares this content type to the content types associated with the document library to which the document is being uploaded. If the document’s content type is one that is associated with the document library, WSS promotes the appropriate document properties and saves the document.
However, there are cases where the document’s content type may not actually be associated with the document library to which the user is uploading the document. For example, the user might have created the document from a document template that contained a content type; or the user might move a document from one document library to another.
If the document’s content type is not associated with the document library, WSS takes the following actions:
· If the document contains a document property for content type, but that document property is empty, WSS invokes the parser to demote the default list content type for the document library into the document. WSS then promotes the document properties that match columns in the default list content type, and stores the document.
This would occur if the document had not yet been assigned a content type.
· If the document is assigned a content type not associated with the document library, WSS determines whether the document library allows any content type. If so, WSS leaves the document’s content type as is. WSS does not promote the document content type; however, it does promote any document properties that match document library columns.
Lists can be set to allow any content type. To do this, add the Unknown Document Type content type to the list. If you add this content type to a list, then documents of any content type can be uploaded to the list without having their content types overwritten. This enables users to move a document to the list without losing the document’s metadata, as would happen if the content type was overwritten.
· If the document is assigned a content type not associated with the document library, and the document library does not allow any content types, WSS invokes the parser to demote the default list content type for the document library into the document. WSS then promotes the document properties that match columns in the default list content type, and stores the document.
The figure below details the actions taken by WSS, if the parser includes the document’s content type as a document property in the property bag returned to WSS when the parser parses a document.
WSS never promotes a document’s content type onto a document library.
In my final post of this series, I'll introduce you to the document parser definition schema, and the document parser interface.
In my last entry, I gave you a brief overview of what document parsers are in Windows SharePoint Services V3, and a high-level look at what you need to do to build a custom document parser for your own custom file types. Today we’re going to start digging a little deeper, and examine how a parser interacts with WSS in detail.
When a file is uploaded, or move or copied to a document library, WSS determines if a parser is associated with the document's file type. If one is, WSS invokes the parser, passing it the document to be parsed, and a property bag object. The parser extracts the properties and matching property values from the document, and adds them to the property bag object. The parser extracts all the properties from the document.
WSS accesses the document property bag and determines which properties match the columns for the document. It then promotes those properties, or writes the document property value to the matching document library column. WSS only promotes the properties that match columns applicable to the document. The columns applicable to a document are specified by:
· The document's content type, if it has been assigned a content type.
· The columns in the document library, if the document does not have a content type.
WSS also stores the entire document property collection in a hash table; this hash table can be accessed programmatically by using the SPFile.Properties properties. There is no user interface to access the document properties hash table.
The following figure illustrates the document parsing process. In it, the parser extracts document properties from the document and writes them to the property bag. Of the four document properties, three are included in the document's content type. WSS promotes these properties to the document library; that is, writes their property values to the appropriate columns. WSS does not promote the fourth document property, Status, even though the document library includes a matching column. This is because the document's content type does not include the Status column. WSS also writes all four document properties to a hash table that is stored with the document on the document library.
WSS can also invoke the parser to demote properties, or write a column value into the matching property in the document itself. When WSS invokes the demotion function of the parser, it again passes the parser the document, and a property bag object. In this case, the property bag object contains the properties that WSS expects the parser to demote into the document. The parser demotes the specified properties, and WSS saves the updated document back to the document library.
The figure below illustrates the document property demotion process. To update two document properties, WSS invokes the parser, passing it the document to be updated, and a property bag object containing the two document properties. The parser reads the property values from the property bag, and updates the properties in the document. When the parser finishes updating the document, it passes a parameter back to WSS that indicates that it has changed the document. WSS then saves the updated document to the document library.
Once the document parser writes the document properties to the property bag object, WSS promotes the document properties that match columns on the document library. To do this, WSS compares the document property name with the internal names of the columns in the document’s content type, or on the document library itself if the document doesn’t have a content type. When WSS finds a column whose internal name matches the document property, it promotes the document property value into that column for the document.
However, WSS also enables you to explicitly map a document property to a specific column. You specify this mapping information in the column’s field definition schema.
Mapping document properties to columns in the column’s field definition enables you to map document properties to columns that may or may not be named the same. For example, you can map the document property ‘Author’ to the ‘Creator’ column of a content type or document library.
To specify this mapping, add a ParserRef element to the field definition schema, as shown in the example below:
<Field Type=”Text” Name=”Creator” … >
<ParserRef Name=”Author” Assembly=”myParser.Assembly”>
The following elements are used to define a document property mapping:
Optional. Represents a list of document parser references for this column.
Optional. Represents a single document parser reference. This element contains the following attributes:
· Name Required String. The name of the document property to be mapped to this column.
· Assembly Required String. The name of the document parser used.
A column’s field definition might contain multiple parser references, each specifying a different document parser.
In addition, if you are working with files in multiple languages, you can use parser references to manage the mapping of document properties to the appropriate columns in multiple languages, rather than have to build that functionality into the parser itself. The parser can generate a single document property, while you use multiple parser references to make sure the property is mapped to the correct column for that language. For example, suppose a parser extracts a document property named ‘Singer’. You could then map that property to a column named ‘Cantador’, as in the example below:
<Field Type=”Text” Name=”Cantador” … >
<ParserRef Name=”Singer” CLSID=”MyParser”>
<ParserRef Name=”Artist” Assembly=”MP3Parser.Assembly”>
To edit a column’s field definition schema programmatically, use the SPField.SchemaXML object. There is no equivalent user interface for specifying a parsers for a column.
In the next entry, we'll discuss how WSS processes document that contain their content type definition.
Now that I’ve talked about the built-in XML parser, and how you can use it to promote and demote document properties for XML files, you might be thinking: what about custom files types that aren’t XML? What if I’ve got proprietary binary file types from which I want to promote and demote properties to the SharePoint list?
We’ve got you covered there as well.
For the next four entries, I’m going to go over in detail how to construct and register a custom parser that enables you to promote and demote properties between your custom file types and Windows SharePoint Services.
This information will get rolled into the next update of the WSS SDK, so consider this a preview if case you want to work with the parser framework right now.
Managing the metadata associated with your document is one of the most powerful advantages of storing your enterprise content in WSS. However, keeping that information in synch between the document library level and in the document itself is a challenge. WSS provides the document parser infrastructure, which enables you to create and install custom document parsers that can parse your custom file types and update a document for changes made at the document library level, and vice versa. Using a document parser for your custom file types helps ensure that your document metadata is always up-to-date and synchronized between the document library and the document itself.
A document parser is a custom COM assembly that, by implementing the WSS document parser interface, does the following when invoked by WSS:
· Extracts document property values from a document of a certain file type, and pass those property values to WSS for promotion to the document library property columns.
· Receives document properties, and demote those property values into the document itself.
This enables users to edit document properties in the document itself, and have the property values on the document library automatically updated to reflect their changes. Likewise, users can update property values at the document library level, and have those changes automatically written back into the document.
I’ll talk about how WSS invokes document parsers, and how those parsers promote and demote document metadata, in my next entry.
For WSS to use a custom document parser, the document parser must meet the following conditions:
· The document parser must be a COM assembly that implements the document parser interface.
I’ll go over the details of the IParser interface in a later entry.
· The document parser assembly must be installed and registered on each front-end Web server in the WSS installation.
· You must add an entry for the document parser in DOCPARSE.XML, the file that contains the list of document parsers and the file types with which each is associated.
And I’ll give you the specifics of the document parser definition schema in a later entry as well. All in good time.
WSS selects the document parser to invoke based on the file type of the document to be parsed. A given document parser can be associated with multiple file types, but you can associate a given file type with only one parser.
To specify the file type or types that a custom document parser can parse, you add a node to the Docparse.XML file. Each node in this document identifies a document parser assembly, and specifies the file type for which it is to be used. You can specify a file type by either file extension or program ID.
If you specify multiple document parsers for the same file type, WSS invokes the first document parser in the list associated with the file type.
WSS includes built-in document parsers for the following file types:
· OLE: includes DOC, XLS, PPT, MSG, and PUB file formats
· Office 2007 XML formats: includes DOCX, DOCM, PPTX, PPTM, XLSX and XLSM file formats
· HTM: includes HTM, HTML, MHT, MHTM, and ASPX file formats
You cannot create a custom document parser for these file types. With the XML parser, you can use content types to specify which document properties you want to map to which content type columns, and where the document properties reside in your XML documents.
To guarantee that WSS is able to invoke a given parser whenever necessary, you must install each parser assembly on each front end Web server in your WSS installation. Because of this, you can specify only one parser for a given file type across a WSS installation.
The document parser framework does not include the ability to package and deploy a custom document parser as part of a SharePoint feature.
In my next post, I’ll discuss how the document parser actually parses documents and interacts with WSS.
Today I'd like to talk about how to store and manage XML forms (InfoPath and otherwise) in WSS V3.
In general, forms have three special areas of functionality:
· Property Promotion and Demotion This refers to promoting and demoting document data to and from columns in a SharePoint library.
· Link Management This refers to how WSS keeps the link to the form template in the XML file up to date, if any site, sub-site, or library is renamed.
· Merge Forms Sends multiple XML files that have the same schema to a client application to be merged.
In Windows SharePoint Services Version 2, this special functionality was part of the Form Library site template. Now, in WSS V3, it's encapsulated in the Form content type instead. Instead of creating a new form library, you can create a new content type, inheriting from the Form content type. Your new form becomes the template for the content type.
This new approach offers several major advantages over the form libraries:
· Central management of forms Because you're creating a new content type, you gain all the advantages content types offer in terms of centralized management. You can control the form and its metadata from a single location, regardless of how many libraries to which you've added the content type. You can also specify enterprise content management features for your content type, such as property promotion and demotion, workflow, or (if you have Office Server 2007) information policy. And you don't have to republish the form if you make changes to the content type for which it's the form template.
· Add multiple forms to the same library Again, because each type of form is a separate content type, you can add multiple form type to the same library.
· Add forms to the same libraries as documents You can form content types to the same libraries that contain document content types. In a very real sense, there's no distinction between form and document libraries in WSS V3; there're just libraries. Any special functionality is encapsulated in the content types themselves.
(However, the form library site template has been retained in WSS V3 for purposes of backward compatibility with XML-based forms editors that do not support publishing forms to content types, such as InfoPath 2003. But if you are using an XML-based forms editor that supports content types, such as InfoPath 2007, we strongly recommend you use the Form content type instead of the form library template. And with all the obvious advantages, why wouldn't you?)
So let's talk specifically about InfoPath 2007 forms for WSS V3. InfoPath 2007 includes the ability to publish forms directly into new or existing content types on a WSS installation. This includes setting up property promotion and demotion: you're able to choose which data fields on your form you want to map to which SharePoint columns. You get link management and merge forms functionality for free, because the content type to which you publish your form is a child of the Form content type.
When you publish an InfoPath 2007 form, you have the option to publish it to a SharePoint site. When you do, you have the further option of publishing the form into a new or existing content type.
(You still have the option of publishing your form to a document library, just as you did with InfoPath 2003. In InfoPath 2007, though, you can update both document libraries as well as form libraries, as long as that library’s default content type is a child of the Form content type. If the library doesn’t have multiple content types, then the single library content type must be a child of Form in order for you to update it. In addition, document property demotion now works in document libraries.)
When you choose to create a new content type, you select the content type from which you want your new content type to inherit. By default, the new content type is a direct child of the Form content type, but you can specify any descendant of Form to use as your new content type's parent.
Next, you can choose which data fields you want to promote and demote to and from SharePoint site columns. To do this, you specify the columns to which you want to map the data fields in your form. You can map the data fields to existing site columns, or create new columns.
If you map a data field to an existing site column, InfoPath adds a <FieldRef> element to the content type for that site column. The <FieldRef> element contains a set of attributes you can override for the site column, as it applies to items assigned this content type. These attributes include those that specify where in an XML form the data field information is located. Because you’re mapping a data field (i.e., the data in your XML) to the column, InfoPath uses the Node attribute to specify an XPath expression for where the data resides in the form.
For more information on how the built-in XML parser uses the Node attribute for data promotion and demotion, see this earlier post.
If you create a new site column, InfoPath adds a <Field> element that represents that site column to the site, and then adds a <FieldRef> element to the content type for that site column.
For more information on how <Field> and <FieldRef> elements differ, and how <FieldRef> elements work in a content type, see my earlier post here.
If you choose to update the existing content type itself, you can stick with the existing columns for that content type, or add new ones. You can also remove columns for data fields you've deleted or don't want promoted or demoted anymore. If you do delete a column, InfoPath removes the <FieldRef> element from the content type definition, but leaves the site column intact (that is, the <Field> element for that site column remains in the site definition). You cannot remove any columns the content type inherits from its parent content type.
Once you've published your form to a content type, you can use WSS to further customize the content type, such as adding columns, workflows, and policies. Also, remember that this is a site content type; in order to use the content type in a library, you have to add that site content type to the library through WSS.
Here are a few other things to keeping mind about InfoPath 2007 forms and form content types:
InfoPath forms themselves do not contain the content type ID of the content type they’ve been assigned. Instead, WSS uses the form template to determine the content type of the form. The form template URL is included in the <?xml> processing instruction of the form, and points to the .xsn on which the form is based.
The built-in XML parser included in WSS first attempts to find the content type ID in the XML file, and, failing that, attempts to determine the content type based on the form template. So, for InfoPath forms, the built-in XML parser always fails its first check, and has to use the form template to determine content type.
For more information on how the XML parser determines content type, see this earlier post.
The program ID for InfoPath 2007 forms is included in the forms in the progId2 attribute of the <?mso-infopathdocument> processing instruction. In content type definitions, InfoPath maps this to the ProgID column using the PrimaryPITarget and PrimaryPIAttribute attributes.
So, for content types for InfoPath 2007 forms, the attributes for the ProgID <FieldRef> element are set to the following values:
PITarget = mso-infopathdocument
PIAttribute = InfoPath.Document
PrimaryPITarget = mso-infopathdocument
PrimaryPIAttribute = InfoPath.Document.2
Because WSS looks at the PrimaryPITarget and PrimaryPIAttribute pair first, the InfoPath.Document.2 attribute value is promoted to the ProgID column. The ProgID column determines which application WSS calls to open a selected file.
Written while listening to The Twilight Singers : Twilight as Played by the Twilight Singers
This is the final post in a five-part series on how to use the built-in XML parser in WSS V3 to promote and demote document properties in your XML files, including InfoPath 2007 forms.
Read part four here.
You can include namespace prefixes in the XPath expressions you use to specify the location of a document property. To use a namespace prefix, you must first define it in a custom XMLDocument element included in the content type definition.
The namespace for this XML node is:
The structure of the custom XMLDocument node is as follows:
Following is a list of the elements in the schema, and their definitions:
Namespaces The root element. Represents a collection of namespaces for use in XPath expressions.
For each namespace you specify, you must include the following values:
· prefix The prefix to use when designating this namespace.
· value The actual namespace for which you are specifying a prefix.
This schema describes optional XML you can include in a content type as custom information. For more information on including custom information in a content type, see this topic in the WSS V3 Beta 2 SDK.
This is the fourth in a five-part series on how to use the built-in XML parser in WSS V3 to promote and demote document properties in your XML files, including InfoPath 2007 forms.
There are two document properties the built-in XML parser examines to determine the content type to assign to an XML document when a user first uploads it to a given document library. The parser must determine which of the content types associated with the document library to assign the document before the parser can promote or demote document properties.
For a detailed examination of the process the parser performs to match a document’s content type with a content type associated with the document library, see part three.
The parser first looks for a processing instruction that specifies the document’s content type by content type ID. The location of this processing instruction is included in the definition for the content type ID column template. The processing instruction is named MicrosoftWindowsSharePointServices and contains an attribute named ContentTypeID that represent the ID of the document's content type.
Name="Content Type ID"
By default, all library list templates include a column that represents the content type ID.
Add this processing instruction to your XML document. Set the ContentTypeID attribute to the ID of the document’s content type.
<? MicrosoftWindowsSharePointServices ContentTypeID=”0x010101003D7907A1908011d082BD08005AA74F5E00A557E10DA69DBF4C8BE1E21071B08163”/>
The parser will fail to determine the content type in the following situations:
· The MicrosoftWindowsSharePointServices processing instruction isn’t present in the document
· The processing instruction does not specify a content type
· The specified content type is not associated with the document library
· No parent or child of the specified content type is associated with the document library
If the parser cannot identify the content type by content type ID, it performs a second check, detailed below.
Note The parser looks for the content type ID in whatever document location you specify in the field definition for the Content Type ID column on the document library. You can map the Content Type ID column to any processing instruction or XPath expression you choose. However, we recommend you adhere to the default mapping include in the content type ID column template definition. This minimizes the chance of having content types that specify a different location for this document property than the document library with which they are associated. Such a situation would lead to the XML parser looking in the wrong document location for the content type ID.
If the parser fails to determine a suitable content type for the document based on content type ID, the parser then looks for a processing instruction that contains the URL of the document template on which the document is based. The processing instruction is named mso-infoPathSolution that contains an attribute named href that represents the URL of the document template.
This column is included in the Form content type, and is added to a library anytime that content type is added to the library.
So, rather than include a content type ID, you can add this processing instruction to your XML document. Set the href attribute to the URI of the document template on which the document is based.
If the parser finds this processing instruction, it then examines the content types associated with the document library to determine if a content type has the same document template. If so, the parser assigns that content type to the document. If more than one content type associated with the document library has the same matching document template, the parser simply assigns the first content type it finds that matches.
Note The parser looks for the document template URL in whatever document location you specify in the field definition for the Document Template column on the document library. You can map the Document Template column to any processing instruction or XPath expression you choose. However, we recommend you adhere to the default mapping included in the document template column template definition. This minimizes the chance of having content types that specify a different location for this document property than the document library with which they are associated. Such a situation would lead to the XML parser looking in the wrong document location for the document template.
In the final installment of this series, I'll show how you can include namespace prefixes in the XPath expressions you use to specify the location of a document property.
This is the third in a five-part series on how to use the built-in XML parser in WSS V3 to promote and demote document properties in your XML files, including InfoPath 2007 forms.
In order for the built-in XML parser to determine the document’s content type, and thereby access the content type definition, the document itself must contain the content type as a document property. The parser looks for a special processing instruction in your XML documents to identify the document’s content type. You can include processing instructions that identify the document’s content type by content type, and/or document template.
When a user uploads an XML document to a document library, WSS V3 invokes the built-in XML parser. Before the parser can promote document properties, it must first determine the content type, if any, of the document itself.
The parser first looks at the Field element in the document library schema that represents the content type ID column on the document library. The parser examines the Field element for the location in the document where the content type ID should be stored. The parser then determines if the content type ID is indeed stored in the document at this location. If no content type ID is specified at that location, the parser assigns the default content type to the document. The parser then uploads the document and promotes any document properties accordingly.
If the document does contain a content type ID at the specified location, the parser determines if the content type with that ID is also associated with the document library. If it is, the parser uploads the document and promotes any document properties accordingly.
If the parser doesn't find an exact match, it examines ID's of the content types on the document library to determine if one or more are children of the document content type. If so, the parser assigns the closest child content type to the document. The parser then uploads the document and promotes any document properties accordingly.
Note The parser examines the list for content types that are children of the document content type because, in most cases, the document will have been assigned a site content type. In such cases, the matching list content type will be a child of the site content type.
If the parser finds no content type match at all, it then looks at the Field element in the document library schema that represents the document template column on the document library, if such a column is present. If the document library does contain a document template column, the parser examines the Field element for the location in the document where the document template should be stored. The parser then determines if the document template is indeed stored in the document at this location.
If the document does contain a document template, the parser compares the template with the document templates specified in each content type on the document library. If the parser finds a content type with the same document template as the document, the parser assigns that content type to the document. If there are multiple content types with the same document template as the document, the parser simply assigns the first such content type it finds. The parser then uploads the document and promotes any document properties accordingly.
Finally, if the parser cannot find a content type match, the parser assigns the default content type to the document. The parser then uploads the document and promotes any document properties accordingly.
The flow chart below illustrates the checks the parser performs to determine a document's content type.
For more information on how the parser promotes and demotes specific document properties, part two of this series.
One aspect of the parser's operation that bears emphasis is the fact the parser looks to the document library's content type and document template columns to determine where in the XML file to look for those matching document properties. Therefore, in order for promotion and demotion to work correctly, all content types on a given document library must contain content type and document template column definitions that specify the same location for those document properties as the document library columns. Otherwise, the parser will be looking in the wrong location within the document for those properties.
In the next entry, we’ll take a look at how you actually specify the content type of the document, inside that document itself.
This is the second in a five-part series on how to use the built-in XML parser in WSS V3 to promote and demote document properties in your XML files, including InfoPath 2007 forms.
When WSS V3 invokes the built-in XML parser to parse XML files, the parser uses the document's content type to determine which document properties map to which content type columns, and where those document properties are stored in the document itself. Therefore, to have WSS V3 use the built-in XML parser with your XML files, you must:
· Create a content type that includes the necessary parsing information. For each document property you want promoted and demoted, include a field definition that includes the name of the document property that maps to the column the field definition represents, and where the document property is stored in the document.
· Make sure that the content type ID is a document property that is demoted into the document itself. This ensures that the built-in XML parser can identify and access the correct content type for the document. (We’ll talk about this more in a later post.)
Document properties are promoted to and demoted from columns on the document library in which the document is stored. If the document is assigned a content type, these columns are specified in the content type definition. In the content type definition XML, each column included in the content type is represented by a FieldRef element.
Note Field elements represent columns that are defined for a site or list. FieldRef elements represent references to columns that are included in the content type. The FieldRef element contains column attributes that you can override for the column as it appears in this specific content type, such as the display name of the column, and whether it is hidden, or required on the content type. This information also includes the location of the document property to map to this column as it appears in the content type. This enables you to specify different locations for the document property that maps to the column in different content types.
Because of this, to specify the information the built-in XML parser needs to promote and demote a document property, you must edit the FieldRef element that represents the document property's corresponding column in the content type definition.
The figure below illustrations the actions the parser takes when an XML file is checked in to a document library. WSS V3 invokes the parser, which looks at the content type ID column to determine where in the document the document's content type ID is stored. The parser then looks inside the document for its content type at this location. The parser then examines the content type, to determine which FieldRef elements contain document property information. For each FieldRef element mapped to a document property, the parser looks for the document property at the location in the document specified in the matching FieldRef element. If the parser finds the document property at the specified location, it promotes that value to the matching column.
When an XML document is first uploaded to a document library, the built-in XML parser must first determine the content type of the document, and whether that content type is associated with the document library.
There are several attributes you can edit in a Field or FieldRef element to map that element to a document property and specify the location of the property in the document.
First, the Field or FieldRef element must contain an ID attribute that specifies the ID of the column in the document library. For example:
Next, add additional attributes to the Field or FieldRef element that specifies the location of the document property in the document. Document properties can be stored in either:
· The XML content of the document, or
· The processing instructions of the document.
The attributes you add to the Field or FieldRef element to specify the property location depends on whether the property is stored as XML content or processing instructions. These attributes are mutually exclusive; if you add an attribute that specifies a location in the XML content, you cannot also add attributes that specify a location in the processing instructions.
To edit a column’s field definition schema programmatically, use the SPField.SchemaXML object.
If you store the document property in the document as XML content, you specify an XPath expression that represents the location of the property within the document. Add a Node attribute to the Field or FieldRef element, and set it equal to the XPath expression. For example:
If you specify an XPath expression that returns a collection of values, you can also include an aggregation attribute in the Field or FieldRef element. The aggregation attribute specifies the action to take on the value set returned. This action can be either an aggregation function, or an indication of the particular element within the collection.
Possible values include the following:
· plaintext Converts node text content into plain text.
· first Specifies that property promotion and demotion be applied to the first element in the collection.
· last Specifies that property promotion and demotion be applied to the last element in the collection.
Because processing instructions need not be just XML, XPath expressions are insufficient to identify document properties stored in processing instructions. Instead, you must add a pair of attributes to the Field or FieldRef element that specify the processing instruction and processing instruction attribute you want to use as a document property:
· Add a PITarget attribute to specify the processing instruction in which the document property is stored in the document.
· Add a PIAttribute attribute to specify the attribute to use as the document property.
These attributes would instruct the parser to examine the following processing instruction and attribute for the document property value:
You can also add another pair of attributes, PrimaryPITarget and PrimaryPIAttribute. This attribute pair is optional. Like PITarget and PIAttribute, they work in unison to identify the location of the document property. However, if they are present, the built-in XML parser looks for the document property in the location they specify first. If there is a value at that location, the parser uses that value and ignores the PITarget and PIAttribute attributes. Only if the location specified by the PrimaryPITarget and PrimaryPIAttribute attributes returns a null value does the parser then look for the document property at the location specified by the PITarget and PIAttribute attribute pair.
If you specify the PrimaryPITarget and PrimaryPIAttribute attributes, you must also specify PITarget and PIAttribute attributes. The parser only uses the PrimaryPITarget and PrimaryPIAttribute attributes if the processing instruction attribute specified by the PITarget and PIAttribute pair does not exist in the document, not if that attribute exists but is null or empty.
In my next post, we’ll discuss how the XML parser determines a document’s content type in the first place.
I've just finished putting together a lot of information around how document parsers work within Windows SharePoint Services V3, including how to use the built-in XML parser, and how to create your own custom parsers for custom file types. This material won't be included in the WSS SDK until the next major update, so I figured I'd give you a preview of it here. For the next five posts, I'm going to be covering how to use the built-in XML parser in WSS V3 to promote and demote document properties in your XML files, including InfoPath 2007 forms.
So without further ado:
WSS V3 includes a built-in XML document parser you can use to promote and demote the properties included in your XML documents. Your XML files can adhere to any schema you choose. As long as your XML file meets the requirements listed below, WSS V3 automatically invokes the built-in XML parser whenever document property promotion or demotion is required.
(Property promotion refers to extracting document properties from a document, and writing those property values to the appropriate columns on the document library where the document is stored. Property demotion refers to taking column values from the document library where a document is stored, and writing those column values into the document itself.)
Using the built-in XML parser for your custom XML files helps ensure that your document metadata is always up-to-date and synchronized between the document library and the document itself. Users can edit document properties in the document itself, and have the property values on the document library automatically updated to reflect their changes. Likewise, users can update property values at the document library level, and have those changes automatically written back into the document itself.
For WSS V3 to invoke the built-in XML parser for an XML file, that XML file must meet the following requirements:
· The file must have an extension of .xml.
· The file must not be a WordML file. WSS V3 contains a separate built-in parser for WordML files; WSS V3 automatically invokes this parser for XML files created using WordML.
Additionally, for the XML parser to actually promote and demote document properties, the XML file should be assigned a content type that specifies where each document property is located in the document, and which content type column that property maps to. (We'll talk about that in a later entry in this series.)
The following is a brief overview of how the built-in parser operates:
When a user uploads an XML document, WSS V3 examines the document to determine if the built-in XML parser should be invoked. If the document meets the requirements, WSS V3 invokes the parser to promote the appropriate document properties to the document library.
Once invoked, the XML parser examines the document to determine the document content type. The parser then accesses the document's content type definition. The content type definition includes information about each column in that content type; this information can include:
· The document property that maps to a given column, if there is one
· The location where the document property is stored in the document itself
Using this information, the XML parser can extract each document property from the correct location in the document, and pass these properties to WSS V3. WSS V3 then promotes the appropriate document property to the matching column included in the content type.
Likewise, WSS V3 can also invoke the built-in XML parser to demote properties from the content type columns, on the document library, into the document itself. When WSS V3 invokes the demotion function of the parser, it passes the parser the document and the column values to be demoted into the document. Once again, the parser accesses the document's content type definition. The parser uses the content type definition to determine:
· Which document properties map to the column values passed to it for demotion
· The location of those document properties in the document
Using this information, the parser writes the column values into the applicable document property locations in the document.
For a document property to be demoted, the column to which it is mapped must be defined with its ReadOnly attribute set to "false".
In my next post, we'll discuss how to use content type to specify XML document properties. Stay tuned.
I've got another conceptual poster for download. This one deals with document parsers, and how Windows SharePoint Services uses them to promote and demote document properties.
The poster gives a quick (but stylish) overview of:
· How WSS uses your custom parser to promote and demote document properties for documents of your custom file type.
· How the built-in XML parser promotes and demotes document properties for XML files.
· What built-in parsers are included in WSS for specific file types.
Document parsers are something I'm hoping to have a lot more to say about soon. I'm putting the finishing touches on some topics for the WSS SDK dealing with them. Once I get those topics finished, I'll post some excerpts here. Stay tuned.
And this time around, I'm saving the poster as an attachment to this post. Not that the fine people at OfficeZealot aren't wonderful for hosting my other posters, but I hate to have to bug them all the time. And I'm curious to see if the attachment functionality actually works. The poster should be listed as an attachment at the end of this post. Click to download it. If you have any problems, please leave me a message in the comments section so I know things aren't working out.
So, a reader emailed me the other day, asking for more information on content type IDs: what they are, how to create your own, etc. Because he asked nicely, and because I like to keep both my readers happy, I decided to write up a quick overview of content type IDs.
The truth is, this is something I had hoped to get into the Beta 2 SDK, but the clock ran out. So his question gave me the perfect excuse to write the material up for the next refresh of the SDK. Consider this a preview then.
Because I’m planning on incorporating this material into the SDK, you’ll forgive me if I slip into my formal, developer documentation writing style.
<Authoritative SDK Voice>
Content type IDs uniquely identify the content type. Content type IDs are designed to be recursive. The content type ID encapsulates that content type’s “lineage”, or the line of parent content types from which the content type inherits. Each content type ID contains the ID of the parent content type, which in turn contains the ID of that content type’s parent, and so on, ultimately back to and including the System content type ID. By parsing the content type ID, you can determine which content types the content type inherits, and how two content types are related.
Windows SharePoint Services V3 uses this information to determine the relationship between content types, and for push down operations.
You can construct a valid content type ID using one of two conventions:
· Parent content type ID + two hexadecimal values
· Parent content type ID + “00” + hexadecimal GUID
There is one special case, that of the System content type, which has the content type ID of “0x”. The System content type is the sealed content type from which all other content types ultimately inherit.
For all other content types, you must use one of the above methods for constructing a valid content type ID.
Note that if you use the first method, the two hexadecimal values cannot be “00”.
A content type ID must be unique within a site collection.
Let’s examine each of these conventions in turn.
Windows SharePoint Services V3 uses the first method for generating content type IDs for the default content types that come included with the platform. For example, the content type ID of the Item content type, one of the most basic content types, is 0x01. This denotes that the Item content type is a direct child of System. The content type ID of the Document content type is 0x0101, and the Folder content type has a content type ID of 0x0120. By parsing these content type IDs, we can determine that both Document and Folder are direct children of Item, which in turn inherits directly from System:
In this way you can determine not only what content types a content type inherits from, but at which point two content types have common ancestors.
The figure below maps out the relationship of the four content types discussed above. In each, the unique portion of the content type ID is represented by blue text.
Windows SharePoint Services V3 employs the second content type ID generation convention when creating content type IDs for:
· Site content types you create based on other content types.
· List content types, which are copied to a list when you add a site content type to that list.
For example, if you have a content type with a content type ID of “0x010100D5C2F139-516B-419D-801A-C6C18942554D”, you would know that the content type was either:
· A site content type that is a direct child of the Document content type, or
· A list content type created when the Document site content type was added to a list.
In general, the first content type ID generation technique emphasizes brevity, in that it only takes two hexadecimal digits to denote a new content type. The second approach emphasizes uniqueness, as it includes a GUID to denote the new content type. Each approach is best in certain situations.
We recommend you use the GUID approach to identify any content types that are direct children of content types you did not create. In other words, use the GUID approach if the parent content type is:
· A default content type included in Windows SharePoint Services V3, such as Document.
· A content type developed by a third party.
That way, you are guaranteed that the content type ID is unique and will not be duplicated later by the developer of the parent content type.
Once you’ve uniquely identified a content type in this manner, however, you can use the first method to identify any children of that content type. In essence, the GUID used in your content type can act as a de facto namespace for your content type. Any children based on that content type can be identified by just two hexadecimal digits. Because the maximum length of a content type ID is finite, this approach maximizes the number of content type “generations” allowable.
Content type IDs have a maximum length of 512 bytes. Because two hexadecimal characters can fit in each byte, this gives each content type ID an effective maximum length of 1024 characters.
For example, suppose you wanted to create a new content type, myDocument, based on the default Windows SharePoint Services V3 content type Document. For the myDocument content type ID, you start with the Document content type ID, 0x0101, and append 00 and a GUID. This uniquely identifies the myDocument content type, guaranteeing Windows SharePoint Services won’t later add another default content type with the same content type ID (which would be possible, if you had only appended two hexadecimal digits). To generate content type IDs for any content types you derive from myDocument, however, you can simply append two hexadecimal digits to the myDocument content type ID. This keeps the length of the content type ID to a minimum, thereby maximizing the number of content type “generations’ allowable.
The figure below illustrates this scenario. Again, the unique portion of each content type ID is represented by blue text.
</Authoritative SDK Voice>
Now, the above information is probably most useful to developers working with the XML definition of content types. This way, if you’re looking at a content type ID in an XML file, or need to generate one for a content type definition file you’re writing, you’ll understand how to construct and parse them manually.
The SharePoint object model, on the other hand, includes methods to parser and compare content type IDs. Specifically, you can use the SPContentTypeID.Parent method to find the parent of a content type without having to parser the content type ID yourself. The SPContentTypeID object also contains several methods that enable you to compare content types by ID, and identify a common ancestor.
One last thing that might be of interest. If you want to take a look at actual content type IDs in WSS, here’s what you can do: navigate to the Content Type Gallery for a site. When you click on a content type, the URL to that content type contains a parameter, ctype, which is in fact the content type ID for that content type.
Written while listening to: The Replacements : Let It Be
Gotta love Beta documentation.
Turn out that some of the material I wrote in the WSS Beta 2 SDK concerning content types is not strictly technically accurate, in the sense that it’s dead wrong. Ahem. The problem came from the fact that I was documenting content types as they were initially designed, not necessarily as they were implemented.
Specifically, here are the three things I documented incorrectly in the WSS Beta 2 SDK:
· You create content types at the site level, and then apply them to the lists on the site (or on child sites). You do not create content types directly on the lists themselves.
· Content types can contain references to columns. You do not create columns directly within the content type itself.
· Child sites do not contain content type references back to site content types created on a parent site.
So as you read through the conceptual topics about content types, please keep this in mind. My apologies for the mistakes; they'll be corrected in the final version of the SDK.
Unfortunately, I also included this incorrect information in one of the content type technical posters I offered for download. So, if you've already downloaded the poster titled "Using Columns and Content Types to Organize and Mange Your Content in Windows SharePoint Services (version 3)", please download the corrected version.
I’ve attached the corrected content type poster below (at least, I have if the attachment functionality works. This is the first time I’ve used it). The guys at OfficeZealot, who are hosting the poster downloads, were also kind enough to upload the corrected poster, so the link in my original post should get you the corrected poster now as well.
And for a more complete discussion how content types and columns interact, see my earlier post right there.
Written while listening to Nellie McKay : Pretty Little Head (23 track version)
Today I want to address a piece of SharePoint terminology that confused me no end when I first started working on the products. So, as a service to beginning SharePoint programmers the world over, here’s a quick (and hopefully precise, if not definitive) overview of three terms that tend to be used to mean the same thing: column, field, and document property.
Columns on Sites and Lists
Basically, what all three terms refer to a specific piece of metadata on a SharePoint item.
In other words, this:
In the UI, these are called ‘columns’ because, well, that’s what they are displayed as: columns. Each piece of metadata you’re collecting for a list is represented as a column on that list (Whether the column is actually displayed on the list or not. Columns can be hidden.)
However, if you take a look under the hood, either in the SharePoint schemas or object model, you’ll find they’re called Fields. This is what they were called in V2, and for compatibility sake, that’s what they remain in V3. (Database columns tend to be called ‘fields’, so that might be where the term originally crept in.)
So far, that’s all pretty straightforward. But V3 adds some complexity (and correspondingly, much flexibility and power) with the addition of content types, and site columns. I’ve talked some about content types here. Site columns can be thought of as templates; you create the site column at the site level, then you can apply it to the various lists and sub-sites as you wish. Site columns are represented as <Field> elements in the site schema, and Field objects in the object model.
When you add a site column to a list, the column definition is copied locally to the list, as a list column. So, in the list schema, the list column is represented by a <Field> element in the list schema now. In the object model, it’s represented by a Field object.
Another important point to mention: when you add a site column to a list, the resulting list column has the same field ID as the site column. SharePoint uses this to track which list columns are “children” of a given site column. This enables you to make changes to a site column and propagate those changes out to all the list columns that are children of the site column.
You can also create columns at the list level. These columns only apply to the list on which they are created. You can think of them as one-offs. You can add list columns to content types on that list, but that's it. List columns are also represented as <Field> elements in the list schema, and SPField objects in the object model. Because they were created from scratch, though, they do not have a parent/child relationship with any other column.
Columns in Content Types
Here’s where it gets interesting:
If there’s certain item metadata you want to track in a content type, you include a column that represents that metadata. However, you cannot create a column in a content type; rather, you have to create the column, and then reference that column in the content type definition. Because of this, when you add a column to a content type, the content type schema doesn’t contain a <Field> element, it contains a <FieldRef> element. This is true of both site and list columns you add to content types.
The <FieldRef> element is a reference to a column defined elsewhere, either at the site or list level. In the field reference, you can override a subset of the column properties, such as:
· Display name
· XML promotion and demotion attributes
· Whether the field is read-only, required, or hidden
Changing these properties in the field reference only changes them as they apply to the specific content type that contains the field reference, of course.
Field references retain the same field ID as the column they reference.
If you create a content type based on a parent content type, be default all the columns in the parent are included in the child content type, as <FieldRef> elements.
Now, when you add a content type to a list, the columns referenced in that content type get copied locally onto the list as list columns. In other words, the columns referenced by the various <FieldRef> elements in the content type schema are copied onto the list schema as <Field> elements—again, with the child/parent relationship to the site column.
As mentioned earlier, when you add a list column to a list content type, it's added as a <FeildRef> in the list content type schema.
Therefore, columns are always represented by <Field> elements in site and list schemas, but always represented by <FieldRef> elements in content type schemas.
Field references in content types are represented by the SPFieldLink object in the SharePoint object model.
The term 'document property' is most often used in the context of talking about a particular piece of metadata you're interested in tracking for a document. That is, the particular column value for that document. The last modified date, for example. When you upload a bunch of documents and display the last modified date for each, you get a column of last modified date values, as in the screen shot above.
The document property might be something you're tracking solely at the document library level, or it might also be included in the document itself.
(In which case, WSS V3 includes functionality that enables you to promote and demote the document property, so the value in the document is always in synch with the value in the column.
Property promotion refers to extracting document properties from a document, and writing those property values to the appropriate columns on the document library where the document is stored. Property demotion refers to taking column values from the document library where a document is stored, and writing those column values into the document itself.
WSS includes several built-in document parsers that automatically promote and demote document properties for well-known file types. In addition, you can use the built-in XML parser to promote and demote properties from your custom XML files. Finally, WSS also includes a document parser interface, which enables you to build custom parsers that can promote and demote document properties from your custom file types.)
Hopefully, the figure below illustrates this relationship. You add the site column Author to a content type; in the content type schema, the column is represented by a <FieldRef> element. When you add the content type to a list, WSS adds the Author column as a <Field> element. Both elements have the same field ID as the Author site column. When you add the list column ItemNo to the list content type, WSS adds it as a <FieldRef> element, with the same field ID. For Document C, the actual values for those two columns are stored in the document itself, and also displayed in the columns on the list.
The Bottom Line
So, to review:
What are called columns in the user interface are referred to as fields in the schema and object model.
You can create columns at two levels: the site, and list levels. These columns are represented as <Field> elements in the site and list schema, and Field objects in the object model. List columns created when you add a site column to a list retain a child/parent relationship with the site column, and retain the same field ID as the site column.
You cannot create a column in a content type. When you add a column to a content type, it's added as a <FieldRef> in the content type schema. When you add a content type to a list, the columns referenced by the <FieldRef> elements in that content type schema are added to the list as <Field> elements.
Therefore, columns are always represented by <Field> elements in site and list schemas, and always represented by <FieldRef> elements in content type schemas.
Document properties usually just refer to a field as it applies to a specific document. The document property might be something you're tracking solely at the document library level, or it might also be included in the document itself.
Postscript: A Short Digression Concerning the SPContentType Object
In the SharePoint object model, the SPContentType object contains both a SPFieldLinkCollection and an SPFieldCollection object. But if columns in content types are represented by field references, how can you have a collection of fields in the content type? Because it's one of the ways we're making your life easier, that's why.
The SPFieldCollection in the SPContentType object enables developers an easy way to get a 'merged view' of a column's attributes, as they are in that content type. By merged view, I mean all the attributes of a field, merged with those attributes that have been overridden in the field reference. When you access a field through SPContentType.SPFieldCollection["myField"], WSS merges the field definition with the field reference and returns the resulting SPField object to you. That way, you don't have to look up a field definition, then look up all the attributes in the field definition overridden by the field reference for that content type. We do it for you.
Because of this, there's a 1-to-1 correlation between the items in the SPFieldLinkCollection and SPFieldCollection objects. For each SPFieldLink you add to a content type, we add an SPField object that represents the merged view of that column as it's defined in the content type. You cannot directly add or delete items from an SPFieldCollection object in an SPContentType object; trying to do so throws an error.
Written while listening to Nick Cave : Henry's Dream