简体   繁体   English

如何在HTTP处理程序ashx中将文件上传到网络路径?

[英]How to upload file to network path in http handler ashx?

I tried to upload file to a network path with following codes for silverlight app: 我尝试使用以下Silverlight应用程序代码将文件上传到网络路径:

public void ProcessRequest (HttpContext context) 
{
  //.....
  using (FileStream fs = File.Create(@"\\Server\Folder\" + filename))            
 {
   byte[] buffer = new byte[4096];
   int bytesRead;
   while ((bytesRead = context.Request.InputStream.Read(buffer, 0, buffer.Length)) != 0)
   {
      fs.Write(buffer, 0, bytesRead);
   }
 }
}

It's working fine when I run it in debug mode with VS built-in web server. 当我使用VS内置的Web服务器在调试模式下运行它时,它工作正常。 At SL side, I call this handler with url like: 在SL端,我用url将此处理程序称为:

UriBuilder ub = new UriBuilder("http://localhost:38700/FileUpload.ashx");

Then I publish this app to local IIS and change the url to http://localhost/Mysite/FileUpload.ashx 然后,我将此应用程序发布到本地IIS,并将URL更改为http://localhost/Mysite/FileUpload.ashx

then run the app again. 然后再次运行该应用程序。 It won't work anymore, but no error. 它不再工作了,但是没有错误。

I guess it is because different credential to call File.Create. 我猜这是因为调用File.Create的凭据不同。 So I want to use specific credential in handler to put file to the destination. 所以我想在处理程序中使用特定的凭据将文件放置到目标位置。

How to use a credential for File.Create? 如何对File.Create使用凭据?

I believe you will need to impersonate a user. 我相信您将需要冒充用户。 The code below should do it. 下面的代码应该做到这一点。 Essentially, you gather the domain, user, and password and instantiate the ImpersonationMgr class. 本质上,您收集域,用户和密码并实例化ImpersonationMgr类。 Then call the BeginImpersonation method. 然后调用BeginImpersonation方法。 After that call the corresponding WriteFile method you wish. 之后,调用所需的相应WriteFile方法。 The WriteFile method will assert if impersonation is enabled. 如果启用了模拟,则WriteFile方法将断言。 You can follow similar patterns for other file methods such as delete and move. 您可以对其他文件方法(例如删除和移动)遵循类似的模式。

public class ImpersonationMgr : IDisposable

  [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType,
                                      int dwLogonProvider, out SafeTokenHandle phToken);

  [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  public static extern bool CloseHandle(IntPtr handle);

  private const int LOGON32_PROVIDER_DEFAULT = 0;
  private const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

  private readonly string userName = string.Empty;
  private readonly string domainName = string.Empty;
  private readonly string password = string.Empty;

  private SafeTokenHandle safeTokenHandle = null;
  private WindowsImpersonationContext impersonatedUser = null;

  public ImpersonationMgr(string userName, string domainName, string password)
  {
     this.userName = userName;
     this.domainName = domainName;
     this.password = password;
  }

  public void BeginImpersonation()
  {
     bool returnValue = LogonUser(userName, domainName, password, LOGON32_LOGON_NEW_CREDENTIALS,
                                  LOGON32_PROVIDER_DEFAULT, out safeTokenHandle);
     if (returnValue == false)
     {
        int ret = Marshal.GetLastWin32Error();
        throw new System.ComponentModel.Win32Exception(ret);
     }

     impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle());
  }

  private void AssertImpersonationIsEnabled()
  {
     if(safeTokenHandle == null || impersonatedUser == null)
     {
        throw new UnauthorizedAccessException("You must call the BeginImpersonation method before attempting file write access.");
     }
  }

  public void WriteFile(string pathToFile, string fileContents)
  {
     AssertImpersonationIsEnabled();
     using (FileStream fileStream = File.Open(pathToFile, FileMode.CreateNew))
     {
        using (StreamWriter fileWriter = new StreamWriter(fileStream))
        {
           fileWriter.Write(fileContents);
        }
     }
  }

  public void WriteFile(string pathToFile, byte[] fileContents)
  {
     AssertImpersonationIsEnabled();
     using (FileStream fileStream = new FileStream(pathToFile, FileMode.Create))
     {
        fileStream .Write(fileContents, 0, fileContents.Length);
        fileStream .Flush();          
     }
  }

  public void Dispose()
  {
     Dispose(true);
     GC.SuppressFinalize(this);
  }
}

UPDATE 更新

   public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
   {
      private SafeTokenHandle()
         : base(true)
      {
      }


      [DllImport("kernel32.dll")]
      [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
      [SuppressUnmanagedCodeSecurity]
      [return: MarshalAs(UnmanagedType.Bool)]
      private static extern bool CloseHandle(IntPtr handle);

      protected override bool ReleaseHandle()
      {
         return CloseHandle(handle);
      }
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 jQuery AJAX 和处理程序 (ashx) 上传文件不起作用 - File Upload with jQuery AJAX and Handler (ashx) not working HTTP处理程序不适用于CS文件,但适用于ASHX文件 - http handler doesn't work in cs file but works in ashx file 通过将文件上传到ASHX处理程序来实现SSE(服务器发送事件) - Implement SSE (Server Sent Events) with File Upload to ASHX Handler 使用jquery和handler(ashx)在上传文件中“找不到”错误 - 'Not found' error in upload file using jquery and handler(ashx) c# 如何使用 HTTP POST multipart/form-data 将文件上传到 ashx - c# How to upload file to ashx with HTTP POST multipart/form-data 如何将id参数传递给.ashx文件上传 - How to pass id parameter to .ashx file upload 如何在我的控制器(ASP.NET MVC)中调用Http Handler文件(.ashx)中定义的方法? - How can I call a method that's defined in an Http Handler file (.ashx) in my controller (ASP.NET MVC)? 如何从ashx处理程序文件中调用Java脚本函数 - How to call java script function from ashx handler file 如何测试附加文件的ASP NET ashx处理程序 - How to test ASP NET ashx Handler With File Attached 无法在.ashx处理程序中上传多个文件 - Unable to upload multiple files in .ashx handler
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM