【问题标题】:Access to file on network drive asp net core访问网络驱动器 asp net core 上的文件
【发布时间】:2020-08-20 14:13:46
【问题描述】:

我通过asp核心端点成功打开文件:

        [HttpGet("files/{fileName}")]
        public IActionResult GetFile(string fileName)
        {
            var filePath = _hostingEnvironment.ContentRootPath + "\\Files\\" + fileName;
            if (filePath == null) return NotFound();
            return PhysicalFile(filePath, MimeTypes.GetMimeType(filePath));
        }

文件在服务器本地文件夹中:

C:\inetpub\wwwroot\myProject\files

我想对安装为磁盘 R:\ 的网络文件夹执行相同的操作:

var filePath = "R:\\Files\\" + fileName;
R:\files

但这不适用于错误 500。 我也可以使用登录名和密码直接通过 Windows 资源管理器从R:\ 打开文件。 那么如何访问网络驱动文件呢?

【问题讨论】:

  • 你找到解决办法了吗??我有同样的场景,我需要从 .Net Core api 访问共享驱动器!现在变得头疼了。

标签: asp.net-core


【解决方案1】:

您需要获取映射到 R: Drive 的网络地址,然后您可以将其用作代码中的文件/文件夹路径:

由于您需要密码才能访问此共享驱动器中的文件,因此您有两个选项,如 SO answer 中所述

1:设置AppPool用户

执行此操作的“正确”方法是将网络服务器的 AppPool 作为 可以访问共享的身份。这样,唯一的凭证 存储在 IIS 配置中安全地完成(而不是在您的代码中) 或在可读的配置文件中)。将网络服务器和文件服务器放入 相同的 Windows 域(或具有信任的不同域)是 最简单的方法,但是“相同的用户名/密码”应该在那里工作 也是。

2: P/Invoke 到 WNetAddConnection2 这里有一个很好的实现How To Access Network Drive Using C#

using System;  
using System.ComponentModel;  
using System.Runtime.InteropServices;  
using System.Net; 
public class ConnectToSharedFolder: IDisposable  
{  
    readonly string _networkName;  
  
    public ConnectToSharedFolder(string networkName, NetworkCredential credentials)  
    {  
        _networkName = networkName;  
  
        var netResource = new NetResource  
        {  
            Scope = ResourceScope.GlobalNetwork,  
            ResourceType = ResourceType.Disk,  
            DisplayType = ResourceDisplaytype.Share,  
            RemoteName = networkName  
        };  
  
        var userName = string.IsNullOrEmpty(credentials.Domain)  
            ? credentials.UserName  
            : string.Format(@"{0}\{1}", credentials.Domain, credentials.UserName);  
  
        var result = WNetAddConnection2(  
            netResource,  
            credentials.Password,  
            userName,  
            0);  
  
        if (result != 0)  
        {  
            throw new Win32Exception(result, "Error connecting to remote share");  
        }  
    }  
  
    ~ConnectToSharedFolder()  
    {  
        Dispose(false);  
    }  
  
    public void Dispose()  
    {  
        Dispose(true);  
        GC.SuppressFinalize(this);  
    }  
  
    protected virtual void Dispose(bool disposing)  
    {  
        WNetCancelConnection2(_networkName, 0, true);  
    }  
  
    [DllImport("mpr.dll")]  
    private static extern int WNetAddConnection2(NetResource netResource,  
        string password, string username, int flags);  
  
    [DllImport("mpr.dll")]  
    private static extern int WNetCancelConnection2(string name, int flags,  
        bool force);  
  
    [StructLayout(LayoutKind.Sequential)]  
    public class NetResource  
    {  
        public ResourceScope Scope;  
        public ResourceType ResourceType;  
        public ResourceDisplaytype DisplayType;  
        public int Usage;  
        public string LocalName;  
        public string RemoteName;  
        public string Comment;  
        public string Provider;  
    }  
  
    public enum ResourceScope : int  
    {  
        Connected = 1,  
        GlobalNetwork,  
        Remembered,  
        Recent,  
        Context  
    };  
  
    public enum ResourceType : int  
    {  
        Any = 0,  
        Disk = 1,  
        Print = 2,  
        Reserved = 8,  
    }  
  
    public enum ResourceDisplaytype : int  
    {  
        Generic = 0x0,  
        Domain = 0x01,  
        Server = 0x02,  
        Share = 0x03,  
        File = 0x04,  
        Group = 0x05,  
        Network = 0x06,  
        Root = 0x07,  
        Shareadmin = 0x08,  
        Directory = 0x09,  
        Tree = 0x0a,  
        Ndscontainer = 0x0b  
    }  
}  

public string networkPath = @"\\{Your IP or Folder Name of Network}\Shared Data";  
NetworkCredential credentials = new NetworkCredential(@"{User Name}", "{Password}");  
public string myNetworkPath = string.Empty;

public byte[] DownloadFileByte(string DownloadURL)  
{  
    byte[] fileBytes = null;  
  
    using (new ConnectToSharedFolder(networkPath, credentials))  
    {  
        var fileList = Directory.GetDirectories(networkPath);  
  
        foreach (var item in fileList) { if (item.Contains("ClientDocuments")) { myNetworkPath = item; } }  
  
        myNetworkPath = myNetworkPath + DownloadURL;  
  
        try  
        {  
            fileBytes = File.ReadAllBytes(myNetworkPath);  
        }  
        catch (Exception ex)  
        {  
            string Message = ex.Message.ToString();  
        }  
    }  
  
    return fileBytes;  
}  

【讨论】:

  • 如果我使用第一种方式。 nslookup [myipaddress] 给了我Non-existent domain。在网络服务器上尝试this way 也会在这一步出现错误IIS AppPool\DefaultAppPool — 找不到对象。
  • 同时尝试使用与文件服务器相同的日志/密码在 Web 服务器上创建用户会导致密码策略错误——太短/太简单了。
  • 用户不必拥有与文件服务器相同的日志/通行证,只需正确的权限即可访问文件服务器
  • 在哪里/如何做到这一点?在 IIS 中,我的应用程序池设置为 ApplicationPoolIdentity。
  • campuslogicinc.freshdesk.com/support/solutions/articles/… 尝试选择自定义帐户并输入您用于访问网络共享的用户名密码。还要确保此用户可以访问网站文件夹
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 1970-01-01
  • 1970-01-01
  • 2011-10-24
相关资源
最近更新 更多