Sharepoint:如何通过Web服务上传包含分类法字段的元数据的文件

时间:2012-09-17 11:23:56

标签: sharepoint upload lookup taxonomy

作为SharePoint编码的新手,我被分配了一项任务,即创建一个原型代码来上传文件并设置该文件的字段值,该文件将在打开包含该文件的sharepoint页面时显示。

这必须从远程计算机而不是Sharepoint服务器本身完成,因此使用ShareNet的.Net对象是不可能的。

我很快就找到了如何通过Sharepoint Web Service Copy.asmx上传文件:

void UploadTestFile() {
        var file = @"C:\Temp\TestFile.doc";
        string destinationUrl = "http://mysharepointserver/Documents/"
                                 + Path.GetFileName(file);
        string[] destinationUrls = { destinationUrl };

        var CopyWS = new Copy.Copy();
        CopyWS.UseDefaultCredentials = true;
        CopyWS.Url = "http://mysharepointserver/_vti_bin/copy.asmx";

        CopyResult[] result;
        byte[] data = File.ReadAllBytes(file);

        FieldInformation mf1 = new FieldInformation {
            DisplayName = "title",
            InternalName = "title",
            Type = FieldType.Text,
            Value = "Dummy text"
        };

        FieldInformation mf2 = new FieldInformation {
            DisplayName = "MyTermSet",
            InternalName = "MyTermSet",
            Type = FieldType.Note,
            Value = "Test; Unit;"
        };

        CopyWS.CopyIntoItems(
                "+", 
                destinationUrls, 
                new FieldInformation[] { mf1, mf2 }, 
                data,
                out result);
}

此代码可以轻松地将任何文件上传到目标网站,但只使用信息填充“标题”字段。 MyTermSet字段中我添加了3个术语allready - Test,Unit和Page - 不会更新值“Test;”和“单位;” 作为Sharepoint的新手并且我没有掌握所有基础知识谷歌搜索告诉我,更新“文件”,“计算”或“查找”字段不适用于CopyIntoItems方法,而MyTermSet是分类法字段是 - 如果我是正确的 - 查找字段。

那么如何使用值“Test”更新MyTermSet?和“单位;” ?

我真的更喜欢如果某人有这样的示例代码。我已经遵循了几个提示链接,但我不是更明智的。我根本没有找到任何样本代码。

有没有人制作一个包装它的方法?或者从文件上载接收destinationUrl并更新术语集/分类字段的另一种方法。

1 个答案:

答案 0 :(得分:2)

将迄今为止发现的内容困惑在一起,我现在能够按照自己的意愿去做。但我真的希望能够动态获取Taxonomy字段GUID,而不必自己明确设置它们:

void UploadTestFile(string FileName, string DocLib, Dictionary<string, string> Fields = null) {

    //Upload the file to the target Sharepoint doc lib 
    string destinationUrl = DocLib + Path.GetFileName(FileName);
    string[] destinationUrls = { destinationUrl };

    var CopyWS = new Copy.Copy();
    CopyWS.UseDefaultCredentials = true;
    CopyWS.Url = new Uri(new Uri(DocLib), "/_vti_bin/copy.asmx").ToString();

    CopyResult[] result;
    var data = File.ReadAllBytes(FileName);
    CopyWS.CopyIntoItems(
            "+",
            destinationUrls,
            new FieldInformation[0],
            data,
            out result);

    if (Fields == null) return; //Done uploading 

    //Get the ID and metadata information of the fields 
    var list = new ListsWS.Lists();
    list.UseDefaultCredentials = true;
    var localpath = new Uri(DocLib).LocalPath.TrimEnd('/');
    var site = localpath.Substring(0, localpath.LastIndexOf("/")); //Get the site of the URL
    list.Url = new Uri(new Uri(DocLib), site + "/_vti_bin/lists.asmx").ToString(); //Lists on the right site

    FieldInformation[] fiOut;
    byte[] filedata;

    var get = CopyWS.GetItem(destinationUrl, out fiOut, out filedata);
    if (data.Length != filedata.Length) throw new Exception("Failed on uploading the document.");

    //Dictionary on name and display name
    var fieldInfos = fiOut.ToDictionary(x => x.InternalName, x => x);
    var fieldInfosByName = new Dictionary<string, FieldInformation>();
    foreach (var item in fiOut) {
        if (!fieldInfosByName.ContainsKey(item.DisplayName)) {
            fieldInfosByName.Add(item.DisplayName, item);
        }
    }

    //Update the document with fielddata - this one can be extended for more than Text and Note fields.  
    if (!fieldInfos.ContainsKey("ID")) throw new Exception("Could not get the ID of the upload.");

    var ID = fieldInfos["ID"].Value; //The ID of the document we just uploaded 

    XDocument doc = new XDocument(); //Creating XML with updates we need 
    doc.Add(XElement.Parse("<Batch OnError='Continue' ListVersion='1' ViewName=''/>"));
    doc.Element("Batch").Add(XElement.Parse("<Method ID='1' Cmd='Update'/>"));
    var methNode = doc.Element("Batch").Element("Method");

    //Add ID 
    var fNode = new XElement("Field");
    fNode.SetAttributeValue("Name", "ID");
    fNode.Value = ID;
    methNode.Add(fNode);

    //Loop each field and add each Field 
    foreach (var field in Fields) {

        //Get the field object from name or display name
        FieldInformation fi = null;
        if (fieldInfos.ContainsKey(field.Key)) {
            fi = fieldInfos[field.Key];
        }
        else if (fieldInfosByName.ContainsKey(field.Key)) {
            fi = fieldInfosByName[field.Key];
        }

        if (fi != null) {

            //Fix for taxonomy fields - find the correct field to update
            if (fi.Type == FieldType.Invalid && fieldInfos.ContainsKey(field.Key + "TaxHTField0")) {
                fi = fieldInfos[field.Key + "TaxHTField0"];
            }
            else if (fi.Type == FieldType.Invalid && fieldInfosByName.ContainsKey(field.Key + "_0")) {
                fi = fieldInfosByName[field.Key + "_0"];
            }


            fNode = new XElement("Field");
            fNode.SetAttributeValue("Name", fi.InternalName);
            switch (fi.Type) {
                case FieldType.Lookup:
                    fNode.Value = "-1;#" + field.Value;
                    break;
                case FieldType.Choice:
                case FieldType.Text:
                    fNode.Value = field.Value;
                    break;
                case FieldType.Note: //TermSet's  
                    var termsetval = "";

                    var terms = field.Value.Split(';');
                    foreach (var term in terms) {
                        termsetval += "-1;#" + term + ";";
                    }
                    fNode.Value = termsetval.TrimEnd(';');
                    break;
                default:
                    //..Unhandled type. Implement if needed.
                    break;
            }
            methNode.Add(fNode); //Adds the field to the XML 
        }
        else {
            //Field does not exist. No use in uploading. 
        }
    }

    //Gets the listname (not sure if it is the full path or just the folder name) 
    var listname = new Uri(DocLib).LocalPath;
    var listcol = list.GetListCollection(); //Get the lists of the site

    listname = (from XmlNode x 
                in listcol.ChildNodes 
                where x.Attributes["DefaultViewUrl"].InnerText.StartsWith(listname, StringComparison.InvariantCultureIgnoreCase) 
                select x.Attributes["ID"].InnerText).DefaultIfEmpty(listname).First();


    //Convert the XML to XmlNode and upload the data 
    var xmldoc = new XmlDocument();
    xmldoc.LoadXml(doc.ToString());
    list.UpdateListItems(listname, xmldoc.DocumentElement);
} 

然后我称之为:

var fields = new Dictionary<string, string>();
fields.Add("Test", "Dummy Text");
fields.Add("MrTermSet", "Page|a4ba29c1-3ed5-47e9-b43f-36bc59c0ea5c;Unit|4237dfbe-22a2-4d90-bd08-09f4a8dd0ada");
UploadTestFile(@"C:\Temp\TestFile2.doc", @"http://mysharepointserver/Documents/", fields);

我宁愿这样称呼:

var fields = new Dictionary<string, string>();
fields.Add("Test", "Dummy Text");
fields.Add("MrTermSet", "Page;Unit");
UploadTestFile(@"C:\Temp\TestFile2.doc", @"http://mysharepointserver/Documents/", fields);