c#如何使用HTTP POST多部分/表单数据将文件上载到ashx

c#如何使用HTTP POST多部分/表单数据将文件上载到ashx,c#,asp.net,web-services,file-upload,ashx,C#,Asp.net,Web Services,File Upload,Ashx,我正在尝试将一个大文件上载到Generic Handler FileUpload.ashx 我用Fiddler数据检查它,并以正确的方式到达服务器。但我无法在服务器端成功 我尝试了很多方法,但都无法将数据存储在数据库中 我试过旧的 context.Request.Files[0]; context.Request.Params["file"] context.Request["file"]; 还有其他一些事情,现在我很困惑。在简单HTML中,仅设置类型文件并使用上面的第一个方法进行输入,这里复

我正在尝试将一个大文件上载到Generic Handler FileUpload.ashx

我用Fiddler数据检查它,并以正确的方式到达服务器。但我无法在服务器端成功

我尝试了很多方法,但都无法将数据存储在数据库中

我试过旧的

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,您可能想检查一下他们在这个项目中是如何做到这一点的:

以下是处理接收上载文件的主要代码:

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";
        }

    }
}
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用System.Web;
使用System.Web.Script.Serialization;
命名空间jQuery\u文件\u Upload.MVC3.Upload
{
/// 
///UploadHandler的摘要说明
/// 
公共类UploadHandler:IHttpHandler
{
私有只读JavaScriptSerializer js;
私有字符串存储根
{
获取{return Path.Combine(System.Web.HttpContext.Current.Server.MapPath(“~/Files/”);}//Path应该!始终以“/”结尾
}
公共上传处理程序()
{
js=新的JavaScriptSerializer();
js.MaxJsonLength=41943040;
}
公共布尔可重用{get{return false;}}
公共void ProcessRequest(HttpContext上下文)
{
AddHeader(“Pragma”,“无缓存”);
AddHeader(“缓存控制”,“私有,无缓存”);
HandleMethod(上下文);
}
//基于方法处理请求
私有void HandleMethod(HttpContext上下文)
{
开关(context.Request.HttpMethod)
{
案例“头”:
案例“GET”:
if(GivenFilename(context))DeliverFile(context);
else ListCurrentFiles(上下文);
打破
案例“职位”:
案例“付诸表决”:
上传文件(上下文);
打破
案例“删除”:
删除文件(上下文);
打破
案例“选项”:
返回选项(上下文);
打破
违约:
context.Response.ClearHeaders();
context.Response.StatusCode=405;
打破
}
}
私有静态void ReturnOptions(HttpContext上下文)
{
AddHeader(“允许”、“删除、获取、HEAD、POST、PUT、OPTIONS”);
context.Response.StatusCode=200;
}
//从服务器上删除文件
私有void DeleteFile(HttpContext上下文)
{
var filePath=StorageRoot+context.Request[“f”];
if(File.Exists(filePath))
{
File.Delete(文件路径);
}
}
//将文件上载到服务器
私有void上载文件(HttpContext上下文)
{
变量状态=新列表();
var headers=context.Request.headers;
if(string.IsNullOrEmpty(头[“X-File-Name”]))
{
UploadWholeFile(上下文、状态);
}
其他的
{
UploadPartialFile(标题[“X-File-Name”]、上下文、状态);
}
WriteJsonIframeSafe(上下文、状态);
}
//上载部分文件
私有void UploadPartialFile(字符串文件名、HttpContext上下文、列表状态)
{
如果(context.Request.Files.Count!=1)抛出新的HttpRequestValidationException(“尝试上载每个请求包含多个片段的分块文件”);
var inputStream=context.Request.Files[0]。inputStream;
var fullName=StorageRoot+Path.GetFileName(文件名);
使用(var fs=new FileStream(全名、FileMode.Append、FileAccess.Write))
{
var buffer=新字节[1024];
var l=inputStream.Read(缓冲区,0,1024);
而(l>0)
{
fs.写入(缓冲区,0,l);
l=inputStream.Read(缓冲区,0,1024);
}
fs.Flush();
fs.Close();
}
添加(新文件状态(新文件信息(全名));
}
//上载整个文件
私有void UploadWholeFile(HttpContext上下文,列表状态)
{
for(int i=0;ipublic 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");
}