2

作为 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 - 测试、单元和页面 - 不会使用值“测试”更新;和“单位;”。
对 Sharepoint 非常陌生,而我没有掌握所有基本知识,谷歌搜索告诉我更新“文件”、“计算”或“查找”字段不适用于 CopyIntoItems 方法,并且 MyTermSet 作为分类字段是 - 如果我是正确的- 查找字段。

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

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

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

4

1 回答 1

2

将我迄今为止的发现拼凑起来,我现在可以做我想做的事了。但我真的希望能够动态获取分类字段 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);
于 2012-09-18T11:48:48.090 回答