C#如何自定義multipart/form-data的解析器
使用WebSocketSharp自定義實現(xiàn)Web服務(wù)時,無法解析multipart/form-data請求的數(shù)據(jù)。
通過查找資料,采用以下方式實現(xiàn)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> /// 參數(shù)集合 /// </summary> public IDictionary<string, string> Parameters = new Dictionary<string, string>(); /// <summary> /// 上傳文件部分參數(shù) /// </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> /// 上傳的文件內(nèi)容 /// </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); } } } } }
調(diào)用示例
?HttpMultipartParser parser = new HttpMultipartParser(paramData); ? ? ? ? ? ? if (!parser.Success) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? result.Code = -1; ? ? ? ? ? ? ? ? result.Message = "請求數(shù)據(jù)格式不能正確"; ? ? ? ? ? ? ? ? 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); ? ? } } ?
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
C# Winform實現(xiàn)導(dǎo)出DataGridView當(dāng)前頁以及全部數(shù)據(jù)
基本上,所有的業(yè)務(wù)系統(tǒng)都會要求有導(dǎo)出的功能,所以這篇文章主要為大家介紹了如何利用Winform實現(xiàn)原生DataGridView的導(dǎo)出功能,需要的可以參考一下2023-07-07word ppt excel文檔轉(zhuǎn)換成pdf的C#實現(xiàn)代碼
這篇文章主要介紹了word ppt excel文檔轉(zhuǎn)換成pdf的C#實現(xiàn)代碼,有需要的朋友可以參考一下2014-01-01C#數(shù)值轉(zhuǎn)換-顯式數(shù)值轉(zhuǎn)換表(參考)
就是在將一種類型轉(zhuǎn)換成另外一種類型時,需要額外的代碼來完成這種轉(zhuǎn)換。2013-04-04C#使用BinaryFormatter類、ISerializable接口、XmlSerializer類進行序列化和反序列
這篇文章介紹了C#使用BinaryFormatter類、ISerializable接口、XmlSerializer類進行序列化和反序列化的方法,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-09-09淺談Async和Await如何簡化異步編程(幾個實例讓你徹底明白)
本篇文章主要介紹了淺談Async和Await如何簡化異步編程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12