小道消息的文件上传示例

Posted

技术标签:

【中文标题】小道消息的文件上传示例【英文标题】: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 属性没有任何方法可以做到这一点。谁能给我举个例子?

【问题讨论】:

【参考方案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 *** question 的答案,该答案尚未经过我的测试。

【讨论】:

以上是关于小道消息的文件上传示例的主要内容,如果未能解决你的问题,请参考以下文章

Extjs文件上传进度

Spring Boot 中的文件上传:上传、验证和异常处理

MVC-4 文件上传成功消息

MVC中的Ajax.BeginForm上传文件

在 Laravel 5.4 中获取上传失败文件的文件名

文件上传 servlet 从HttpServletRequest.getInputStream()中获得消息内容