Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Bagian 2: Unggah File dan MIME Multipart
Tutorial ini menunjukkan cara mengunggah file ke API web. Ini juga menjelaskan cara memproses data MIME multipihak.
Catatan
Berikut adalah contoh formulir HTML untuk mengunggah file:
<form name="form1" method="post" enctype="multipart/form-data" action="api/upload">
<div>
<label for="caption">Image Caption</label>
<input name="caption" type="text" />
</div>
<div>
<label for="image1">Image File</label>
<input name="image1" type="file" />
</div>
<div>
<input type="submit" value="Submit" />
</div>
</form>
Formulir ini berisi kontrol input teks dan kontrol input file. Ketika formulir berisi kontrol input file, atribut enctype harus selalu "multipart/form-data", yang menentukan bahwa formulir akan dikirim sebagai pesan MIME multipart.
Format pesan MIME multipihak paling mudah dipahami dengan melihat contoh permintaan:
POST http://localhost:50460/api/values/1 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------41184676334
Content-Length: 29278
-----------------------------41184676334
Content-Disposition: form-data; name="caption"
Summer vacation
-----------------------------41184676334
Content-Disposition: form-data; name="image1"; filename="GrandCanyon.jpg"
Content-Type: image/jpeg
(Binary data not shown)
-----------------------------41184676334--
Pesan ini dibagi menjadi dua bagian, satu untuk setiap kontrol formulir. Batas bagian ditunjukkan oleh garis yang dimulai dengan tanda hubung.
Catatan
Batas bagian mencakup komponen acak ("41184676334") untuk memastikan bahwa string batas tidak secara tidak sengaja muncul di dalam bagian pesan.
Setiap bagian pesan berisi satu atau beberapa header, diikuti oleh konten bagian.
- Header Content-Disposition menyertakan nama kontrol. Untuk file, ini juga berisi nama file.
- Header Jenis Konten menjelaskan data di bagian tersebut. Jika header ini dihilangkan, defaultnya adalah teks/biasa.
Dalam contoh sebelumnya, pengguna mengunggah file bernama GrandCanyon.jpg, dengan gambar jenis konten/jpeg; dan nilai input teks adalah "Summer Vacation".
Unggah File
Sekarang mari kita lihat pengontrol API Web yang membaca file dari pesan MIME multibagian. Pengontrol akan membaca file secara asinkron. WEB API mendukung tindakan asinkron menggunakan model pemrograman berbasis tugas. Pertama, berikut adalah kode jika Anda menargetkan .NET Framework 4.5, yang mendukung kata kunci asinkron dan menunggu.
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
public class UploadController : ApiController
{
public async Task<HttpResponseMessage> PostFormData()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
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);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
Perhatikan bahwa tindakan pengontrol tidak mengambil parameter apa pun. Itu karena kami memproses isi permintaan di dalam tindakan, tanpa memanggil formatter jenis media.
Metode IsMultipartContent memeriksa apakah permintaan berisi pesan MIME multipihak. Jika tidak, pengontrol mengembalikan kode status HTTP 415 (Jenis Media yang Tidak Didukung).
Kelas MultipartFormDataStreamProvider adalah objek pembantu yang mengalokasikan aliran file untuk file yang diunggah. Untuk membaca pesan MIME multibagian, panggil metode ReadAsMultipartAsync . Metode ini mengekstrak semua bagian pesan dan menulisnya ke dalam aliran yang disediakan oleh MultipartFormDataStreamProvider.
Ketika metode selesai, Anda bisa mendapatkan informasi tentang file dari properti FileData , yang merupakan kumpulan objek MultipartFileData .
- MultipartFileData.FileName adalah nama file lokal di server, tempat file disimpan.
- MultipartFileData.Headers berisi header bagian (bukan header permintaan). Anda dapat menggunakan ini untuk mengakses header Content_Disposition dan Tipe Konten.
Seperti namanya, ReadAsMultipartAsync adalah metode asinkron. Untuk melakukan pekerjaan setelah metode selesai, gunakan tugas kelanjutan (.NET 4.0) atau kata kunci tunggu (.NET 4.5).
Berikut adalah versi .NET Framework 4.0 dari kode sebelumnya:
public Task<HttpResponseMessage> PostFormData()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
// Read the form data and return an async task.
var task = Request.Content.ReadAsMultipartAsync(provider).
ContinueWith<HttpResponseMessage>(t =>
{
if (t.IsFaulted || t.IsCanceled)
{
Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
}
// 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);
}
return Request.CreateResponse(HttpStatusCode.OK);
});
return task;
}
Membaca Data Kontrol Formulir
Formulir HTML yang saya tampilkan sebelumnya memiliki kontrol input teks.
<div>
<label for="caption">Image Caption</label>
<input name="caption" type="text" />
</div>
Anda bisa mendapatkan nilai kontrol dari properti FormData dari MultipartFormDataStreamProvider.
public async Task<HttpResponseMessage> PostFormData()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
await Request.Content.ReadAsMultipartAsync(provider);
// Show all the key-value pairs.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
Trace.WriteLine(string.Format("{0}: {1}", key, val));
}
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
FormData adalah NameValueCollection yang berisi pasangan nama/nilai untuk kontrol formulir. Koleksi dapat berisi kunci duplikat. Pertimbangkan formulir ini:
<form name="trip_search" method="post" enctype="multipart/form-data" action="api/upload">
<div>
<input type="radio" name="trip" value="round-trip"/>
Round-Trip
</div>
<div>
<input type="radio" name="trip" value="one-way"/>
One-Way
</div>
<div>
<input type="checkbox" name="options" value="nonstop" />
Only show non-stop flights
</div>
<div>
<input type="checkbox" name="options" value="airports" />
Compare nearby airports
</div>
<div>
<input type="checkbox" name="options" value="dates" />
My travel dates are flexible
</div>
<div>
<label for="seat">Seating Preference</label>
<select name="seat">
<option value="aisle">Aisle</option>
<option value="window">Window</option>
<option value="center">Center</option>
<option value="none">No Preference</option>
</select>
</div>
</form>
Isi permintaan mungkin terlihat seperti ini:
-----------------------------7dc1d13623304d6
Content-Disposition: form-data; name="trip"
round-trip
-----------------------------7dc1d13623304d6
Content-Disposition: form-data; name="options"
nonstop
-----------------------------7dc1d13623304d6
Content-Disposition: form-data; name="options"
dates
-----------------------------7dc1d13623304d6
Content-Disposition: form-data; name="seat"
window
-----------------------------7dc1d13623304d6--
Dalam hal ini, koleksi FormData akan berisi pasangan kunci/nilai berikut:
- perjalanan: pulang-pergi
- opsi: nonstop
- opsi: tanggal
- seat: window