我正在尝试将一个大文件上传到Generic Handler FileUpload.ashx。
我用Fiddler数据检查它以正确的方式到达服务器。但我无法在服务器端取得成功。
我尝试了很多方法,但我无法将数据存储在HttpContext中。
我尝试过旧的
context.Request.Files[0];
context.Request.Params["file"]
context.Request["file"];
和其他一些事情,现在我很困惑。在简单的HTML中只设置类型文件并使用上面的第一个方法输入,这里复杂吗?我是否必须为内容编写自己的解析器。有没有更简单的方法?
public void ProcessRequest(HttpContext context)
{
// what to do here
}
任何人都可以为客户端和服务器端提供样本
顺便说一下,我的客户端是WinRt,服务器端是.Net 4.5
答案 0 :(得分:2)
您可能想要检查他们在此项目中的表现:
https://github.com/maxpavlov/jQuery-File-Upload.MVC3
以下是处理上传文件接收的主要代码:
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
namespace jQuery_File_Upload.MVC3.Upload
{
/// <summary>
/// Summary description for UploadHandler
/// </summary>
public class UploadHandler : IHttpHandler
{
private readonly JavaScriptSerializer js;
private string StorageRoot
{
get { return Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/Files/")); } //Path should! always end with '/'
}
public UploadHandler()
{
js = new JavaScriptSerializer();
js.MaxJsonLength = 41943040;
}
public bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext context)
{
context.Response.AddHeader("Pragma", "no-cache");
context.Response.AddHeader("Cache-Control", "private, no-cache");
HandleMethod(context);
}
// Handle request based on method
private void HandleMethod(HttpContext context)
{
switch (context.Request.HttpMethod)
{
case "HEAD":
case "GET":
if (GivenFilename(context)) DeliverFile(context);
else ListCurrentFiles(context);
break;
case "POST":
case "PUT":
UploadFile(context);
break;
case "DELETE":
DeleteFile(context);
break;
case "OPTIONS":
ReturnOptions(context);
break;
default:
context.Response.ClearHeaders();
context.Response.StatusCode = 405;
break;
}
}
private static void ReturnOptions(HttpContext context)
{
context.Response.AddHeader("Allow", "DELETE,GET,HEAD,POST,PUT,OPTIONS");
context.Response.StatusCode = 200;
}
// Delete file from the server
private void DeleteFile(HttpContext context)
{
var filePath = StorageRoot + context.Request["f"];
if (File.Exists(filePath))
{
File.Delete(filePath);
}
}
// Upload file to the server
private void UploadFile(HttpContext context)
{
var statuses = new List<FilesStatus>();
var headers = context.Request.Headers;
if (string.IsNullOrEmpty(headers["X-File-Name"]))
{
UploadWholeFile(context, statuses);
}
else
{
UploadPartialFile(headers["X-File-Name"], context, statuses);
}
WriteJsonIframeSafe(context, statuses);
}
// Upload partial file
private void UploadPartialFile(string fileName, HttpContext context, List<FilesStatus> statuses)
{
if (context.Request.Files.Count != 1) throw new HttpRequestValidationException("Attempt to upload chunked file containing more than one fragment per request");
var inputStream = context.Request.Files[0].InputStream;
var fullName = StorageRoot + Path.GetFileName(fileName);
using (var fs = new FileStream(fullName, FileMode.Append, FileAccess.Write))
{
var buffer = new byte[1024];
var l = inputStream.Read(buffer, 0, 1024);
while (l > 0)
{
fs.Write(buffer, 0, l);
l = inputStream.Read(buffer, 0, 1024);
}
fs.Flush();
fs.Close();
}
statuses.Add(new FilesStatus(new FileInfo(fullName)));
}
// Upload entire file
private void UploadWholeFile(HttpContext context, List<FilesStatus> statuses)
{
for (int i = 0; i < context.Request.Files.Count; i++)
{
var file = context.Request.Files[i];
var fullPath = StorageRoot + Path.GetFileName(file.FileName);
file.SaveAs(fullPath);
string fullName = Path.GetFileName(file.FileName);
statuses.Add(new FilesStatus(fullName, file.ContentLength, fullPath));
}
}
private void WriteJsonIframeSafe(HttpContext context, List<FilesStatus> statuses)
{
context.Response.AddHeader("Vary", "Accept");
try
{
if (context.Request["HTTP_ACCEPT"].Contains("application/json"))
context.Response.ContentType = "application/json";
else
context.Response.ContentType = "text/plain";
}
catch
{
context.Response.ContentType = "text/plain";
}
var jsonObj = js.Serialize(statuses.ToArray());
context.Response.Write(jsonObj);
}
private static bool GivenFilename(HttpContext context)
{
return !string.IsNullOrEmpty(context.Request["f"]);
}
private void DeliverFile(HttpContext context)
{
var filename = context.Request["f"];
var filePath = StorageRoot + filename;
if (File.Exists(filePath))
{
context.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
context.Response.ContentType = "application/octet-stream";
context.Response.ClearContent();
context.Response.WriteFile(filePath);
}
else
context.Response.StatusCode = 404;
}
private void ListCurrentFiles(HttpContext context)
{
var files =
new DirectoryInfo(StorageRoot)
.GetFiles("*", SearchOption.TopDirectoryOnly)
.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden))
.Select(f => new FilesStatus(f))
.ToArray();
string jsonObj = js.Serialize(files);
context.Response.AddHeader("Content-Disposition", "inline; filename=\"files.json\"");
context.Response.Write(jsonObj);
context.Response.ContentType = "application/json";
}
}
}
答案 1 :(得分:0)
问题的服务器端部分的更直接答案:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
// *Very Important* Security checks need to go here (is the user authorised to upload.. And do we want to restrict filetypes eg. executable scripts to prevent common hacking attempts)
// This can be done via prior security checks and setting a session variable as such:
// if ((bool)Session["ValidatedUser"] != true) throw new Exception("Invalid Permissions");
// Check if file has been sent
if (context.Request.Files.Count > 0)
{
// Save uploaded file
HttpPostedFile uploadedFile = context.Request.Files[0];
uploadedFile.SaveAs("D:/MyUploadFolder/" + uploadedFile.FileName);
context.Response.Write("OK");
}
else
context.Response.Write("No file attached");
}
很明显,可以根据需要扩展它。