WebAPI通過multipart/form-data方式同時上傳文件以及數據(含HttpClient上傳Demo)
來源:程序員人生 發布時間:2015-06-19 09:09:44 閱讀次數:5093次
簡單的Demo,用于了解WebAPI如何同時接收文件及數據,同時提供HttpClient摹擬如何同時上傳文件和數據的Demo,下面是HttpClient上傳的Demo界面

1、HttpClient部份:
HttpClient通過PostAsync提交數據時,第2個要求參數為抽象類HttpContent,當前我們需要通過multipart/form-data的方式摹擬要求,multipart對應的要求HttpContent為MultipartContent及其子類MultipartFormDataContent,按名字明顯可以看出MultipartFormDataContent對應multipart/form-data,MultipartFormDataContent可以通過Add方法添加具體的HttpContent,這里固然是添加ByteArrayContent了
下面是分別獲得文件及鍵值對集合對應ByteArrayContent集合的代碼
/// <summary>
/// 獲得文件集合對應的ByteArrayContent集合
/// </summary>
/// <param name="files"></param>
/// <returns></returns>
private List<ByteArrayContent> GetFileByteArrayContent(HashSet<string> files)
{
List<ByteArrayContent> list = new List<ByteArrayContent>();
foreach (var file in files)
{
var fileContent = new ByteArrayContent(File.ReadAllBytes(file));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = Path.GetFileName(file)
};
list.Add(fileContent);
}
return list;
}
/// <summary>
/// 獲得鍵值集合對應的ByteArrayContent集合
/// </summary>
/// <param name="collection"></param>
/// <returns></returns>
private List<ByteArrayContent> GetFormDataByteArrayContent(NameValueCollection collection)
{
List<ByteArrayContent> list = new List<ByteArrayContent>();
foreach (var key in collection.AllKeys)
{
var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(collection[key]));
dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
Name = key
};
list.Add(dataContent);
}
return list;
}
然后提交Api部份的代碼以下(如需完全代碼,請至底部點擊源代碼下載鏈接)
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/" + this.cmbResponseContentType.Text.ToLower()));//設定要響應的數據格式
using (var content = new MultipartFormDataContent())//表明是通過multipart/form-data的方式上傳數據
{
var formDatas = this.GetFormDataByteArrayContent(this.GetNameValueCollection(this.gv_FormData));//獲得鍵值集合對應的ByteArrayContent集合
var files = this.GetFileByteArrayContent(this.GetHashSet(this.gv_File));//獲得文件集合對應的ByteArrayContent集合
Action<List<ByteArrayContent>> act = (dataContents) =>
{//聲明1個拜托,該拜托的作用就是將ByteArrayContent集合加入到MultipartFormDataContent中
foreach (var byteArrayContent in dataContents)
{
content.Add(byteArrayContent);
}
};
act(formDatas);//履行act
act(files);//履行act
try
{
var result = client.PostAsync(this.txtUrl.Text, content).Result;//post要求
this.txtResponse.Text = result.Content.ReadAsStringAsync().Result;//將響應結果顯示在文本框內
}
catch (Exception ex)
{
this.txtResponse.Text = ex.ToString();//將異常信息顯示在文本框內
}
}
}
2、WebAPI部份
其實WebAPI這部份真的沒甚么,完全是參考了國外大牛的代碼,不過某些不明了的地方在方法內有備注,有時間會去研究下如何才能實現無需保存文件至硬盤,便可獲得相應的數據流
[HttpPost]
public async Task<Dictionary<string, string>> Post(int id = 0)
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
Dictionary<string, string> dic = new Dictionary<string, string>();
string root = HttpContext.Current.Server.MapPath("~/App_Data");//指定要將文件存入的
服務器物理位置
var provider = new MultipartFormDataStreamProvider(root);
try
{
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the file names.
foreach (MultipartFileData file in provider.FileData)
{//接收文件
Trace.WriteLine(file.Headers.ContentDisposition.FileName);//獲得上傳文件實際的文件名
Trace.WriteLine("Server file path: " + file.LocalFileName);//獲得上傳文件在服務上默許的文件名
}//TODO:這樣做直接就將文件存到了指定目錄下,暫時不知道如何實現只接收文件數據流但其實不保存至
服務器的目錄下,由開發自行指定如何存儲,比如通過服務存到圖片
服務器
foreach (var key in provider.FormData.AllKeys)
{//接收FormData
dic.Add(key, provider.FormData[key]);
}
}
catch
{
throw;
}
return dic;
}
源代碼下載,運行Demo時請先調試服務端,然后開啟客戶端,如果缺少HttpClient對應的dll,請通過NuGet下載
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈