0

I am working with the code from this tutorial to access files remotely C# NetworkConnection for file share or other remote communication

I can connect to the remote directory and access the files which are just .jpg images.

This is the code for accessing the images:

[HttpGet]
public ActionResult GetPhoto(string cpuNr, Int64 imageNameNr)
{
    string source = @"ipadress\photos";
    string imgPath = Path.Combine(path where the image is from the cpuNr and imageNameNr build toghether);

    FileContentResult result = null;

    using(var share = new NetworkConnection(source, new NetworkCredentials())
    {
        byte[] fileContent = System.IO.File.ReadAllBytes(imgPath);
        result = File(fileContent, "image/jpeg");
    }

    return result;
}

This works fine in most of the cases. But sometimes I get an error:

Network Error: System.ComponentModel.Win32Exception (0x80004005):
Error connecting to remote share.

The source couldn't be accessed. It doesn't mean that a specific image can't be always accessed, because sometimes it does and sometimes it doesn't.

Is there any way around this error, any fix, because I can't find anything that will help me further for finding the reason of this problem or a solution for it.

EDIT The same file, from the same path, with the same user, sometimes gets accessed normally, but sometimes not.

arianit ax
  • 187
  • 1
  • 3
  • 13
  • 1
    A deadlock issue maybe? Caused by EndpointProtection perhaps? Can you add a file scan exception for this folder and check? – LocEngineer Feb 11 '20 at 14:38
  • I don't think it has to do with EndpointProtection because the same file is sometimes accessible and sometimes not. It kinda happens by randomness. – arianit ax Feb 11 '20 at 14:40
  • The error message in your question here isn't present in the source code you linked to. – Uwe Keim Feb 11 '20 at 14:40
  • @UweKeim it is if you look in the github code – arianit ax Feb 11 '20 at 14:42
  • In addition, you should call [`WNetGetLastErrorA`](https://learn.microsoft.com/en-us/windows/win32/api/winnetwk/nf-winnetwk-wnetgetlasterrora) if the call to `WNetAddConnection2A` fails. This would help you figuring out the error details. – Uwe Keim Feb 11 '20 at 14:42
  • @UweKeim sorry, it should be "Error connecting to remote share"... the code you provided is in c++ – arianit ax Feb 11 '20 at 14:45
  • 1
    @arianitax that's not a tutorial. You don't need anything special to read anything from a file share, just use the correct path with any of the IO commands, eg `File.ReadAllBytes(@"\\myserver\someShare\someFile.png")` just works. – Panagiotis Kanavos Feb 11 '20 at 14:49
  • @arianitax the only reason for this code, is to impersonate a *different* account. Typically, there's no need for that - just make sure your application pool's account has permissions to that folder. If you use a local account, change it to a domain account. Even if that's not possible (why?), you can [impersonate an account already](https://learn.microsoft.com/en-us/dotnet/standard/security/impersonating-and-reverting). Which is a bad idea, because you have to store those credentials somewhere, introducing unnecessary security risks – Panagiotis Kanavos Feb 11 '20 at 14:54
  • 1
    Look at the first item in the [fallacies of distributed computing](https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing) for one possible. – Damien_The_Unbeliever Feb 11 '20 at 16:31
  • @PanagiotisKanavos the user can configure the path and the user. And then this part of code `var userName = string.IsNullOrEmpty(credentials.Domain) ? credentials.UserName : string.Format(@"{0}\{1}", credentials.Domain, credentials.UserName);` will do that switch local account <-> domain account. – arianit ax Feb 12 '20 at 06:31
  • 1
    That's not how file shares work. There's no need for switching between local and domain accounts, or a custom user - just add use a domain account for the app pool and give it permissions to the shares. The easy way is to create a domain group with all the accounts that need access to multiple shares and add *that* to the shares' permissions. As for providing the path, that's what `File.ReadAllBytes` already does - it accepts a UNC path. Just use the *correct* `imgPath`, eg `\\someserver\photos` or `\\10.0.0.123\photos` – Panagiotis Kanavos Feb 12 '20 at 08:15
  • @PanagiotisKanavos can you give me an example about this domain account for the app pool. Seems I am not getting you. – arianit ax Feb 12 '20 at 10:32
  • 1
    @arianitax here's a basic guide for how to change the identity used by your app's Application Pool in IIS: https://campuslogicinc.freshdesk.com/support/solutions/articles/5000713210-changing-identity-user-for-iis-application-pool .You need to set it to use a domain account whose password doesn't change. Or you can potentially use "Network Service", as that should have access to the fileshare. See https://support.microsoft.com/en-gb/help/4466942/understanding-identities-in-iis for more details. – ADyson Feb 12 '20 at 10:40
  • I already do it with Application Pool account. But I think for different reasons (network, package lose, firewall, etc.) sometimes the same directory, for a split second, can't be accessed. Therefore I need to work around this problem and reduce this issue as much as possible – arianit ax Feb 12 '20 at 15:39

1 Answers1

-1

this is a Windows limitation. While working with async, multiple requests get send while waiting for the previous respond. And windows blocks those request without. Changing my function call to sync in the JS file, from async, helped.

arianit ax
  • 187
  • 1
  • 3
  • 13
  • There's no such Windows limitation. File shares are used for several decades on file servers with thousands of users. The problem is the code itself – Panagiotis Kanavos Nov 25 '22 at 09:04
  • yes, it is. the windows server firewall will kick in and don't allow you access. we are talking about hundreds of requests at once. and when I changed to sync functions, where the next request doesn't happen before the previous respond is done, then it works. maybe my explanation is wrong but that's how it is – arianit ax Nov 25 '22 at 09:07
  • No it's not. The code was wrong 2 years ago and still is. You don't need any `NetworkConnection` to read a file from a file share. Just type the path. `we are talking about hundreds of requests at once.` that's not a lot. File servers server far, far more – Panagiotis Kanavos Nov 25 '22 at 09:07
  • If something works for **billions** of users for decades, what are the chances you just found a critical bug that would affect everybody? Every company, from small ones to multinationals, uses Windows file shares. That *does* mean several thousand concurrent requests, from every user working with a file stored on a server. Nobody's opening and closing connections for every operation though. The OS itself handles this. – Panagiotis Kanavos Nov 25 '22 at 09:12
  • I already mentioned this in my other comments. this was my scenario. I looked at this problem with the IT department and the firewall was blocking me. this is my solution and it worked for my case. why do you have a problem with it? it's 2 years since I fixed it and wanted to share my solution with people who might have the same issue. also, hundreds request was just an expression, sometimes it is 2 (which is the minimum) and sometimes it can go up to millions – arianit ax Nov 25 '22 at 09:16
  • That was an application bug, not a Windows problem. One caused by faulty business logic - you can impersonate user accounts in a web application, you don't need to open any connections. You don't even need any credentials, since the server already knows who's logged in. – Panagiotis Kanavos Nov 25 '22 at 09:22
  • I remember there was something official from microsoft about this or an article by some 3rd party who talked about this. I am not the only one with this problem – arianit ax Nov 25 '22 at 09:22
  • And finally, the application was blocked by network security devices, not Windows, because it was doing what malware does - hammer servers with different credentials. Any firewall would have blocked this without an explicit rule – Panagiotis Kanavos Nov 25 '22 at 09:23
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/249883/discussion-between-arianit-ax-and-panagiotis-kanavos). – arianit ax Nov 25 '22 at 09:23
  • `I am not the only one with this problem` where are those others then, for the last 30 years? – Panagiotis Kanavos Nov 25 '22 at 09:23
  • let me repeat it again: the credentials have nothing to do with this, they were the same for every request. I already was doing it the way you suggested me 2 years ago. I also don't need to mention the details of the location of the files I needed to access, because it's out of this topic (they were not stored in the server I accessed, the server was just like a middleware if I remember right). – arianit ax Nov 25 '22 at 09:33
  • p.s. LocEngineer has mentioned this in his comment. as I said, maybe not the best choice of words to describe the problem, but that's how I fixed this. – arianit ax Nov 25 '22 at 09:53
  • 1
    In case someone stumbles across this later, you do need a network connection to the file share since "Network Service" (who is the user a Windows service runs as) does not normally have access to network resources unless your program explicitly gets them (e.g. via the NetworkConnection class in the question). The problem is that the .Net application will request the connection for each GetPhoto HTTP Get request. The error code says that the connection is already authorized to a user and can't be authorized again until the last one is dropped. – DevLocus May 23 '23 at 18:39