Có ai biết cách sử dụng HttpClient
trong .Net 4.5 với multipart/form-data
tải lên không?
Tôi không thể tìm thấy bất kỳ ví dụ trên internet.
Có ai biết cách sử dụng HttpClient
trong .Net 4.5 với multipart/form-data
tải lên không?
Tôi không thể tìm thấy bất kỳ ví dụ trên internet.
Câu trả lời:
kết quả của tôi trông như thế này:
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(...)
có chứa một ký tự ranh giới không hợp lệ (có thể là dấu phân cách "/"). Không có lỗi, chỉ là không có tệp nào được đăng lên máy chủ - trong trường hợp của tôi, Context.Request.Files.Count = 0 trong bộ điều khiển API. Có thể chỉ là một Nancy
vấn đề, nhưng tôi đề nghị sử dụng một cái gì đó như DateTime.Now.Ticks.ToString("x")
thay thế.
key
và fileName
các tham số vào content
( bilddatei và upload.jpg trong ví dụ này).
Nó hoạt động ít nhiều như thế này (ví dụ sử dụng tệp hình ảnh / 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);
}
(Bạn có thể làm requestContent.Add()
bất cứ điều gì bạn muốn, hãy xem hậu duệ của HTTPContent để xem các loại có sẵn để truyền vào)
Khi hoàn thành, bạn sẽ tìm thấy nội dung phản hồi bên trong HttpResponseMessage.Content
mà bạn có thể sử dụng HttpContent.ReadAs*Async
.
// here you can specify boundary if you need---^
:)
async
trên dòng đầu tiên và await
trên dòng trước cuối cùng là không cần thiết.
Đây là một ví dụ về cách đăng chuỗi và luồng tệp bằng HTTPClient bằng MultipartFormDataContent. Bố trí nội dung và loại nội dung cần được chỉ định cho từng HTTPContent:
Đây là ví dụ của tôi. Hy vọng nó giúp:
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
. Kudos cho bạn thưa ngài
Content-Type
và Content-Disposition
vẫn ổn, nhưng trên Server 2008 R2 (IIS 7.5) không thể tìm thấy tệp, điều đó thật lạ. Vì vậy, tôi làm như câu trả lời.
Đây là một ví dụ khác về cách sử dụng HttpClient
để tải lên a multipart/form-data
.
Nó tải tệp lên API REST và bao gồm chính tệp đó (ví dụ: JPG) và các tham số API bổ sung. Các tập tin được tải lên trực tiếp từ đĩa cục bộ thông qua FileStream
.
Xem ở đây để biết ví dụ đầy đủ bao gồm logic cụ thể API bổ sung.
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);
}
Hãy thử nó làm việc cho tôi.
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()
kịch bản .NET Core của một bài kiểm tra tích hợp để tải lên dữ liệu + tệp.
Đây là một mẫu hoàn chỉnh làm việc cho tôi. Các boundary
giá trị trong yêu cầu được thêm tự động bởi .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;
Ví dụ với lõi tải trước Dotnet 3.0
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();
}
}
Tôi đang thêm một đoạn mã cho biết cách đăng một tệp lên API đã được phơi bày qua động từ XÓA http. Đây không phải là trường hợp phổ biến để tải lên một tệp với động từ XÓA http nhưng nó được cho phép. Tôi đã giả sử xác thực Windows NTLM để ủy quyền cuộc gọi.
Vấn đề mà người ta có thể gặp phải là tất cả sự quá tải của HttpClient.DeleteAsync
phương thức không có tham số nào cho HttpContent
cách chúng ta có được PostAsync
phương thức
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);
}
}
Bạn cần các không gian tên bên dưới ở đầu tệp C # của bạn:
using System;
using System.Net;
using System.IO;
using System.Net.Http;
PS Xin lỗi về rất nhiều khối sử dụng (mẫu IDis Dùng) trong mã của tôi. Thật không may, cú pháp sử dụng cấu trúc của C # không hỗ trợ khởi tạo nhiều biến trong một câu lệnh.
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;
}