Qualcuno sa come utilizzare HttpClientin .Net 4.5 con multipart/form-dataupload?
Non sono riuscito a trovare esempi su Internet.
Qualcuno sa come utilizzare HttpClientin .Net 4.5 con multipart/form-dataupload?
Non sono riuscito a trovare esempi su Internet.
Risposte:
il mio risultato è simile al seguente:
public static async Task<string> Upload(byte[] image)
{
using (var client = new HttpClient())
{
using (var content =
new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)))
{
content.Add(new StreamContent(new MemoryStream(image)), "bilddatei", "upload.jpg");
using (
var message =
await client.PostAsync("http://www.directupload.net/index.php?mode=upload", content))
{
var input = await message.Content.ReadAsStringAsync();
return !string.IsNullOrWhiteSpace(input) ? Regex.Match(input, @"http://\w*\.directupload\.net/images/\d*/\w*\.[a-z]{3}").Value : null;
}
}
}
}
new MultipartFormDataContent(...)contenere un carattere di limite non valido (forse il separatore "/"). Nessun errore, solo nessun file pubblicato sul server - nel mio caso, Context.Request.Files.Count = 0 nel controller API. Forse solo un Nancyproblema, ma suggerisco di usare qualcosa di simile DateTime.Now.Ticks.ToString("x")invece.
keye fileNamea content( bilddatei e upload.jpg in questo esempio).
Funziona più o meno così (esempio usando un file immagine / jpg):
async public Task<HttpResponseMessage> UploadImage(string url, byte[] ImageData)
{
var requestContent = new MultipartFormDataContent();
// here you can specify boundary if you need---^
var imageContent = new ByteArrayContent(ImageData);
imageContent.Headers.ContentType =
MediaTypeHeaderValue.Parse("image/jpeg");
requestContent.Add(imageContent, "image", "image.jpg");
return await client.PostAsync(url, requestContent);
}
(Puoi fare requestContent.Add()quello che vuoi, dai un'occhiata al discendente di HttpContent per vedere i tipi disponibili da trasmettere)
Al termine, troverai il contenuto della risposta all'interno del HttpResponseMessage.Contentquale puoi consumare HttpContent.ReadAs*Async.
// here you can specify boundary if you need---^:)
asyncsulla prima riga e awaitsulla riga prima dell'ultima non sono necessarie.
Questo è un esempio di come inviare un flusso di stringhe e file con HTTPClient usando MultipartFormDataContent. La disposizione del contenuto e il tipo di contenuto devono essere specificati per ciascun contenuto HTTP:
Ecco il mio esempio Spero che sia d'aiuto:
private static void Upload()
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("User-Agent", "CBS Brightcove API Service");
using (var content = new MultipartFormDataContent())
{
var path = @"C:\B2BAssetRoot\files\596086\596086.1.mp4";
string assetName = Path.GetFileName(path);
var request = new HTTPBrightCoveRequest()
{
Method = "create_video",
Parameters = new Params()
{
CreateMultipleRenditions = "true",
EncodeTo = EncodeTo.Mp4.ToString().ToUpper(),
Token = "x8sLalfXacgn-4CzhTBm7uaCxVAPjvKqTf1oXpwLVYYoCkejZUsYtg..",
Video = new Video()
{
Name = assetName,
ReferenceId = Guid.NewGuid().ToString(),
ShortDescription = assetName
}
}
};
//Content-Disposition: form-data; name="json"
var stringContent = new StringContent(JsonConvert.SerializeObject(request));
stringContent.Headers.Add("Content-Disposition", "form-data; name=\"json\"");
content.Add(stringContent, "json");
FileStream fs = File.OpenRead(path);
var streamContent = new StreamContent(fs);
streamContent.Headers.Add("Content-Type", "application/octet-stream");
//Content-Disposition: form-data; name="file"; filename="C:\B2BAssetRoot\files\596090\596090.1.mp4";
streamContent.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\"" + Path.GetFileName(path) + "\"");
content.Add(streamContent, "file", Path.GetFileName(path));
//content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
Task<HttpResponseMessage> message = client.PostAsync("http://api.brightcove.com/services/post", content);
var input = message.Result.Content.ReadAsStringAsync();
Console.WriteLine(input.Result);
Console.Read();
}
}
}
MultipartFormDataContent. Complimenti, signore
Content-Typee Content-Dispositionva bene, ma su Server 2008 R2 (IIS 7.5) non riesco a trovare i file, è strano. Quindi faccio come risposta.
Ecco un altro esempio su come utilizzare HttpClientper caricare un multipart/form-data.
Carica un file su un'API REST e include il file stesso (ad esempio un JPG) e parametri API aggiuntivi. Il file viene caricato direttamente dal disco locale tramite FileStream.
Vedi qui per l'esempio completo che include la logica aggiuntiva API specifica.
public static async Task UploadFileAsync(string token, string path, string channels)
{
// we need to send a request with multipart/form-data
var multiForm = new MultipartFormDataContent();
// add API method parameters
multiForm.Add(new StringContent(token), "token");
multiForm.Add(new StringContent(channels), "channels");
// add file and directly upload it
FileStream fs = File.OpenRead(path);
multiForm.Add(new StreamContent(fs), "file", Path.GetFileName(path));
// send request to API
var url = "https://slack.com/api/files.upload";
var response = await client.PostAsync(url, multiForm);
}
Prova questo funziona per me.
private static async Task<object> Upload(string actionUrl)
{
Image newImage = Image.FromFile(@"Absolute Path of image");
ImageConverter _imageConverter = new ImageConverter();
byte[] paramFileStream= (byte[])_imageConverter.ConvertTo(newImage, typeof(byte[]));
var formContent = new MultipartFormDataContent
{
// Send form text values here
{new StringContent("value1"),"key1"},
{new StringContent("value2"),"key2" },
// Send Image Here
{new StreamContent(new MemoryStream(paramFileStream)),"imagekey","filename.jpg"}
};
var myHttpClient = new HttpClient();
var response = await myHttpClient.PostAsync(actionUrl.ToString(), formContent);
string stringContent = await response.Content.ReadAsStringAsync();
return response;
}
TestServer.CreatClient()scenario .NET Core di un test di integrazione per un caricamento di dati + file.
Ecco un esempio completo che ha funzionato per me. Il boundaryvalore nella richiesta viene aggiunto automaticamente da .NET.
var url = "http://localhost/api/v1/yourendpointhere";
var filePath = @"C:\path\to\image.jpg";
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
FileStream fs = File.OpenRead(filePath);
var streamContent = new StreamContent(fs);
var imageContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
form.Add(imageContent, "image", Path.GetFileName(filePath));
var response = httpClient.PostAsync(url, form).Result;
Esempio con preloader Dotnet 3.0 Core
ProgressMessageHandler processMessageHander = new ProgressMessageHandler();
processMessageHander.HttpSendProgress += (s, e) =>
{
if (e.ProgressPercentage > 0)
{
ProgressPercentage = e.ProgressPercentage;
TotalBytes = e.TotalBytes;
progressAction?.Invoke(progressFile);
}
};
using (var client = HttpClientFactory.Create(processMessageHander))
{
var uri = new Uri(transfer.BackEndUrl);
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", AccessToken);
using (MultipartFormDataContent multiForm = new MultipartFormDataContent())
{
multiForm.Add(new StringContent(FileId), "FileId");
multiForm.Add(new StringContent(FileName), "FileName");
string hash = "";
using (MD5 md5Hash = MD5.Create())
{
var sb = new StringBuilder();
foreach (var data in md5Hash.ComputeHash(File.ReadAllBytes(FullName)))
{
sb.Append(data.ToString("x2"));
}
hash = result.ToString();
}
multiForm.Add(new StringContent(hash), "Hash");
using (FileStream fs = File.OpenRead(FullName))
{
multiForm.Add(new StreamContent(fs), "file", Path.GetFileName(FullName));
var response = await client.PostAsync(uri, multiForm);
progressFile.Message = response.ToString();
if (response.IsSuccessStatusCode) {
progressAction?.Invoke(progressFile);
} else {
progressErrorAction?.Invoke(progressFile);
}
response.EnsureSuccessStatusCode();
}
}
}
X509Certificate clientKey1 = null;
clientKey1 = new X509Certificate(AppSetting["certificatePath"],
AppSetting["pswd"]);
string url = "https://EndPointAddress";
FileStream fs = File.OpenRead(FilePath);
var streamContent = new StreamContent(fs);
var FileContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
FileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("ContentType");
var handler = new WebRequestHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ClientCertificates.Add(clientKey1);
handler.ServerCertificateValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) =>
{
return true;
};
using (var client = new HttpClient(handler))
{
// Post it
HttpResponseMessage httpResponseMessage = client.PostAsync(url, FileContent).Result;
if (!httpResponseMessage.IsSuccessStatusCode)
{
string ss = httpResponseMessage.StatusCode.ToString();
}
}
Sto aggiungendo uno snippet di codice che mostra come inviare un file a un'API che è stata esposta tramite il comando DELETE http verbo. Questo non è un caso comune per caricare un file con il comando DELETE http verbo ma è permesso. Ho assunto l'autenticazione di Windows NTLM per autorizzare la chiamata.
Il problema che si potrebbe incontrare è che tutti i sovraccarichi del HttpClient.DeleteAsyncmetodo non hanno parametri per HttpContentil modo in cui lo otteniamo nel PostAsyncmetodo
var requestUri = new Uri("http://UrlOfTheApi");
using (var streamToPost = new MemoryStream("C:\temp.txt"))
using (var fileStreamContent = new StreamContent(streamToPost))
using (var httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true })
using (var httpClient = new HttpClient(httpClientHandler, true))
using (var requestMessage = new HttpRequestMessage(HttpMethod.Delete, requestUri))
using (var formDataContent = new MultipartFormDataContent())
{
formDataContent.Add(fileStreamContent, "myFile", "temp.txt");
requestMessage.Content = formDataContent;
var response = httpClient.SendAsync(requestMessage).GetAwaiter().GetResult();
if (response.IsSuccessStatusCode)
{
// File upload was successfull
}
else
{
var erroResult = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
throw new Exception("Error on the server : " + erroResult);
}
}
È necessario sotto gli spazi dei nomi nella parte superiore del file C #:
using System;
using System.Net;
using System.IO;
using System.Net.Http;
PS Mi dispiace per così tanti blocchi usando (modello IDisposable) nel mio codice. Sfortunatamente, la sintassi dell'uso del costrutto di C # non supporta l'inizializzazione di più variabili in una singola istruzione.
public async Task<object> PassImageWithText(IFormFile files)
{
byte[] data;
string result = "";
ByteArrayContent bytes;
MultipartFormDataContent multiForm = new MultipartFormDataContent();
try
{
using (var client = new HttpClient())
{
using (var br = new BinaryReader(files.OpenReadStream()))
{
data = br.ReadBytes((int)files.OpenReadStream().Length);
}
bytes = new ByteArrayContent(data);
multiForm.Add(bytes, "files", files.FileName);
multiForm.Add(new StringContent("value1"), "key1");
multiForm.Add(new StringContent("value2"), "key2");
var res = await client.PostAsync(_MEDIA_ADD_IMG_URL, multiForm);
}
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
return result;
}