Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I have a content type in a library configured with a word document as a template, it is the default content type. When creating via the UI from New item entering information into the DIP sets values in the document via Quick Part Document Properties. These entries are reflected on the underlying SharePoint list item and in the body of the document.

If I re-open the document the changes in the DIP do not get reflected in the Document body.

If I create a document via code using the template file, set the list item field the list item properties are not reflected in the document at all. They can be found when I inspect the XML but they never get demoted into the body of the document.

Hashtable properties = new Hashtable
                            {
                                {"ApplicationNumber", "CP1234567"},
                                {"DealerName", "Jim Bob Harry"},
                                {"DealerFax", "094025566"},
                                {"CustFirstName", "Gustav"},
                                {"CustLastName", "Gustavisson"},
                                {"FPFCompany", "RFS"}
                            };
SPFolder rootFolder = list.RootFolder;
SPFile spFile = rootFolder.Files.Add(string.Format("{0}.docx", Guid.NewGuid()), Resources.DeclinedFaxTemplate, properties);

Any body got any pointers as to how we can try and ensure that the document and the list item properties are kept in sync?

share|improve this question
add comment

4 Answers 4

I've just made a small test of difference ways to create a word document in the file system and then use it to programatically create documents in a document library with properties.

Create not using SharePoint
Create document/template from scrach in Word. Add Custom properties. Add Quick Part using Field|DocProperty|Property. Save to file system

Result:
Properties showing in Quick Part: Value from source
Properties showing in DIP/File|Info: Value from program/SP

Create using contenttype in SharePoint save to file system
Go to Document library with properties. Click New Document(or your contenttype) button in Ribbon. Add Quick Part using Document Property|Property. Save to file system<

Result:
Properties showing in Quick Part: Value from program/SP
Properties showing in DIP/File|Info: Value from program/SP

Create using contenttype in SharePoint extract to file system
Go to Document library with properties. Click New Document(or your contenttype) button in Ribbon. Add Quick Part using Document Property|Property. Save to Document library. Use program to extract to file system

Result:
Properties showing in Quick Part: Value from program/SP
Properties showing in DIP/File|Info: Value from program/SP

Conclusion
So it seems that the important part is to use SharePoint to create the document based on your contenttype, so that it gets the properties in the right way.

I also ran a test creating the documents in SP programatically, extracting them from SP into file system programatically and then opening them in word. And the result was the exact same as opening directly from SP. So if SP is allowed to create the properties in the first place it seems it's capable of maintaining it without help from the client program.

Test performed on SP2010 Enterprise. Documents create using Word 2010 as .docx files.

This is the code used to extract the document in the last test:

using System.IO;
using Microsoft.SharePoint;

namespace ExtractDocument
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var site =new SPSite("http://sp2010"))
            using (var web = site.OpenWeb())
            {
                var doclib = web.GetList("MyDocLib") as SPDocumentLibrary;
                foreach (SPFile source in doclib.RootFolder.Files)
                {
                    File.WriteAllBytes(string.Format("C:\\testdocs2\\{0}", source.Name), source.OpenBinary());
                }
            }
        }
    }
}

And this is the code used to create documents based on the content from the file system:

using System;
using System.Collections;
using System.IO;
using Microsoft.SharePoint;

namespace GenerateDocuments
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var site = new SPSite("http://sp2010"))
            using (var web = site.OpenWeb())
            {
                var doclib = web.GetList("MyDocLib") as SPDocumentLibrary;
                foreach (var sourceName in Directory.GetFiles("C:\\testdocs"))
                {
                    var source = new FileInfo(sourceName);
                    Console.WriteLine(source.Name);
                    doclib.RootFolder.Files.Add(source.Name, File.ReadAllBytes(sourceName), new Hashtable { { "Property1", "From Create" }, { "Property2", "From Create" } });
                }
            }

        }
    }
}
share|improve this answer
    
Could you please post a sample of the code used to create the document programatically? –  GavinB Apr 9 '12 at 20:53
    
My create code was very based on your sample, but I've added both my programs to my answer –  Per Jakobsen Apr 10 '12 at 6:46
add comment

I believe Property promotion and demotion will only occur when a document is uploaded or downloaded via the SP web UI or via WebDav (folder open in Windows Explorer for example).

share|improve this answer
add comment

We had the same problem, there are 2 things 2 keep in mind:

Fields in a word file use the SourceID property of a field, if that field is created using XML in a feature and the source id is not set in the XML, sharepoint will regenerate it. So a template created on Farm A (DEV) will not work on System B (PRD), seeing as the SourceID will be different (usually a GUID, i keep it the same as the actual field ID)

SharePoint does not always actually update the word file when programmatically changing a field on the listitem / adding an item. You can to do this yourself using Word Automation Services.

share|improve this answer
add comment

Here is 'my tuppence worth':

From my experience (in certain scenarios) SPFileCollection.Add Method (String, Byte(), Hashtable) (or any other SPFileCollection.Add overload with Hashtable) can fail to update document properties.

I had similar issue while adding files to library using similar code (like in question above). After some time I ended with this:

var file = destinationFolder.Files.Add(strDestUrl, binFile, true); 
file.Item["MyField1"] = MyFieldValue1;
file.Item["MyField2"] = MyFieldValue2;
...
file.Item.SystemUpdate(false); 

This code first creates document and then it changes document properties. SystemUpdate is used to avoid multiple versions.

I really don't recall exact scenario when SPFileCollection.Add+Hashtable failed me (it was more then a year ago) but since then I am using above approach in all of my projects.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.