天天看點

Retrofit2.0+ .Net MVC4(WebApi) 上傳多張圖檔

最近在做Android項目,使用的是MVP+Retrofit+rxjava+dagger的項目架構,RestFul 服務使用的.Net平台的WebApi。由于業務中需要有多檔案上傳的功能。是以在這裡記載一下,便于以後查閱。

Android端Retrofit api 定義

 在這次上傳中,我們将實體類資料和檔案資料一起上傳到服務端。是以隻寫一個api就好

<code>()</code>

<code>Observable&lt;HttpResult&lt;String&gt;&gt; addEvent(() Event entity, ()List&lt;MultipartBody.Part&gt; parts);</code>

讀取檔案并将其轉換成MuiltipartBody.Part 清單

<code>List&lt;MultipartBody.Part&gt; getFilesMap() {</code>

<code>    </code><code>= ArrayList&lt;MultipartBody.Part&gt;();</code>

<code>    </code><code>File file = ;</code>

<code>    </code><code>{</code>

<code>        </code><code>(!= &amp;&amp; .size() &gt; ) {</code>

<code>            </code><code>(String path : ) {</code>

<code>                </code><code>file = File(path);</code>

<code>                </code><code>RequestBody requestBody = RequestBody.(MediaType.(), file);</code>

<code>                </code><code>MultipartBody.Part part = MultipartBody.Part.(, file.getName(), requestBody);</code>

<code>                </code><code>.add(part);</code>

<code>            </code><code>}</code>

<code>        </code><code>}</code>

<code>    </code><code>} (Exception e) {</code>

<code>        </code><code>e.printStackTrace();</code>

<code>    </code><code>}</code>

<code>    </code><code>;</code>

<code>}</code>

調用Retrofit 進行網絡請求,并将實體類資料和檔案資料一并發送到 服務端

<code>addEvent() {</code>

<code>    </code><code>Event entity = .getEntity();</code>

<code>    </code><code>List&lt;MultipartBody.Part&gt; fileMap = .getFilesMap();</code>

<code>    </code><code>.clear();</code>

<code>        </code><code>Subscription subscription = .getRetrofitInstance()</code>

<code>                </code><code>.create(EventInterface.)</code>

<code>                </code><code>.addEvent(entity, fileMap)</code>

<code>                </code><code>.subscribeOn(.io()).observeOn(.ui()).subscribe(Subscriber&lt;HttpResult&lt;String&gt;&gt;() {</code>

<code>                    </code><code>onCompleted() {</code>

<code>                    </code><code>}</code>

<code>                    </code><code>onError(Throwable e) {</code>

<code>                        </code><code>.setLoadingIndicator();</code>

<code>                        </code><code>e.printStackTrace();</code>

<code>                    </code><code>onNext(HttpResult&lt;String&gt; httpResult) {</code>

<code>                        </code><code>(httpResult.getResultCode() != ConstData.HttpResult.) {</code>

<code>                            </code><code>.setLoadingIndicator();</code>

<code>                        </code><code>} {</code>

<code>                        </code><code>}</code>

<code>                </code><code>});</code>

<code>        </code><code>.add(subscription);</code>

在webapi 端對檔案以及資料進行接收。由上面轉化MultipartBody   那一個環節我們可以看到,傳到服務端的資料是以HTTP形式傳送的。資料類型都是multipart/form-data類型的。是以我們在服務端要使用http相關協定來進行接收。

<code>               </code><code>[HttpPost]</code>

<code>        </code><code>public</code> <code>HttpResult&lt;string&gt; AddEvent()</code>

<code>        </code><code>{</code>

<code>            </code><code>//擷取EventET 的屬性</code>

<code>            </code><code>HttpRequest request = HttpContext.Current.Request;</code>

<code>            </code><code>string entity = request.Form[</code><code>0</code><code>];</code>

<code>            </code><code>BaseBN baseBN = </code><code>new</code> <code>BaseBN();</code>

<code>            </code><code>EventET et = baseBN.CTJsonSerializer&lt;EventET&gt;(entity);</code>

<code>            </code><code>SystemBN bn = </code><code>new</code> <code>SystemBN();</code>

<code>            </code><code>et.EVENT_ID = bn.CreateID(</code><code>"EVENT"</code><code>, HaiQu.N, </code><code>"EVENT_ID"</code><code>, </code><code>"EVENT"</code><code>, EventType.YiYou);</code>

<code>            </code><code>List&lt;string&gt; addr = </code><code>new</code> <code>List&lt;string&gt;();</code>

<code>            </code><code>//擷取上傳的檔案</code>

<code>            </code><code>HttpFileCollection coll = request.Files;</code>

<code>            </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i &lt; coll.Count; i++)</code>

<code>            </code><code>{</code>

<code>                </code><code>HttpPostedFile file = coll.Get(i);</code>

<code>                </code><code>String filename = file.FileName.Substring(file.FileName.LastIndexOf(</code><code>"\\"</code><code>) + </code><code>1</code><code>);</code>

<code>                </code><code>if</code> <code>(!Directory.Exists(System.Web.HttpContext.Current.Server.MapPath(</code><code>"~/Upload/"</code> <code>+ et.EVENT_ID)))</code><code>//如果不存在就建立file檔案夾</code>

<code>                </code><code>{</code>

<code>                    </code><code>Directory.CreateDirectory(System.Web.HttpContext.Current.Server.MapPath(</code><code>"~/Upload/"</code> <code>+ et.EVENT_ID));</code>

<code>                </code><code>}</code>

<code>                </code><code>string fileSavePath = string.Format(</code><code>"~/Upload/"</code> <code>+ et.EVENT_ID + </code><code>"/{0}"</code><code>, filename);</code>

<code>                </code><code>file.SaveAs(System.Web.HttpContext.Current.Server.MapPath(fileSavePath));</code>

<code>                </code><code>addr.Add(fileSavePath);</code>

<code>            </code><code>EventBN eventBN = </code><code>new</code> <code>EventBN();</code>

<code>            </code><code>HttpResult&lt;string&gt; result = eventBN.AddEvent(et, addr, HaiQu.N);</code>

<code>            </code><code>return</code> <code>result;</code>

<code>          </code> 

這裡有幾點需要注意,實體類的資料,傳輸到服務端的時候,會以JSON字元串的形式傳輸到背景。這樣的話,在背景使用的時候,需要對其進行反序列化。

另外,上傳的檔案,在HTTP中是以集合的形式存在,直接取出來,存儲到本地就好。有一點需要注意的是,由于IIS對上傳檔案的限制,需要提前修改一下允許上傳檔案的上限。要不然,會上傳不成功(這些都是已經踩過的坑)。

說在最後,其實上傳檔案很簡單,網上有很多的大神已經講解的非常詳細。之所又自己啰嗦了一下,是因為,在做的過程中,踩了很多的坑,而且網上大多數人都隻寫了Android端,沒有寫服務端。再加上,.NET WebApi 用的人比較小衆,是以就記錄了一下。以後有時間會補上Spring 作為服務端的寫法。以及Struts作為服務端的寫法。

今天就到這裡吧。

     本文轉自Eumenides_s 51CTO部落格,原文連結:http://blog.51cto.com/xiaoshuaigege/1878634,如需轉載請自行聯系原作者

繼續閱讀