Файл.Существует, возвращающий false из общего сетевого ресурса

StackOverflow https://stackoverflow.com/questions/401284

  •  03-07-2019
  •  | 
  •  

Вопрос

Я работал над проектом ASP.NET, который будет сохранять загруженные файлы в общий сетевой ресурс.Я подумал, что могу просто использовать виртуальный каталог и все будет в порядке, но у меня возникли проблемы с разрешениями для каталога.CreateDirectory.

Я смог загрузить файлы, поэтому решил изменить свой код, чтобы поместить все в один каталог, однако для этого мне нужно использовать File .Существует, чтобы избежать перезаписи дубликатов.

Теперь, когда я обновил весь свой код, я обнаружил, что независимо от того, что я делаю, File.Exists всегда возвращает false (файл определенно существует) при тестировании с общим сетевым ресурсом.

Есть какие-нибудь идеи?Я подхожу к самому концу своей карьеры с сетевыми ресурсами.

Это было полезно?

Решение

Я совсем недавно работал над очень похожим проектом, где я сохраняю файлы в общий сетевой ресурс.Эти два компьютера находятся в одной подсети, но не управляются контроллером домена, поэтому у каждого компьютера есть свои пользователи.

Я создал пользователя с одинаковым именем пользователя и паролем на обоих компьютерах.Затем я создал общий сетевой ресурс и установил права доступа к папке / общему ресурсу, чтобы разрешить пользователю чтение и запись.

Затем я создал следующий класс для управления олицетворением:

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

Затем на странице ASP.NET Я сделал следующее:

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();

Другие советы

File.Exist на самом деле не проверяет наличие файла.Вместо этого он проверяет наличие файлов, к которым у вас есть некоторый доступ.Если вы знаете, что файл существует, скорее всего, проблема в том, что у вас нет к нему доступа.

Возможно, ваш код, который запущен (т. е.ASP.NET серверный код) выполняется от имени пользователя (например,пользователь IIS), у которого нет прав доступа к этому сетевому ресурсу.

Я думаю, что IIS не должен запускаться как пользователь с высокими привилегиями, который по умолчанию имеет разрешение на просмотр общих ресурсов на других компьютерах.

Я использовал почти тот же код, но мой класс реализовал интерфейс IDisposable и добавил функцию Undo() к методу Dispose().Этот код работает нормально, если вы единственный разработчик, использующий его, и вы всегда будете делать все правильно, не так ли?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top