0

I open file by asp core endpoint successfully:

        [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));
        }

The file is in the server local folder:

C:\inetpub\wwwroot\myProject\files

I want to do the same with network folder mounted as disk R:\:

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

But this do not works with error 500. I also can open file from R:\ directly by windows explorer with login & password. So how to get access to the network drive file?

1
  • Did you find any solution for this ?? I have same scenario where i need to access shared drive from .Net Core api ! its becoming headache now. Commented Nov 1, 2021 at 3:53

1 Answer 1

1

You'll need to get the network address which is mapped to R: Drive, then you can use it as the file/folder path in your code:

Since you require a password to access the files in this shared drive, you've got two options as explained in this SO answer

1: Set AppPool user

The "right" way to do this is to run the webserver's AppPool as the identity that can access the share. That way, the only credential storage is done securely in the IIS config (rather than in your code or in readable config files). Putting the webserver and fileserver in the same Windows domain (or different domains with trust) is the easiest way, but the "same username/password" thing should work there as well.

2: P/Invoke to WNetAddConnection2 This has a good implementation here 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;  
}  
Sign up to request clarification or add additional context in comments.

6 Comments

If I use 1st way. nslookup [myipaddress] gives me Non-existent domain. Also trying this way on web-server gives error at this step IIS AppPool\DefaultAppPool — can not find object.
Also trying to create user on web-server with same log/pass as at fileserver gives password policy error — it is too short/simple.
The user doesn't have to have the same log/pass as fileserver, just correct rights to access the fileserver
Where/how could be this done? In IIS my app pool is set as ApplicationPoolIdentity.
campuslogicinc.freshdesk.com/support/solutions/articles/… try selecting custom account and enter the username password you use for accessing network share. Also ensure this user as access to the website folder
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.