[英]How to upload file to network path in http handler ashx?
我尝试使用以下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);
}
}
}
当我使用VS内置的Web服务器在调试模式下运行它时,它工作正常。 在SL端,我用url将此处理程序称为:
UriBuilder ub = new UriBuilder("http://localhost:38700/FileUpload.ashx");
然后,我将此应用程序发布到本地IIS,并将URL更改为http://localhost/Mysite/FileUpload.ashx
然后再次运行该应用程序。 它不再工作了,但是没有错误。
我猜这是因为调用File.Create的凭据不同。 所以我想在处理程序中使用特定的凭据将文件放置到目标位置。
如何对File.Create使用凭据?
我相信您将需要冒充用户。 下面的代码应该做到这一点。 本质上,您收集域,用户和密码并实例化ImpersonationMgr类。 然后调用BeginImpersonation方法。 之后,调用所需的相应WriteFile方法。 如果启用了模拟,则WriteFile方法将断言。 您可以对其他文件方法(例如删除和移动)遵循类似的模式。
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);
}
}
更新
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.