通过IIS7在c#/asp.net网页中访问虚拟目录(映射驱动器)

12

我有两台服务器,A和B。

服务器A:Windows Server 2008R2;服务器B:Windows Server 2003。

网页使用4.0框架,用VS2013 Pro RC创建。

在服务器A上,我的asp.net/c#网页在IIS7上运行。在服务器B上,我有一个共享文件夹。

现在,我已经将这个共享文件夹从服务器B映射到服务器A,并且可以在桌面/Windows资源管理器中完全访问它,但是从网页访问该文件夹就是另一回事了。

为了访问该文件夹,我在IIS7中创建了一个虚拟文件夹,指向映射的驱动器。

如果该文件夹在同一台服务器A上,则会起作用,但由于它在不同的服务器B上,我收到以下错误消息:

找不到路径的一部分'L:\a\b\file.pdf'。现在路径是100%正确的,因为我已经检查过了。


以下是一些额外的调试信息:

找不到路径的一部分'L:\a\b\file.pdf'。

描述:在执行当前网页请求时发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源代码的更多信息。

异常详细信息:System.IO.DirectoryNotFoundException: 找不到路径的一部分'L:\a\b\file.pdf'。

源错误:

在当前网页请求执行期间生成了未处理的异常,可以使用下面的异常堆栈跟踪标识异常的起源和位置。

堆栈跟踪:

[DirectoryNotFoundException: 找不到路径的一部分'L:\a\b\file.pdf'。] System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +216 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options,

SECURITY_ATTRIBUTES secAttrs,String msgPath,Boolean bFromProxy,Boolean useLongPath)+2481 System.IO.FileStream..ctor(String path,FileMode mode,FileAccess access,FileShare share,Int32 bufferSize,FileOptions options,String msgPath,Boolean bFromProxy)+229
System.IO.FileStream..ctor(String path,FileMode mode,FileAccess access,FileShare share)+102
System.Web.HttpResponse.WriteFile(String filename,Boolean readIntoMemory)+166 Reloc.Client.Contracts.openLinkClick(Object sender,EventArgs e)in c:\Users\x\Documents\Visual Visual Studio2013\Projects\p\p\S\Listdoc.aspx.cs:230
System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e,Boolean causesValidation,String validationGroup)+1192
System.Web.UI.WebControls.GridViewRow.OnBubbleEvent(Object source, EventArgs e)+164 System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)+52
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)+3707


我认为这可能与权限或相关的问题有关,尝试了很多方法,但都没有成功。所以请在这里帮助我。提前感谢。

3个回答

11
如wata所建议,每个用户都有自己的映射驱动器。这意味着您的L:驱动器与您的应用程序池帐户的L:驱动器不同。
此外,除非您已更改应用程序池正在运行的帐户,否则它将无法访问其他服务器上的共享文件夹。最可能的是,您正在使用Active Directory域帐户登录两个服务器。如果是这样,您可能需要创建一个新的Active Directory域帐户作为应用程序池的标识。您可以将应用程序池标识更改为使用自己的域帐户进行开发/测试目的,但在生产系统中,这不是推荐的安全实践。
创建新的Active Directory“服务帐户”之后(为避免未来麻烦,请确保密码不会过期),您需要在IIS中更改应用程序池的标识。转到应用程序池,找到您的站点正在使用的应用程序池,选择它并选择右侧的高级设置,转到标识,并单击...按钮以设置自定义帐户,确保在用户名前缀加上域名:mydomain\myserviceusername。
您还需要授予服务帐户对Server B共享的访问权限。
现在,您需要使用您的服务帐户从服务器A创建一个持久映射驱动器到服务器B。请参阅this以获取详细信息,确保设置一个脚本,在重启后重新映射驱动器,使用如下命令:net use L: \\ServerB\sharedfolder /persistent:yes,确保此命令以您的服务帐户身份运行。您甚至可以在应用程序的Global.asax.cs Application_Start中首先运行此命令。如果您想避免本段落中的步骤麻烦,请使用wata的建议,使用完整的UNC路径而不是映射驱动器。现在,您的Web应用程序应该能够访问服务器B上的共享文件夹了。 :-)

感谢您详细的解释,这使得我们的问题更加清晰,我认为我们很快就能让它正常工作了,只需要等待管理员的一些权限。 - Mana

5
问题在于,如果您创建了一个映射的驱动器,则只有创建它的用户才能看到它。由于您的应用程序的IIS应用程序池可能在不同的用户下运行,因此该映射的驱动器对其来说是不可见的。(在不同的用户帐户下运行应用程序是一个很好的安全实践)
我建议采用以下方法:不要使用映射驱动器作为虚拟目录,而是尝试使用UNC路径。例如:创建一个名为“documents”的虚拟目录,将其映射到\\ServerB\a\b。然后,您应该能够通过“documents/file.pdf”访问您的文件。 请记住,应用程序的IIS应用程序池用户需要访问网络共享\\ServerB\以及您所需的子文件夹和文件。

对于需要查找已映射驱动器的 UNC(通用命名约定)的人,请在命令提示符中键入“net use”,参见https://dev59.com/h2Ei5IYBdhLWcg3wN6Nt。 - Tony L.

2

检查服务器上文件夹的权限,并确保站点的应用程序池可以访问它。


你能告诉我如何给网站的应用程序池授予权限,或者引导我去哪里阅读相关信息吗? - Mana
你是在说共享文件夹的权限吗? 我必须修改服务器A还是B上的权限? - Mana

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接