【问题标题】:Sharepoint: How to upload files with metadata including Taxonomy fields through web servicesSharepoint:如何通过 Web 服务上传带有元数据的文件,包括分类字段
【发布时间】:2012-09-17 11:23:55
【问题描述】:

作为 SharePoint 编码的新手,我被分配了创建原型代码以上传文件并设置该文件的字段值的任务,该文件将在打开带有文件的共享点页面时显示。

这必须从远程计算机而不是 Sharepoint 服务器本身完成,因此无法使用 .Net 对象进行 Sharepoint。

我很快发现了如何通过 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);
}

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

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

如果有人对此有示例代码,我真的更愿意。我遵循了几个提示链接,但我并不聪明。我根本没有找到任何示例代码。

有没有人制作了一种包装所有内容的方法?或者从文件上传中获取destinationUrl并更新术语集/分类字段的另一种方法。

【问题讨论】:

    标签: sharepoint upload lookup taxonomy


    【解决方案1】:

    把我目前的发现拼凑起来,我现在可以做我想做的事了。但我真的希望能够动态获取分类字段 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);
    

    【讨论】:

    • 您是否能够填充字段名称中包含空格的分类元数据字段?例如,使用您的字段名称,那么我的问题是您可以毫无问题地更新“Mr TermSet”吗?我一直在尝试更新名称中包含空格的列。 Here is my similar question
    • 我现在没有环境来验证它,但是使用我的代码的人有带有空格和其他字符的字段。所以我相信它应该有效。所以 fields.Add("MrTermSet", "My Own Page|a4ba29c1-3ed5-47e9-b43f-36bc59c0ea5c") 应该可以工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多