【问题标题】:File upload example for grapevine小道消息的文件上传示例
【发布时间】:2017-03-08 08:43:02
【问题描述】:

我是 Web API 和 REST 服务的新手,我希望构建一个简单的 REST 服务器来接受文件上传。我发现了简单易懂的小道消息。我找不到任何文件上传示例?

这是一个使用 System.Web.Http 的示例

 var streamProvider = new MultipartFormDataStreamProvider(ServerUploadFolder);

 await Request.Content.ReadAsMultipartAsync(streamProvider);

但是小道消息 Request 属性没有任何方法可以做到这一点。谁能给我举个例子?

【问题讨论】:

    标签: asp.net-web-api grapevine


    【解决方案1】:

    如果您尝试将文件作为二进制负载上传,请参阅 GitHub 上的 this question/answer

    如果您尝试从表单提交上传文件,这会有点棘手,因为尚未添加多部分有效负载解析器,但仍然可以。

    以下代码示例完全未经测试,我只是在脑海中写下了这个,所以它可能不是最好的解决方案,但它是一个起点:

    public static class RequestExtensions
    {
        public static IDictionary<string, string> ParseFormUrlEncoded(this IHttpRequest request)
        {
            var data = new Dictionary<string, string>();
    
            foreach (var tuple in request.Payload.Split('='))
            {
                var parts = tuple.Split('&');
                var key = Uri.UnescapeDataString(parts[0]);
                var val = Uri.UnescapeDataString(parts[1]);
                if (!data.ContainsKey(key)) data.Add(key, val);
            }
    
            return data;
        }
    
        public static IDictionary<string, FormElement> ParseFormData(this IHttpRequest request)
        {
            var data = new Dictionary<string, FormElement>();
            var boundary = GetBoundary(request.Headers.Get("Content-Type"));
    
            if (boundary == null) return data;
    
            foreach (var part in request.Payload.Split(new[] { boundary }, StringSplitOptions.RemoveEmptyEntries))
            {
                var element = new FormElement(part);
                if (!data.ContainsKey(element.Name)) data.Add(element.Name, element);
            }
    
            return data;
        }
    
        private static string GetBoundary(string contenttype)
        {
            if (string.IsNullOrWhiteSpace(contenttype)) return null;
    
            return (from part in contenttype.Split(';', ',')
                select part.TrimStart().TrimEnd().Split('=')
                into parts
                where parts[0].Equals("boundary", StringComparison.CurrentCultureIgnoreCase)
                select parts[1]).FirstOrDefault();
        }
    }
    
    public class FormElement
    {
        public string Name => _dispositionParams["name"];
        public string FileName => _dispositionParams["filename"];
        public Dictionary<string, string> Headers { get; private set; }
        public string Value { get; }
    
        private Dictionary<string, string> _dispositionParams;
    
        public FormElement(string data)
        {
            var parts = data.Split(new [] { "\r\n\r\n", "\n\n" }, StringSplitOptions.None);
            Value = parts[1];
    
            ParseHeaders(parts[0]);
            ParseParams(Headers["Content-Disposition"]);
        }
    
        private void ParseHeaders(string data)
        {
            Headers = data.TrimStart().TrimEnd().Split(new[] {"\r\n", "\n"}, StringSplitOptions.RemoveEmptyEntries).Select(header => header.Split(new[] {':'})).ToDictionary(parts => parts[0].TrimStart().TrimEnd(), parts => parts[1].TrimStart().TrimEnd());
        }
    
        private void ParseParams(string data)
        {
            _dispositionParams = new Dictionary<string, string>();
    
            foreach (var part in data.Split(new[] {';'}))
            {
                if (part.IndexOf("=") == -1) continue;
                var parts = part.Split(new[] {'='});
                _dispositionParams.Add(parts[0].TrimStart(' '), parts[1].TrimEnd('"').TrimStart('"'));
            }
        }
    }
    

    如果您正在寻找可以立即使用的异步内容,可以尝试实现this stackoverflow question 的答案,该答案尚未经过我的测试。

    【讨论】:

      猜你喜欢
      • 2017-11-25
      • 2016-08-14
      • 2019-04-17
      • 1970-01-01
      • 1970-01-01
      • 2013-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多