緣起:
接續這一篇,今天滿幸運的,上午時就把圖片上傳 Twitter 的 C# 程式搞定,面對那個看起來有點複雜的 form-data 居然沒卡太久,真是可喜可樂。
讀取圖片:
第一步,我們要得到圖片,根據我以往的經驗,非文字的的東東都是當二進制處理,我去查了查 C# 讀取檔案的方法,找到這個。File 的 ReadAllBytes 方法。
哇,使用起來真簡單,你只要傳檔案路徑的 string 給它就好,它就會回傳 byte 的陣列,我不確定在 post 資料時是不是直接傳 bytes 就好,還是要轉成其它編碼之類的,但這也不需我擔心,因為對於 byte 陣列的轉換,C# 就已經有提供很多 function 幫我們做了,像是之前很常用的 Convert.ToBase64String 裡面也能傳 byte 陣列。
form-data boundary:
再來是重頭戲,這篇文章幫了我很多。我們要把 HttpWebRequest 的 ContentType 改成 multipart/form-data,還要加個 boundary,那個 boundary 是可以自己設定的,不過我看大部份的格式都會長成 "前面很多個 - 號再加上一串不重複的英文數字組合",我看我在 POST Man 上面的測試資料,它的 boundary 是 --------------------------919141264236315789851784。
寫那篇文章的人是用 DateTime.Now 來產生那個不重複的英文數字組合,Ticket 是那個 DateTime 物件的刻度數目,資料型態是 long,然後用 toString 轉成 string,toString 裡面可以傳 string 參數來把資料格式化,這邊有說明,x 代表轉成 16 進位格式。
boundary 設好後就能加進我們 HttpWebRequest 的 ContentType 裡了
form-data body:
再來是 request 的 body 部份,這邊最麻煩了,格式要自己弄,而且只要有一丁點的格式錯誤 (像是少了一個換行),server 端就給你報錯。可以先觀察看看 POST Man 的格式
Content-Length 下面的東東就是 reqeust 的 body,可以看到,每個資料固定都會先有個 boundary,然後換行,再來是 Content-Disposition,其實我也不是很清楚這個值要幹啥用的,只知道它固定是 form-data,這裡有詳細的介紹 (我之後有空再看看,應該啦)。那個 name 看來就是 key 的名字,這邊是 media,最後是 filename,檔案名稱,這個沒什麼好講的。有多筆資料的話,一樣照著上面的方法來做,用 boundary 來隔開每筆資料。
要注意的是,這裡的 boundary 前面都要再加兩個 -- ,body 的最後也要再加一個 boundary 代表結束,而且那個 boundary 的後面還要再加兩個 --。知道規則後,就能開始寫程式了。
那篇文章是用 MemoryStream 來把 body 的資料都存起來,裡面存的都是 byte,最後用從 HttpWebRequest GetRequestStream 拿到的 Stream 來把那個 MemoryStream 送出去就完成了。
我們要把那些 string 轉成 byte 才能存進 MemoryStream 中,可以用 Encoding.ASCII.GetBytes 或 Encoding.UTF8.GetBytes 來做。
開頭加入完成後,接下來是加入 Content-Dispositon 那串,要注意的是,這行最後面要加兩個 \r\n。
前面對資料的宣告完成後,就可以開始把值寫進去了,這邊就是我們的圖片 byte 陣列。
讚~~~ 完整程式碼
沒有留言:
張貼留言