C\#http 시 리 즈 는 form-data 방식 으로 여러 파일 과 키 쌍 을 원 격 서버 에 업로드 합 니 다.

시리즈 디 렉 터 리【최신 개발 기사 가 업데이트 되 었 습 니 다.자세 한 내용 을 보 려 면 클릭 하 세 요】
다음 장면 과 같이 폼 에 있 는 사용자 정보(첨부 파일 포함)를 서버 에 업로드 하고 데이터베이스 에 저장 합 니 다.

<form id="form1" runat="server" action="UserManageHandler.ashx" method="post" enctype="multipart/form-data">
 <div>
    : <input type="text" name="uname" class="uname" /><br/>
    : <input type="text" name="email" class="email" /><p/>
    1: <input type="file" name="file1" class="file" /><p/>
    2: <input type="file" name="file2" class="file" /><p/>
    3: <input type="file" name="file3" class="file" /><p/>
    <input type="submit" name="submit" value="  " />
 </div>
</form>
전통 적 인 관리 시스템 이나 사이트 에서 발 표 된 IIS 사이트 에 올 리 면 ASP.NET 의 업로드 컨트롤 을 배경 으로 하 는 HttpContext.Request.Files 와 결합 하 는 관련 유형 과 방법 은 간단 하 다.

HttpFileCollection files = HttpContext.Current.Request.Files;
 HttpPostedFile postedFile = files["fileUpload"];
 postedFile.SaveAs(postedFile.FileName);
클 라 우 드 응용 이 발전 하고 보급 되면 서 제3자 응용 플랫폼 이나 개발 플랫폼 은 클 라 우 드 서버 에 배치 되 었 다.예 를 들 어 아 리 클 라 우 드,텐 센트 클 라 우 드,칠 우 클 라 우 드,청 운 등 이다.제3자 가 대외 적 으로 개방 한 응용 플랫폼 은 대부분이 Restful API 를 제공 하여 개발 자 에 게 업로드(로 컬 또는 원 격 파일)또는 업무 데 이 터 를 다운로드 하여 업무 개발 을 하도록 제공 합 니 다.
multipart/form-data 데이터 형식 소개
1.Postman 을 사용 하여 상기 기능 을 모 의(첨부 파일 을 업로드 하지 않 음)

【코드】단 추 를 누 르 면 아래 창 을 엽 니 다.

2、첨부 파일 하나만 업로드

[제출]단 추 를 누 르 면 Form 이 요청 데 이 터 를 제출 합 니 다.Fiddler 가 가방 을 잡 을 때 보 이 는 요청 은 다음 과 같 습 니 다.(무관 한 요청 머리 는 본문 에서 생략 되 었 습 니 다)


3.첨부 파일 여러 개,일반 텍스트 하나,Office word 문서 하나,jpg 그림 하나 업로드

[제출]단 추 를 누 르 면 Form 이 요청 데 이 터 를 제출 합 니 다.Fiddler 가 가방 을 잡 을 때 보 이 는 요청 은 다음 과 같 습 니 다.(무관 한 요청 머리 는 본문 에서 생략 되 었 습 니 다)

HTTP 요청 의 multipart/form-data 는 폼 의 데 이 터 를 하나의 메시지 로 처리 하고 탭 을 단위 로 구분자 로 분리 합 니 다.키 값 도 올 릴 수 있 고 파일 도 올 릴 수 있 습 니 다.업 로드 된 필드 가 파일 일 때 Content-Type 에서 파일 형식 을 표시 합 니 다.content-disposition,필드 의 정 보 를 설명 하 는 데 사용 합 니 다.
boundary 격 리 가 있 기 때문에 multipart/form-data 는 파일 을 업로드 할 수도 있 고 키 쌍 을 업로드 할 수도 있 습 니 다.키 쌍 방식 을 사용 하여 여러 파일 을 업로드 할 수 있 습 니 다.
구체 적 인 형식 설명:
(1)boundary:서로 다른 필드 를 분할 하 는 데 사용 되 며 본문 내용 과 중복 되 지 않도록 합 니 다.가로 선 2 개 로"-"로 시작 하고 마지막 필드 이후 가로 선 2 개 로"-"로 끝난다.
(2)Content-Type:데 이 터 를 multipart/form-data 로 인 코딩 하 는 것 을 가리 키 고 있 습 니 다.
(3)메시지 주체 에서 필드 개수 에 따라 여러 구조 가 유사 한 부분 으로 나 뉜 다.
  • 각 부분 은--boundary로 시작 합 니 다.
  • 이 어 내용 설명 정보
  • 그리고 리 턴(줄 바 꾸 기),
  • 마지막 으로 필드 의 구체 적 인 내용(텍스트 또는 바 이 너 리)입 니 다.
  • 파일 을 전송 하면 파일 이름과 파일 형식 정 보 를 포함 합 니 다.
  • 메시지 주 체 는 마지막 으로--boundary--표시 로 끝났다.
  • multipart/form-data 에 대한 상세 한 정 의 는RFC1867RFC2045를 보십시오.
    이런 방식 은 일반적으로 파일 을 업로드 하 는 데 사용 되 는데,각 서버 언어 도 그것 에 대해 좋 은 지 지 를 가지 고 있다.
    위 에서 언급 한 이 두 가지 POST 데이터 의 방식 은 모두 브 라 우 저 원생 이 지원 하 는 것 이 고 현 단계 기준 에서 원생
    이 두 가지 방식 만 지원 합 니 다.(요 소 를 통 해enctype속성 을 지정 하고 기본 값application/x-www-form-urlencoded입 니 다.
    C\#일반적인 방법 으로 multipart/form-data 방식 으로 첨부 파일 과 요청 파 라 메 터 를 업로드 합 니 다.multipart/form-data의 데이터 요청 형식 을 알 게 된 후 C\#HttpWebRequest 와 HttpWebResponse 류 를 사용 하여 상기 장면 을 모 의 합 니 다.구체 적 인 코드 는 다음 과 같 습 니 다.
    
    /// <summary>
    /// HTTP  (       ,multipart/form-data)。
    ///                           url    
    /// </summary>
    /// <param name="url">    URL</param>
    /// <param name="fileFullNames">        (           )。         ,      </param>
    /// <param name="kVDatas">          。</param>
    /// <param name="method">     。    WebRequestMethods.Http     </param>
    /// <param name="timeOut">      <see cref="M:System.Net.HttpWebRequest.GetResponse" />  
    ///      <see cref="M:System.Net.HttpWebRequest.GetRequestStream" />       (      )。
    ///      -1       
    /// </param>
    /// <returns></returns>
    public HttpResult UploadFormByMultipart(string url, string[] fileFullNames, NameValueCollection kVDatas = null, string method = WebRequestMethods.Http.Post, int timeOut = -1)
    {
     #region   
     /*      :https://www.alibabacloud.com/help/zh/doc-detail/42976.htm
      C#   : https://github.com/aliyun/aliyun-oss-csharp-sdk/blob/master/samples/Samples/PostPolicySample.cs?spm=a2c63.p38356.879954.18.7f3f7c34W3bR9U&file=PostPolicySample.cs
         (C#                  FormData    ,         。          ,   )
      */
    
     /*   :multipart/form-data       
      *  (1) Header      Content-Type: multipart/form-data; boundary={boundary}。
      *  (2) Header  bod y    \r
    --{boundary} 。 * (3) :Content-Disposition: form-data; name="{key}"\r
    \r
    * {value}\r
    * --{boundary} * (4) , policy、key、file、OSSAccessKeyId、OSSAccessKeyId、Content-Disposition。 * (5) : file 。 。 */ #endregion #region ContentType /* ContentType 。 ContentType Content-typeHTTP 。 Content-typeHTTP , ContentType null。 * : WebHeaderCollection 。 WebHeaderCollection, 。 * Headers */ #endregion #region Method /* ContentLength -1 , Method 。 */ #endregion #region HttpWebRequest.CookieContainer .NET3.5 .NET4.0 /* :https://www.crifan.com/baidu_emulate_login_for_dotnet_4_0_error_the_fisrt_two_args_should_be_string_type_0_1/ */ #endregion HttpResult httpResult = new HttpResult(); #region if (fileFullNames == null || fileFullNames.Length == 0) { httpResult.Status = HttpResult.STATUS_FAIL; httpResult.RefCode = (int)HttpStatusCode2.USER_FILE_NOT_EXISTS; httpResult.RefText = HttpStatusCode2.USER_FILE_NOT_EXISTS.GetCustomAttributeDescription(); return httpResult; } List<string> lstFiles = new List<string>(); foreach (string fileFullName in fileFullNames) { if (File.Exists(fileFullName)) { lstFiles.Add(fileFullName); } } if (lstFiles.Count == 0) { httpResult.Status = HttpResult.STATUS_FAIL; httpResult.RefCode = (int)HttpStatusCode2.USER_FILE_NOT_EXISTS; httpResult.RefText = HttpStatusCode2.USER_FILE_NOT_EXISTS.GetCustomAttributeDescription(); return httpResult; } #endregion string boundary = CreateFormDataBoundary(); // byte[] beginBoundaryBytes = Encoding.UTF8.GetBytes("--" + boundary + "\r
    "); // 。【☆】 \r
    。 byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r
    --" + boundary + "--\r
    "); // 。【☆】 --\r
    。 byte[] newLineBytes = Encoding.UTF8.GetBytes("\r
    "); // MemoryStream memoryStream = new MemoryStream(); HttpWebRequest httpWebRequest = null; try { httpWebRequest = WebRequest.Create(url) as HttpWebRequest; // httpWebRequest.ContentType = string.Format(HttpContentType.MULTIPART_FORM_DATA + "; boundary={0}", boundary); //httpWebRequest.Referer = "http://bimface.com/user-console"; httpWebRequest.Method = method; httpWebRequest.KeepAlive = true; httpWebRequest.Timeout = timeOut; httpWebRequest.UserAgent = GetUserAgent(); #region 1: if (kVDatas != null) { string formDataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r
    \r
    " + "{1}\r
    "; foreach (string key in kVDatas.Keys) { string formItem = string.Format(formDataTemplate, key.Replace(StringUtils.Symbol.KEY_SUFFIX, String.Empty), kVDatas[key]); byte[] formItemBytes = Encoding.UTF8.GetBytes(formItem); memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length); // 1.1 FormData memoryStream.Write(formItemBytes, 0, formItemBytes.Length); // 1.2 FormData } } #endregion #region 2: ( file ) const string filePartHeaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r
    " + "Content-Type: application/octet-stream\r
    \r
    "; int i = 0; foreach (var fileFullName in lstFiles) { FileInfo fileInfo = new FileInfo(fileFullName); string fileName = fileInfo.Name; string fileHeaderItem = string.Format(filePartHeaderTemplate, "file", fileName); byte[] fileHeaderItemBytes = Encoding.UTF8.GetBytes(fileHeaderItem); if (i > 0) { // memoryStream.Write(newLineBytes, 0, newLineBytes.Length); } memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length); // 2.1 FormData memoryStream.Write(fileHeaderItemBytes, 0, fileHeaderItemBytes.Length); // 2.2 FormData int bytesRead; byte[] buffer = new byte[1024]; FileStream fileStream = new FileStream(fileFullName, FileMode.Open, FileAccess.Read); while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { memoryStream.Write(buffer, 0, bytesRead); // 2.3 FormData } i++; } memoryStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); // 2.4 FormData #endregion #region 3: ( ) httpWebRequest , httpWebRequest.ContentLength = memoryStream.Length; Stream requestStream = httpWebRequest.GetRequestStream(); memoryStream.Position = 0; byte[] tempBuffer = new byte[memoryStream.Length]; memoryStream.Read(tempBuffer, 0, tempBuffer.Length); memoryStream.Close(); requestStream.Write(tempBuffer, 0, tempBuffer.Length); // httpWebRequest requestStream.Close(); #endregion HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse; // if (httpWebResponse != null) { //GetHeaders(ref httpResult, httpWebResponse); GetResponse(ref httpResult, httpWebResponse); httpWebResponse.Close(); } } catch (WebException webException) { GetWebExceptionResponse(ref httpResult, webException); } catch (Exception ex) { GetExceptionResponse(ref httpResult, ex, method, HttpContentType.MULTIPART_FORM_DATA); } finally { if (httpWebRequest != null) { httpWebRequest.Abort(); } } return httpResult; }
    코드 의 주석 부분,특히 boundary 를 경계선 으로 하 는 부분 은 형식 이 잘못 되 지 않 으 면 제출 에 성공 할 수 없습니다.
    상기 방법 에 따라 몇 가지 과부하 방법 을 파생 시 킬 수 있다.
    단일 파일 업로드 와 여러 키 쌍
    
    /// <summary>
    /// HTTP  (       ,multipart/form-data)。
    ///                         url    
    /// </summary>
    /// <param name="url">    URL</param>
    /// <param name="fileFullName">      (           )</param>
    /// <param name="kVDatas">          。</param>
    /// <param name="method">     。    WebRequestMethods.Http     </param>
    /// <param name="timeOut">      <see cref="M:System.Net.HttpWebRequest.GetResponse" />  
    ///      <see cref="M:System.Net.HttpWebRequest.GetRequestStream" />       (      )。
    ///      -1       
    /// </param>
    /// <returns></returns>
    public HttpResult UploadFormByMultipart(string url, string fileFullName, NameValueCollection kVDatas = null, string method = WebRequestMethods.Http.Post, int timeOut = -1)
    {
     string[] fileFullNames = { fileFullName };
    
     return UploadFormByMultipart(url, fileFullNames, kVDatas, method, timeOut);
    }
    
    /// <summary>
    /// HTTP  (       ,multipart/form-data)。
    ///                   url    
    /// </summary>
    /// <param name="url">    URL</param>
    /// <param name="fileFullName">      (           )</param>
    /// <param name="kVDatas">          。</param>
    /// <param name="method">     。    WebRequestMethods.Http     </param>
    /// <param name="timeOut">      <see cref="M:System.Net.HttpWebRequest.GetResponse" />  
    ///      <see cref="M:System.Net.HttpWebRequest.GetRequestStream" />       (      )。
    ///      -1       
    /// </param>
    /// <returns></returns>
    public HttpResult UploadFormByMultipart(string url, string fileFullName, Dictionary<string, string> kVDatas = null, string method = WebRequestMethods.Http.Post, int timeOut = -1)
    {
     var nvc = kVDatas.ToNameValueCollection();
     return UploadFormByMultipart(url, fileFullName, nvc, method, timeOut);
    }
    시리즈 디 렉 터 리【최신 개발 기사 가 업데이트 되 었 습 니 다.자세 한 내용 을 보 려 면 클릭 하 세 요】
    총결산
    위 에서 말 한 것 은 소 편 이 소개 한 C\#http 시 리 즈 는 form-data 방식 으로 여러 개의 파일 과 키 워드 를 올 리 는 것 이 원 격 서버 에 집합 하 는 데 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
    만약 당신 이 본문 이 당신 에 게 도움 이 된다 고 생각한다 면,전 재 를 환영 합 니 다.번 거 로 우 시 겠 지만 출처 를 밝 혀 주 십시오.감사합니다!

    좋은 웹페이지 즐겨찾기