J'envoie des données de formulaire en plusieurs parties à mon API Web, comme ceci:
string example = "my string";
HttpContent stringContent = new StringContent(example);
HttpContent fileStreamContent = new StreamContent(stream);
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
content.Add(stringContent, "example", "example");
content.Add(fileStreamContent, "stream", "stream");
var uri = "http://localhost:58690/api/method";
HttpResponseMessage response = await client.PostAsync(uri, content);
et voici l'API Web:
[HttpPost]
[Route("api/method")]
public async Task<HttpResponseMessage> Method()
{
// take contents and do something
}
Comment lire la chaîne et le flux du corps de la demande dans mon API Web?
Cela devrait vous aider à démarrer:
var uploadPath = HostingEnvironment.MapPath("/") + @"/Uploads";
Directory.CreateDirectory(uploadPath);
var provider = new MultipartFormDataStreamProvider(uploadPath);
await Request.Content.ReadAsMultipartAsync(provider);
// Files
//
foreach (MultipartFileData file in provider.FileData)
{
Debug.WriteLine(file.Headers.ContentDisposition.FileName);
Debug.WriteLine("File path: " + file.LocalFileName);
}
// Form data
//
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
Debug.WriteLine(string.Format("{0}: {1}", key, val));
}
}
C'est le code que j'ai utilisé auparavant pour recevoir des données JSON + un fichier facultatif:
var result = await Request.Content.ReadAsMultipartAsync();
var requestJson = await result.Contents[0].ReadAsStringAsync();
var request = JsonConvert.DeserializeObject<MyRequestType>(requestJson);
if (result.Contents.Count > 1)
{
var fileByteArray = await result.Contents[1].ReadAsByteArrayAsync();
...
}
C’est vraiment bien que vous puissiez combiner différents types de données dans une requête comme celle-ci.
Edit: un exemple de comment envoyer cette demande:
let serialisedJson = JSON.stringify(anyObject);
let formData = new FormData();
formData.append('initializationData', serialisedJson);
// fileObject is an instance of File
if (fileObject) {
// the 'jsonFile' name might cause some confusion:
// in this case, the uploaded file is actually a textfile containing json data
formData.append('jsonFile', fileObject);
}
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open('POST', 'http://somewhere.com', true);
xhr.onload = function(e: any) {
if (e.target.status === 200) {
resolve(JSON.parse(e.target.response));
}
else {
reject(JSON.parse(e.target.response));
}
};
xhr.send(formData);
});
Vous pouvez lire le contenu et obtenir toutes les informations sur le fichier (dans mon exemple) sans être copié sur le disque local de cette manière:
public async Task<IHttpActionResult> UploadFile()
{
if (!Request.Content.IsMimeMultipartContent())
{
return StatusCode(HttpStatusCode.UnsupportedMediaType);
}
var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();
foreach (var stream in filesReadToProvider.Contents)
{
// Getting of content as byte[], picture name and picture type
var fileBytes = await stream.ReadAsByteArrayAsync();
var pictureName = stream.Headers.ContentDisposition.FileName;
var contentType = stream.Headers.ContentType.MediaType;
}
}
Pour envoyer plus d'un fichier
System.Web.HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files;
//// CHECK THE FILE COUNT.
for (int iCnt = 0; iCnt <= hfc.Count - 1; iCnt++)
{
System.Web.HttpPostedFile hpf = hfc[iCnt];
string Image = UploadDocuments.GetDocumentorfileUri(hpf);
UploadDocuments.UploadDocumentsIntoData(Image, hpf.FileName, id);
}
// read the file content without copying to local disk and write the content byte to file
try
{
var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
foreach (var stream in filesReadToProvider.Contents)
{
//getting of content as byte[], picture name and picture type
var fileBytes = await stream.ReadAsByteArrayAsync();
var fileName = stream.Headers.ContentDisposition.Name;
var pictureName = stream.Headers.ContentDisposition.FileName;
var contentType = stream.Headers.ContentType.MediaType;
var path = Path.Combine(HttpContext.Current.Server.MapPath("~/Images/Upload/"), json_serializer.Deserialize<string>(pictureName));
File.WriteAllBytes(path, fileBytes);
}
return Request.CreateResponse(HttpStatusCode.OK);
}catch(Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
}