asp.net file network-shares

asp.net - File.Exists que devuelve falso de un recurso compartido de red



network-shares (4)

He estado trabajando en un proyecto de ASP.NET que guardará los archivos cargados en un recurso compartido de red. Pensé que podría usar un directorio virtual y estar bien, pero he tenido problemas con los permisos de Directory.CreateDirectory.

Pude subir archivos, así que decidí cambiar mi código para colocar todo en un solo directorio, sin embargo, esto requiere que utilice File.Exists para evitar sobrescribir duplicados.

Ahora que tengo todo mi código actualizado, he descubierto que no importa lo que haga, File.Exists siempre devuelve falso (El archivo definitivamente existe) cuando pruebo contra el recurso compartido de red.

¿Algunas ideas? Estoy llegando al final de mi cuerda con las acciones de red.


File.Exist no comprueba realmente la existencia de un archivo. En su lugar, comprueba la existencia de archivos a los que tiene acceso en cierta medida. Si sabe que el archivo existe, el problema probable es que no tiene acceso a él.


Quizás su código que se está ejecutando (es decir, el código del servidor ASP.NET) se está ejecutando como un usuario (por ejemplo, el usuario de IIS) que no tiene permiso para acceder a ese recurso compartido de red.

Creo que se supone que IIS no debe ejecutarse como un usuario altamente privilegiado, que de forma predeterminada tiene permiso para ver recursos compartidos en otras máquinas.


Recientemente trabajé en un proyecto muy similar en el que guardo archivos en un recurso compartido de red. Las dos computadoras están en la misma subred, pero no están controladas por el controlador de dominio, por lo que cada computadora tiene sus propios usuarios.

Creé un usuario con el mismo nombre de usuario y contraseña en ambas computadoras. Luego creé un recurso compartido de red y configuré la carpeta / permisos compartidos para permitir la lectura y escritura para el usuario.

Luego creé la siguiente clase para administrar la suplantación:

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Security.Principal; using System.Security.Permissions; using System.Text; namespace MyProject.Business.Web { public class SecurityManager { #region DLL Imports [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public extern static bool CloseHandle(IntPtr handle); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); #endregion public string Domain { get; set; } public string UserName { get; set; } public string Password { get; set; } private WindowsImpersonationContext m_CurrentImpersonationContext; [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] public void StartImpersonation() { const int LOGON32_PROVIDER_DEFAULT = 0; const int LOGON32_LOGON_INTERACTIVE = 2; IntPtr tokenHandle = IntPtr.Zero; IntPtr dupeTokenHandle = IntPtr.Zero; // obtain a handle to an access token bool wasLogonSuccessful = LogonUser(UserName, Domain, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle); if (!wasLogonSuccessful) throw new Exception(String.Format("Logon failed with error number {0}", Marshal.GetLastWin32Error())); // use the token handle to impersonate the user WindowsIdentity newId = new WindowsIdentity(tokenHandle); m_CurrentImpersonationContext = newId.Impersonate(); // free the tokens if (tokenHandle != IntPtr.Zero) CloseHandle(tokenHandle); } public void EndImpersonation() { m_CurrentImpersonationContext.Undo(); } } }

Luego en la página ASP.NET hice lo siguiente:

SecurityManager sm = new SecurityManager(); sm.UserName = ConfigurationManager.AppSettings["UserFileShareUsername"]; sm.Password = ConfigurationManager.AppSettings["UserFileSharePassword"]; sm.StartImpersonation(); if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath); File.Move(sourcePath, destinationPath); sm.EndImpersonation();


Usé el mismo código, pero mi clase implementó la interfaz IDisposable y agregué el método Deshacer () al método Dispose (). Este código funciona bien, si eres el único desarrollador que lo usa y siempre harás las cosas de la manera correcta, ¿verdad?