返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C#如何自定义multipart/form-data的解析器
  • 890
分享到

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

2024-04-02 19:04:59 890人浏览 独家记忆
摘要

目录解析辅助类 调用示例使用websocketSharp自定义实现WEB服务时,无法解析multipart/fORM-data请求的数据。 通过查找资料,采用以下方式实现m

使用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);
    }
}
 

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

--结束END--

本文标题: C#如何自定义multipart/form-data的解析器

本文链接: https://lsjlt.com/news/150925.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C#如何自定义multipart/form-data的解析器
    目录解析辅助类 调用示例使用WebSocketSharp自定义实现Web服务时,无法解析multipart/form-data请求的数据。 通过查找资料,采用以下方式实现m...
    99+
    2024-04-02
  • Java如何自定义DNS解析器
    本篇内容介绍了“Java如何自定义DNS解析器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言:最近终于用上了高性能的测试机(54C96G...
    99+
    2023-06-29
  • 如何使用html5的自定义data-*属性与jquery的data()
    这篇文章主要讲解了“如何使用html5的自定义data-*属性与jquery的data()”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用html5的...
    99+
    2024-04-02
  • H5自定义属性data-*的示例分析
    这篇文章主要为大家展示了“H5自定义属性data-*的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“H5自定义属性data-*的示例分析”这篇文章吧。 ...
    99+
    2024-04-02
  • 如何理解HTML5的自定义属性data-*和JS操作
    这篇文章主要讲解了“如何理解HTML5的自定义属性data-*和JS操作”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解HTML5的自定义属性data...
    99+
    2024-04-02
  • HTML5中data-*自定义属性的示例分析
    这篇文章将为大家详细讲解有关HTML5中data-*自定义属性的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、关于html元素的特性1.html元素都存在一些...
    99+
    2024-04-02
  • Spring Data Jpa如何实现自定义方法
    这篇文章将为大家详细讲解有关Spring Data Jpa如何实现自定义方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Spring Data Jpa 自定义方法的实现最近项目中用到...
    99+
    2023-06-22
  • C语言自定义类型全解析
    目录前言结构体类型结构体的声明结构体变量的定义与初始化结构体的自引用结构体的访问结构体的传参传结构体传地址结构体的内存对齐(强烈建议观看)位段位段的声明位段的内存管理位段的跨平台性 ...
    99+
    2024-04-02
  • 详解如何在SpringBoot中自定义参数解析器
    目录前言1.自定义参数解析器2.PrincipalMethodArgumentResolver3.RequestParamMapMethodArgumentResolver4.小结前...
    99+
    2024-04-02
  • Spring Data MongoDB中如何实现自定义级联
    这篇文章给大家分享的是有关Spring Data MongoDB中如何实现自定义级联的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言Spring Data MongoDB 项目提供与MongoDB文档数据库的集...
    99+
    2023-05-30
    springdata mongodb
  • C#中如何自定义事件
    这篇文章将为大家详细讲解有关C#中如何自定义事件,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。C#自定义事件C#语言中有77个关键字,其中delegate和event专门为C#中事件处理系统...
    99+
    2023-06-17
  • C#如何自定义泛型类
    这篇文章主要为大家展示了“C#如何自定义泛型类”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C#如何自定义泛型类”这篇文章吧。Generic是Framework 2.0的新元素,中文名字称之为“...
    99+
    2023-06-18
  • C#如何自定义WPF中Slider的Autotooltip
    这篇文章主要介绍了C#如何自定义WPF中Slider的Autotooltip的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#如何自定义WPF中Slider的Autotooltip文章都会有所收获,下面我们一起...
    99+
    2023-07-02
  • spring data jpa如何使用自定义repository实现类
    目录spring data jpa使用自定义repository实现类创建MyJpaRepository实现类创建MyJpaRepositoryFactoryBean配置JPAJpa...
    99+
    2024-04-02
  • 如何用C#创建用户自定义异常浅析
    概述 异常是在程序执行期间出现的问题。C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。异常提供了一种把程序控制权从某个部分转移到另一个部分的方式。C# 异常处...
    99+
    2024-04-02
  • Spring Data JPA框架的Repository自定义实现详解
    目录1. Spring Data Repository自定义实现1.1 自定义特殊repository1.2 配置类1.3 解决歧义1.4 手动装配1.5 自定义Base Repos...
    99+
    2024-04-02
  • C#如何创建自定义特性
    目录概述实现方式概述 特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。...
    99+
    2024-04-02
  • C语言如何自定义函数
    这篇文章主要介绍了C语言如何自定义函数的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言如何自定义函数文章都会有所收获,下面我们一起来看看吧。先动手编写程序:#include <stdio.h...
    99+
    2023-06-16
  • C#如何实现自定义屏保
    这篇文章主要介绍“C#如何实现自定义屏保”,在日常操作中,相信很多人在C#如何实现自定义屏保问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#如何实现自定义屏保”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-07-04
  • Spring如何自定义注解
    这篇文章将为大家详细讲解有关Spring如何自定义注解,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。字段注解字段注解一般是用于校验字段是否满足要求,hibernate-validate依赖就提供了很多校验...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作