3

SharePoint上のWebDavで問題が発生しています。ファイルとフォルダー構造のコピーと移動をサポートするために、.NETで優れたWebDavライブラリを作成しましたが、次の問題を回避できません。

.NET 4.0を使用しており、SharePoint2010に接続しています。

同じサイトコレクション内でコピーを実行すると、正常に機能します。

だからコピー

http://my-sps-server/sc1/folder1/file1.txt

http://my-sps-server/sc1/folder2/file1.txt

問題ありませんが

http://my-sps-server/sc1/folder1/file1.txt

http://my-sps-server/sc2/folder2/file1.txt

例外がスローされ、応答ステータスから、サーバーから409が返されました。興味深いことに、コピーする前に、フォルダ'folder2'が存在することを確認します。存在しない場合は、作成され、問題なく機能します。しかし、409応答の詳細は、パス「folder2」が存在しないことを示しています。

私は認証を検討してきました。ネットワークのデフォルトのクレデンシャルを使用しており、同じサイトコレクションにコピーしたり、フォルダーを作成したりする場合に正常に機能します。また、fiddlerを使用してhttpリクエストをエミュレートしており、同じ409応答が返されるため、.NETコードではない可能性があります。

SharePoint2010にバグがあるかどうか疑問に思っています。

誰かが光を当てるか、ここにいくつかのポインタを私に渡してくれることを願っていますか?

ソースからダウンロードを実行し、ターゲット(メモリ内)にアップロードすることになりました。コードは次のとおりです。

    private byte[] DownloadFile(Uri uri)
    {
        var request = GetRequest(uri);
        request.Method = "GET";
        request.Headers.Add("Translate", "f");

        var response = request.GetResponse();

        using (var stream = response.GetResponseStream())
        {
            return ReadFileBytes(stream, (int)response.ContentLength);
        }
    }

    private void UploadFile(Uri uri, byte[] bytes)
    {
        var request = GetRequest(uri);
        request.Method = "PUT";
        request.ContentLength = bytes.Length;
        request.Headers.Add("Translate", "f");

        using (var stream = request.GetRequestStream())
        {
            stream.Write(bytes, 0, bytes.Length);
            stream.Close();
        }

        request.GetResponse();
    }

    /// <summary>
    /// Reads data from a stream until the end is reached. The
    /// data is returned as a byte array. An IOException is
    /// thrown if any of the underlying IO calls fail.
    /// </summary>
    /// <param name="stream">The stream to read data from</param>
    /// <param name="initialLength">The initial buffer length</param>
    private static byte[] ReadFileBytes(Stream stream, int initialLength)
    {
        // If we've been passed an unhelpful initial length, just
        // use 32K.
        if (initialLength < 1)
        {
            initialLength = 32768;
        }

        byte[] buffer = new byte[initialLength];
        int read = 0;

        int chunk;
        while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0)
        {
            read += chunk;

            // If we've reached the end of our buffer, check to see if there's
            // any more information
            if (read == buffer.Length)
            {
                int nextByte = stream.ReadByte();

                // End of stream? If so, we're done
                if (nextByte == -1)
                {
                    return buffer;
                }

                // Nope. Resize the buffer, put in the byte we've just
                // read, and continue
                byte[] newBuffer = new byte[buffer.Length * 2];
                Array.Copy(buffer, newBuffer, buffer.Length);
                newBuffer[read] = (byte)nextByte;
                buffer = newBuffer;
                read++;
            }
        }

        // Buffer is now too big. Shrink it.
        byte[] ret = new byte[read];
        Array.Copy(buffer, ret, read);
        return ret;
    }

ダウンロードとアップロードにはパフォーマンスが低下することに注意してください。これは、大きなファイルでこれを行う場合に顕著になる可能性があります。

次のように、コピー操作全体を実行できます。

UploadFile(to、DownloadFile(from));

4

1 に答える 1

0

最近、この問題の解決にかなりの時間を費やしましたが、残念ながらどこにも行きませんでした。この件に関する古いStackExchangeの投稿がいくつかあり、結果はほとんど同じです。この競合の原因を実際に理解している人は誰もおらず、適切に解決した人もいないようです。あなたがまだ見つけていないように見えることを私があなたに言うことができるのは、ファイルを移動するために新しいドキュメントライブラリを作成した場合、これはしばしば起こらず、古いものでのみ起こるということです。これは、ある種の破損が問題の原因であることを示しています。

私たちが行ったことと、あなたにとって役立つかもしれないことは、SharePointオブジェクトモデルを使用して、あきらめてこれにアプローチすることです。私がこれのために書いたクラスは以下の通りです:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Diagnostics;

// todo: Lists
// DeleteListItem
// WriteFileMetadata
// AddListEntry

// Throttling on copy methods

namespace RE.SharePoint
{
    /// <summary>
    /// Class to encapsulate methods that interact with SharePoint Lists and Libraries
    /// </summary>
    public class ListsAndItems
    {
        /// <summary>
        /// Move items from a list to another list in the same site
        /// </summary>
        /// <param name="siteURL">URL to the host site collection</param>
        /// <param name="sourceList">URL to the source list</param>
        /// <param name="destinationList">URL to the destination list</param>
        /// <param name="retainMeta">Option to retain meta data (created/modified dates) or create new ones</param>
        /// <returns>Boolean value, true for successful copy, false for a failed copy</returns>
        public bool MoveListItems(string siteURL, string sourceList, string destinationList, bool retainMeta)
        {
            OnSharePointOpeningSite(siteURL);

            using (var site = new SPSite(siteURL))
            {
                OnSharePointOpenedSite(siteURL);

                using (var web = site.OpenWeb())
                {
                    OnSharePointGetRelativeURL(web.ServerRelativeUrl);

                    try
                    {
                        // Get your source and destination libraries
                        var source = web.GetList(web.ServerRelativeUrl + sourceList);
                        var destination = web.GetList(web.ServerRelativeUrl + destinationList);

                        OnSharePointSourceSet(source);
                        OnSharePointDestinationSet(destination);

                        // Get the collection of items to move, use source.GetItems(SPQuery) if you want a subset
                        SPListItemCollection items = source.Items;

                        // Get the root folder of the destination we'll use this to add the files
                        SPFolder folder = web.GetFolder(destination.RootFolder.Url);

                        OnSharePointProcessItem(items.Count, source.ToString(), destination.ToString());

                        var fileCount = 0;
                        // Now to move the files and the metadata
                        foreach (SPListItem item in items)
                        {
                            //Get the file associated with the item
                            SPFile file = item.File;

                            OnSharePointProcessFile(folder.Url + "/" + file.Name);

                            // Create a new file in the destination library with the same properties
                            SPFile newFile = folder.Files.Add(folder.Url + "/" + file.Name, file.OpenBinary(), file.Properties, true);

                            if (retainMeta)
                            {
                                SPListItem newItem = newFile.Item;
                                WriteFileMetaDataFiletoFile(item, newItem);
                            }

                            file.Delete();
                            SharePointRecycleBin.EmptyRecycleBinItem(site.ToString(), source.ToString(), file.Name);

                            fileCount++;
                        }

                        OnSharePointProcessList(fileCount, source.ToString(), destination.ToString());
                    }
                    catch (System.IO.FileNotFoundException fex)
                    {
                        OnError("Unable to set a location. Please check that paths for source and destination libraries are correct and relative to the site collection. \n\nSite URL: " 
                                    + siteURL + " \nSource List: " + sourceList + " \nDestination List: " + destinationList + "\n", false, fex);

                        return false;
                    }
                    catch (Exception ex)
                    {
                        OnError("General Exception: ", true, ex);

                        return false;
                    }

                    return true;
                }
            }
        }

        /// <summary>
        /// Move items from one SharePoint list to another in another site
        /// </summary>
        /// <param name="sourceSiteURL">The URL to the source site collection</param>
        /// <param name="sourceList">The URL to the source list</param>
        /// <param name="destinationSiteURL">The URL to the destination site collection</param>
        /// <param name="destinationList">The URL to the destination list</param>
        /// <param name="retainMeta">Option to retain meta data (created/modified dates) or create new ones</param>
        /// <returns>Boolean value, true for successful copy, false for a failed copy</returns>
        public bool MoveListItemsSiteToSite(string sourceSiteURL, string sourceList, string destinationSiteURL, string destinationList, bool retainMeta)
        {
            OnSharePointOpeningSite(sourceSiteURL);

            using (SPSite sourceSite = new SPSite(sourceSiteURL))
            {
                OnSharePointOpenedSite(sourceSiteURL);

                using (SPWeb sourceWeb = sourceSite.OpenWeb())
                {
                    OnSharePointGetRelativeURL(sourceWeb.ServerRelativeUrl);

                    try
                    {
                        // Get your source library
                        var source = sourceWeb.GetList(sourceWeb.ServerRelativeUrl + sourceList);

                        OnSharePointSourceSet(source);

                        // Get the collection of items to move, use source.GetItems(SPQuery) if you want a subset
                        SPListItemCollection items = source.Items;

                        int fileCount = 0;

                        OnSharePointOpeningSite(destinationSiteURL);

                        using (var destSite = new SPSite(destinationSiteURL))
                        {
                            OnSharePointOpenedSite(destinationSiteURL);

                            using (var destinationWeb = destSite.OpenWeb())
                            {
                                OnSharePointGetRelativeURL(destinationWeb.ServerRelativeUrl);

                                // get destination library
                                SPList destination = destinationWeb.GetList(destinationWeb.ServerRelativeUrl + destinationList);

                                OnSharePointDestinationSet(destination);

                                // Get the root folder of the destination we'll use this to add the files
                                SPFolder destinationFolder = destinationWeb.GetFolder(destination.RootFolder.Url);

                                OnSharePointProcessItem(items.Count, source.ToString(), destination.ToString());

                                // Now to move the files and the metadata
                                foreach (SPListItem item in items)
                                {
                                    //Get the file associated with the item
                                    SPFile file = item.File;

                                    // Add event handler
                                    OnSharePointProcessFile(destinationFolder.Url + "/" + file.Name);

                                    // Create a new file in the destination library with the same properties
                                    SPFile newFile = destinationFolder.Files.Add(destinationFolder.Url + "/" + file.Name, file.OpenBinary(),
                                                                                 file.Properties, true);

                                    if (retainMeta)
                                    {
                                        SPListItem newItem = newFile.Item;
                                        WriteFileMetaDataFiletoFile(item, newItem);
                                    }

                                    file.Delete();

                                    SharePointRecycleBin.EmptyRecycleBinItem(sourceSite.ToString(), source.ToString(), file.Name);

                                    fileCount++;
                                }
                                OnSharePointProcessList(fileCount, source.ToString(), destination.ToString());
                            }
                        }
                    }
                    catch (System.IO.FileNotFoundException fex)
                    {
                        OnError("Unable to set a location. Please check that paths for source and destination libraries are correct and relative to the site collection. \n\nSource Site: " 
                                    + sourceSiteURL + " \nSource List: " + sourceList + " \nDestination Site: " + destinationSiteURL + " \nDestination List: " + destinationList + "\n", false, fex);

                        return false;
                    }
                    catch (Exception ex)
                    {
                        OnError("General Exception: ", true, ex);

                        return false;
                    }

                    return true;
                }
            }
        }

        /// <summary>
        /// overwrites a list items meta data with meta data from another file
        /// </summary>
        /// <param name="sourceItem">The source item to take meta data from</param>
        /// <param name="destinationItem">The destination item to set meta data from the source item to</param>
        public static void WriteFileMetaDataFiletoFile(SPListItem sourceItem, SPListItem destinationItem)
        {
            destinationItem["Editor"] = sourceItem["Editor"];
            destinationItem["Modified"] = sourceItem["Modified"];
            destinationItem["Modified By"] = sourceItem["Modified By"];
            destinationItem["Author"] = sourceItem["Author"];
            destinationItem["Created"] = sourceItem["Created"];
            destinationItem["Created By"] = sourceItem["Created By"];

            destinationItem.UpdateOverwriteVersion();
        }


        #region Events

        internal void OnSharePointProcessFile(string itemPath)
        {           
            if (_sharePointProcessedFile == null) return;

            var e = new SharePointProcessFileEventArgs(itemPath);
            _sharePointProcessedFile(this, e);
        }

        internal void OnSharePointProcessItem(int itemCount, string source, string destination)
        {
            if (_sharePointProcessItem == null) return;

            var e = new SharePointProcessItemEventArgs(itemCount, source, destination);

            _sharePointProcessItem(this, e);
        }


        internal void OnSharePointProcessList(int itemCount, string source, string destination)
        {
            if (_sharePointProcessList == null) return;

            var e = new SharePointProcessListEventArgs(itemCount, source, destination);

            _sharePointProcessList(this, e);
        }


        internal void OnSharePointOpeningSite(string siteName)
        {
            if (_sharePointOpeningSite == null) return;

            var e = new SharePointOpeningSiteEventArgs(siteName);

            _sharePointOpeningSite(this, e);
        }

        internal void OnSharePointOpenedSite(string siteName)
        {
            if (_sharePointOpenedSite == null) return;

            var e = new SharePointOpenedSiteEventArgs(siteName);

            _sharePointOpenedSite(this, e);
        }

        internal void OnSharePointGetRelativeURL(string siteCollection)
        {
            if (_sharePointRelativeURL == null) return;

            var e = new SharePointWebRelativeURLEventArgs(siteCollection);

            _sharePointRelativeURL(this, e);
        }

        internal void OnSharePointDestinationSet(SPList destination)
        {
            if (_sharepointDestination == null) return;

            var e = new SharePointDestinationSetEventArgs(destination);

            _sharepointDestination(this, e);
        }

        internal void OnSharePointSourceSet(SPList source)
        {
            if (_sharepointSource == null) return;

            var e = new SharePointSourceSetEventArgs(source);

            _sharepointSource(this, e);
        }

        internal void OnError(string message, bool showException, Exception exception)
        {
            if (_sharePointOnError == null) return;

            var e = new SharePointOnErrorEventsArgs(message, showException, exception);

            _sharePointOnError(this, e);
        }

        private EventHandler<SharePointProcessFileEventArgs> _sharePointProcessedFile;
        private EventHandler<SharePointProcessListEventArgs> _sharePointProcessList;
        private EventHandler<SharePointOpeningSiteEventArgs> _sharePointOpeningSite;
        private EventHandler<SharePointOpenedSiteEventArgs> _sharePointOpenedSite;
        private EventHandler<SharePointWebRelativeURLEventArgs> _sharePointRelativeURL;
        private EventHandler<SharePointDestinationSetEventArgs> _sharepointDestination;
        private EventHandler<SharePointSourceSetEventArgs> _sharepointSource;
        private EventHandler<SharePointProcessItemEventArgs> _sharePointProcessItem;
        private EventHandler<SharePointOnErrorEventsArgs> _sharePointOnError;

        /// <summary>
        /// Event for handling exceptions
        /// </summary>
        public event EventHandler<SharePointOnErrorEventsArgs> SharePointOnError
        {
            add { _sharePointOnError += value; }
            remove { _sharePointOnError += value; }
        }

        /// <summary>
        /// Event for when a file is being processed
        /// </summary>
        public event EventHandler<SharePointProcessFileEventArgs> SharePointProcessFile
        {
            add { _sharePointProcessedFile += value; }
            remove { _sharePointProcessedFile += value; }
        }

        /// <summary>
        /// Event for when a site is attempting to open
        /// </summary>
        public event EventHandler<SharePointOpeningSiteEventArgs> SharePointOpeningSite
        {
            add { _sharePointOpeningSite += value; }
            remove { _sharePointOpeningSite -= value; }
        }

        /// <summary>
        /// Event for when a site has been successfully opened
        /// </summary>
        public event EventHandler<SharePointOpenedSiteEventArgs> SharePointOpenedSite
        {
            add { _sharePointOpenedSite += value; }
            remove { _sharePointOpenedSite -= value; }
        }

        /// <summary>
        /// Event for when source/destination and filecount are established and a copy is about to initiate
        /// </summary>
        public event EventHandler<SharePointProcessItemEventArgs> SharePointProcessItem
        {
            add { _sharePointProcessItem += value; }
            remove { _sharePointProcessItem -= value; }
        }

        /// <summary>
        /// Event for when a list has started processing
        /// </summary>
        public event EventHandler<SharePointProcessListEventArgs> SharePointProcessList
        {
            add { _sharePointProcessList += value; }
            remove { _sharePointProcessList -= value; }
        }

        /// <summary>
        /// Event for when a web relative URL has been retreived from the site collection name
        /// </summary>
        public event EventHandler<SharePointWebRelativeURLEventArgs> SharePointWebRelativeURL
        {
            add { _sharePointRelativeURL += value; }
            remove { _sharePointRelativeURL -= value; }
        }

        /// <summary>
        /// Event for when a destination location has been assigned
        /// </summary>
        public event EventHandler<SharePointDestinationSetEventArgs> SharePointDestinationSet
        {
            add { _sharepointDestination += value; }
            remove { _sharepointDestination -= value; }
        }

        /// <summary>
        /// Event for when a source location has been assigned
        /// </summary>
        public event EventHandler<SharePointSourceSetEventArgs> SharePointSourceSet
        {
            add { _sharepointSource += value; }
            remove { _sharepointSource -= value; }
        }

    #endregion 
    }
}

また、そのオプションが利用可能になったら、この投稿に報奨金を差し上げます...コミュニティの誰かがこの問題を解決する方法を知っているように、十分な時間が経過したことを願っています。

于 2012-09-04T22:49:43.573 に答える