2010-12-15 28 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

相关问题