2010-12-15 53 views
3

我能夠在本地使用SQL Filestream,但是當我嘗試將文件上載到使用SQL身份驗證的遠程SQL服務器時,出現Access Denied異常。顯然,SQL文件流只適用於Windows身份驗證(集成安全性= true),而不適用於我們目前擁有的SQL身份驗證。SQL文件流身份驗證最佳做法

沒有人真的在生產環境中使用Windows身份驗證,所以我只想知道如何克服這個限制。最佳做法是什麼?

public static void AddItem(RepositoryFile repository, byte[] data) 
{ 
    using (var scope = new TransactionScope()) 
    { 
     using (var db = new MyEntities()) // DBContext 
     { 
      db.RepositoryTable.AddObject(repository); 
      db.SaveChanges(); 
     } 

     using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString)) 
     using (var cmd = new SqlCommand(string.Format("SELECT Data.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM dbo.RepositoryTable WHERE ID='{0}'", repository.ID), con)) // "Data" is the column name which has the FILESTREAM. Data.PathName() gives me the local path to the file. 
     { 
      cmd.Connection.Open(); 
      using (var reader = cmd.ExecuteReader()) 
      { 
       while (reader.Read()) 
       { 
        var path = reader.GetString(0); 
        var transactionContext = reader.GetSqlBytes(1).Buffer; 
        var fileStream = new SqlFileStream(path, transactionContext, FileAccess.Write); 

        fileStream.Write(contents, 0, contents.Length); // I get the error at this line. 
        fileStream.Close(); 
       } 
      } 
     } 

     scope.Complete(); 
    } 
} 
+0

你能告訴我們你得到異常的代碼嗎? – 2010-12-15 16:11:19

+4

「沒有人真正在生產環境中使用Windows身份驗證」我已經實現了以下所有情況(Windows服務,Web應用程序和桌面應用程序) – 2010-12-15 16:11:34

+0

@Phil Hunt - 我已經用我的代碼片段。當我嘗試將字節寫入文件時,出現錯誤。該過程顯然無法訪問該文件。 – tempid 2010-12-15 16:24:24

回答

3

您使用FILESTREAM時確實必須使用集成身份驗證:

FILESTREAM Storage in SQL Server 2008

您需要確保的Windows帳戶的生產應用程序運行在已經被添加爲SQL登錄服務器,並且已被授予與應用程序當前使用的SQL身份驗證帳戶相同的權限。

您還必須確保該帳戶具有寫入FILESTREAM容器的文件系統權限。

+0

這是否意味着我可以給一個Windows帳戶訪問sql容器和文件夾,並讓用戶在訪問該文件流時冒充該用戶 – Jake 2012-04-04 14:41:05

2

我正在使用SqlFileStream示例獲得類似的「拒絕訪問」消息。這讓我們難倒了好幾天。

一位同事提出了一種非常好的替代方法。不使用SqlFileStream,而是使用INSERT命令將文件字節直接寫入SQL服務器,並使用帶有字節值的參數。對於我們稱爲「的FileData」的列「ID」(一個GUID)和「字節」表,我會用這樣的:

Byte[] bytes = // assign your data here 

using (SqlConnection conn = new SqlConnection(connectionString)) { 
    SqlCommand insertCmd = new SqlCommand("INSERT INTO FileData (Id, Bytes) VALUES (@Id, @Bytes)", conn); 

    insertCmd.CommandType = System.Data.CommandType.Text; 
    insertCmd.Parameters.AddWithValue("@Id", Guid.NewGuid()); 
    insertCmd.Parameters.AddWithValue("@Bytes", bytes); 
    insertCmd.Transaction = conn.BeginTransaction(); 

    try { 
     insertCmd.ExecuteNonQuery(); 
     insertCmd.Commit(); 
    } 
    catch (Exception e) { 
     insertCmd.Transaction.Rollback(); 
    } 
} 

注意,一個SqlFileStream類不被使用。

+0

那麼您是如何讀取數據的?如果沒有SqlFileStream,我看不到如何讀取文件。 – runfastman 2015-03-18 19:46:28

+0

將文件數據轉換爲字節數組的方法有很多種。一種方法是使用'File'類:'Byte [] bytes = File.ReadAllBytes(fileName);' – 2015-03-24 05:24:38

相關問題