我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C#如何自定义multipart/form-data的解析器

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C#如何自定义multipart/form-data的解析器

使用WebSocketSharp自定义实现Web服务时,无法解析multipart/form-data请求的数据。

通过查找资料,采用以下方式实现multipart/form-data的解析器。

解析辅助类 

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
 
namespace YongFrame.Common.Utils
{
    /// <summary>
    /// multipart/form-data的解析器
    /// </summary>
    internal class HttpMultipartParser
    {
        /// <summary>
        /// 参数集合
        /// </summary>
        public IDictionary<string, string> Parameters = new Dictionary<string, string>();
        /// <summary>
        /// 上传文件部分参数
        /// </summary>
        public string FilePartName { get; }
        /// <summary>
        /// 是否解析成功
        /// </summary>
        public bool Success { get; private set; }
        /// <summary>
        /// 请求类型
        /// </summary>
        public string ContentType { get; private set; }
        /// <summary>
        /// 上传的文件名
        /// </summary>
        public string Filename { get; private set; }
        /// <summary>
        /// 上传的文件内容
        /// </summary>
        public byte[] FileContents { get; private set; }
 
        /// <summary>
        /// 解析multipart/form-data格式的文件请求,默认编码为utf8
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="filePartName"></param>
        public HttpMultipartParser(Stream stream, string filePartName)
        {
            FilePartName = filePartName;
            Parse(stream, Encoding.UTF8);
        }
 
        /// <summary>
        /// 解析multipart/form-data格式的字符串
        /// </summary>
        /// <param name="content"></param>
        public HttpMultipartParser(string content)
        {
            var array = Encoding.UTF8.GetBytes(content);
            var stream = new MemoryStream(array);
            Parse(stream, Encoding.UTF8);
        }
 
        /// <summary>
        /// 解析multipart/form-data格式的文件请求
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="encoding">编码</param>
        /// <param name="filePartName"></param>
        public HttpMultipartParser(Stream stream, Encoding encoding, string filePartName)
        {
            FilePartName = filePartName;
            Parse(stream, encoding);
        }
 
        private void Parse(Stream stream, Encoding encoding)
        {
            Success = false;
 
            var data = ToByteArray(stream);
 
            var content = encoding.GetString(data);
 
            var delimiterEndIndex = content.IndexOf("\r\n", StringComparison.Ordinal);
 
            if (delimiterEndIndex > -1)
            {
                var delimiter = content.Substring(0, content.IndexOf("\r\n", StringComparison.Ordinal)).Trim();
 
                var sections = content.Split(new[] {delimiter}, StringSplitOptions.RemoveEmptyEntries);
 
                foreach (var s in sections)
                {
                    if (s.Contains("Content-Disposition"))
                    {
                        var nameMatch = new Regex(@"(?<=name\=\"")(.*?)(?=\"")").Match(s);
                        var name = nameMatch.Value.Trim().ToLower();
 
                        if (name == FilePartName && !string.IsNullOrEmpty(FilePartName))
                        {
                            var re = new Regex(@"(?<=Content\-Type:)(.*?)(?=\r\n\r\n)");
                            var contentTypeMatch = re.Match(content);
 
                            re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")");
                            var filenameMatch = re.Match(content);
 
                            if (contentTypeMatch.Success && filenameMatch.Success)
                            {
                                ContentType = contentTypeMatch.Value.Trim();
                                Filename = filenameMatch.Value.Trim();
 
                                var startIndex = contentTypeMatch.Index + contentTypeMatch.Length + "\r\n\r\n".Length;
 
                                var delimiterBytes = encoding.GetBytes("\r\n" + delimiter);
                                var endIndex = IndexOf(data, delimiterBytes, startIndex);
 
                                var contentLength = endIndex - startIndex;
 
                                var fileData = new byte[contentLength];
 
                                Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength);
 
                                FileContents = fileData;
                            }
                        }
                        else if (!string.IsNullOrWhiteSpace(name))
                        {
                            var startIndex = nameMatch.Index + nameMatch.Length + "\r\n\r\n".Length;
                            Parameters.Add(name, s.Substring(startIndex).TrimEnd('\r', '\n').Trim());
                        }
                    }
                }
 
                if (FileContents != null || Parameters.Count != 0)
                {
                    Success = true;
                }
            }
        }
 
        public static int IndexOf(byte[] searchWithin, byte[] serachFor, int startIndex)
        {
            var index = 0;
            var startPos = Array.IndexOf(searchWithin, serachFor[0], startIndex);
 
            if (startPos != -1)
            {
                while (startPos + index < searchWithin.Length)
                {
                    if (searchWithin[startPos + index] == serachFor[index])
                    {
                        index++;
                        if (index == serachFor.Length)
                        {
                            return startPos;
                        }
                    }
                    else
                    {
                        startPos = Array.IndexOf(searchWithin, serachFor[0], startPos + index);
                        if (startPos == -1)
                        {
                            return -1;
                        }
 
                        index = 0;
                    }
                }
            }
 
            return -1;
        }
 
        public static byte[] ToByteArray(Stream stream)
        {
            var buffer = new byte[32768];
            using (var ms = new MemoryStream())
            {
                while (true)
                {
                    var read = stream.Read(buffer, 0, buffer.Length);
                    if (read <= 0)
                    {
                        return ms.ToArray();
                    }
 
                    ms.Write(buffer, 0, read);
                }
            }
        }
    }
}

调用示例

 HttpMultipartParser parser = new HttpMultipartParser(paramData);
            if (!parser.Success)
            {
                result.Code = -1;
                result.Message = "请求数据格式不能正确";
                return result;
            }
            if (!parser.Parameters.ContainsKey("optid") || parser.Parameters["optid"] == null || string.IsNullOrEmpty(parser.Parameters["optid"]))
            {
                result.Code = -1;
                result.Message = "用户名不能为空";
                return result;
            }
public void Upload(Stream stream)
{
    HttpMultipartParser parser = new HttpMultipartParser(stream, "image");
 
    if (parser.Success)
    {
        string user = HttpUtility.UrlDecode(parser.Parameters["user"]);
        string title = HttpUtility.UrlDecode(parser.Parameters["title"]);
 
        // Save the file somewhere
        File.WriteAllBytes(FILE_PATH + title + FILE_EXT, parser.FileContents);
    }
}
 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C#如何自定义multipart/form-data的解析器

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java如何自定义DNS解析器

本篇内容介绍了“Java如何自定义DNS解析器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言:最近终于用上了高性能的测试机(54C96G
2023-06-29

C#如何自定义WPF中Slider的Autotooltip

这篇文章主要介绍了C#如何自定义WPF中Slider的Autotooltip的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#如何自定义WPF中Slider的Autotooltip文章都会有所收获,下面我们一起
2023-07-02

antd vue中,如何在form表单中的自定义组件使用v-decorator

antd vue中,在form表单中的自定义组件使用v-decorator问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-17

C#中如何实现自定义类型的转换

在C#中,我们可以通过实现类型转换运算符(conversion operators)来自定义类型的转换。具体步骤如下:创建一个自定义类型,例如一个类或结构体。public class MyType{public int Value { g
C#中如何实现自定义类型的转换
2024-04-03

如何为 AWS ION 编写自定义解组器?

php小编西瓜为您介绍如何为AWS ION编写自定义解析器。AWS ION是一种用于处理大规模数据的开源数据格式,具有高效的存储和传输能力。自定义解析器是为了满足特定需求而开发的,能够将ION数据转化为特定格式。编写自定义解析器需要了解IO
如何为 AWS ION 编写自定义解组器?
2024-02-09

如何理解Spring自定义属性编辑器

如何理解Spring自定义属性编辑器,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Spring 自定义属性编辑器Spring DI注入的时候可以把普通属性注入进来,但是像D
2023-06-17

Java中的注解(Annotation)有什么作用?如何自定义注解?(Java注解的功能是什么?如何定义自己的注解?)

Java注解用于提供附加信息,不会影响代码行为。它们用于:文档化代码代码分析代码生成运行时行为修改自定义注解通过@Retention和@Target指定范围和应用元素,并使用@Documented和@Inherited控制文档和继承行为。在使用时,通过@AnnotationName(value)语法应用注解。通过反射可以在运行时访问自定义注解。最佳实践包括保持简洁、使用标准化命名、避免过度使用和详细文档化。
Java中的注解(Annotation)有什么作用?如何自定义注解?(Java注解的功能是什么?如何定义自己的注解?)
2024-04-02

如何理解Vue中组件的自定义事件

本篇文章为大家展示了如何理解Vue中组件的自定义事件,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。