【问题标题】:c# How to upload file to ashx with HTTP POST multipart/form-datac# 如何使用 HTTP POST multipart/form-data 将文件上传到 ashx
【发布时间】:2014-02-01 20:27:49
【问题描述】:

我正在尝试将一个大文件上传到通用处理程序 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

【问题讨论】:

    标签: c# asp.net web-services file-upload ashx


    【解决方案1】:

    你可能想看看他们在这个项目中是如何做到的:

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

    【讨论】:

      【解决方案2】:

      对问题的服务器端部分的更直接的回答:

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

      显然,这可以根据需要进行扩展。

      【讨论】:

        猜你喜欢
        • 2013-11-26
        • 1970-01-01
        • 2015-03-28
        • 1970-01-01
        • 2019-12-03
        • 1970-01-01
        • 2015-10-23
        • 1970-01-01
        • 2014-01-14
        相关资源
        最近更新 更多