網站首頁 編程語言 正文
使用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);
? ? }
}
?
原文鏈接:https://blog.csdn.net/xiaoyong_net/article/details/107688427
相關推薦
- 2023-05-11 C#利用OLEDB實現將DataTable寫入Excel文件中_C#教程
- 2022-07-01 Go?函數中獲取調用者的函數名和文件名及行號_Golang
- 2022-11-07 python單元測試框架unittest基本用法案例_python
- 2022-09-06 Minio設置文件鏈接永久有效的完整步驟_其它綜合
- 2022-09-26 Shell(希爾)排序算法詳解之C語言版
- 2022-10-23 C#使用Task實現并行編程_C#教程
- 2023-07-18 Springboot獲取jar包同級目錄
- 2021-12-28 Go語言做爬蟲狀態碼返回418的問題解決_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支