1

Visual Studio で生成されたサービス参照によってプロキシされるODataサービスを使用して、SharePoint 2010 および 2013 にドキュメントをアップロードします。ListData.svcこのタスクを実行するためのコードは、以下の C# スニペットに似ています。

public static void Upload<T>(string libraryName, string localFilePath, string targetLibraryRelativePath, T document)
{
    string fullLibraryPath = ContextFactory.ROOT + LibraryName + targetLibraryRelativePath);
    var ctx = ContextFactory.GetODataContext();
    FileInfo fi = new FileInfo(localFilePath);
    document.Path = fullLibraryPath ;
    document.Name = fi.Name;
    document.ContentType = "Document";
    var mimeType = DeriveMIMEType(localFilePath);
    using (FileStream sourceFile = System.IO.File.Open(localFilePath, FileMode.Open, FileAccess.Read))
    {
        ctx.AddObject(libraryName, document);
        ctx.SetSaveStream(document, sourceFile, true, mimeType, fullLibraryPath + "/" + document.Name);
        ctx.SaveChanges();
    }
}

最近、新しいビジネス要件が浮上しました。それは、ドキュメントの複製がライブラリに入らないようにすることです。私の頭に浮かんだ最初のアプローチは、必須の一意の値を持つ新しい列を導入し、そこに MD5 ハッシュのようなものを配置することでした:

document.MD5 = CalculateMD5Hash(File.ReadAllBytes(sourceFile));

同じ MD5 ハッシュを持つ新しいアップロードが試行された場合、サービスは一意のハッシュ列値の制約により、ドキュメント コンテンツの重複がライブラリに到達するのを防ぐ必要があると予想しました。

私の期待は部分的にしか正しくありませんでした.サービスは実際にそのような試みで例外をスローしますが、重複したコンテンツはアップロードされますが、オリジナルの属性がなくdocument、ドキュメントライブラリの完全性を損なう.

実装を少し変更し、ドキュメント ライブラリに同じ MD5 ハッシュ値が存在するかどうかを確認してから呼び出すことは問題ではありませんが、これを呼び出すSetSaveStreamに、MD5 ハッシュ値列の一意の制約を宣言する目的を完全に無効にする過度の努力のように感じます。

私の質問は次のとおりです。ここで何かが欠けているのでしょうか。ドキュメント ライブラリに矛盾したアイテムを配置するというペナルティなしに、システムがドキュメント コンテンツの一意性要件を満たすようにする方法はありますか?

4

1 に答える 1

1

現時点で私が考えることができる最良の選択肢は次のとおりです。

  1. ドキュメントを追加しようとする前に、ライブラリにMD5ハッシュが存在することを確認します(OPですでに提案したように):

    var md5 = GetMd5Hash(File.ReadAllBytes(fi.FullName));
    
    // check that the MD5 hash doesn't exist in the library
    if (ctx.Test.Where(i => i.MD5 == md5).Count() == 0)
    {
        try
        {
            document.Path = fullLibraryPath;
            document.Name = fi.Name;
            document.ContentType = "Document";
            var mimeType = DeriveMIMEType(localFilePath);
            using (FileStream sourceFile = System.IO.File.Open(localFilePath, FileMode.Open, FileAccess.Read))
            {
                ctx.AddObject(libraryName, document);
                ctx.SetSaveStream(document, sourceFile, true, mimeType, fullLibraryPath + "/" + document.Name);
                ctx.SaveChanges();
            }
        }
        catch (DataServiceRequestException)
        {
            // TODO: log the exception
        }
    }
    
  2. try{...}catch{...}ステートメントを使用して例外をキャッチし、追加されたアイテムを削除します。

    using (FileStream sourceFile = System.IO.File.Open(localFilePath, FileMode.Open, FileAccess.Read))
    {
        ctx.AddObject(libraryName, document);
        ctx.SetSaveStream(document, sourceFile, true, mimeType, fullLibraryPath + "/" + document.Name);
        try
        {
            ctx.SaveChanges();
        }
        catch (Exception)
        {
            _ctx.DeleteObject(document);
            _ctx.SaveChanges();
            // TODO: log the exception
        }
    }
    
于 2013-02-09T00:16:35.933 に答える