进入2023的3月了,又开始忙碌的码上生活了,前不久对接某个第3方的厂商要发送照片给它们,于是就用上了这个东东,C#使用HttpClient发送文件的场景较为常见,尤其是基于 .net 6以上来写一些底层的方法,这不,前几天就又封装了一下HttpClient发送文件到第3方的功能
进入2023的3月了,又开始忙碌的码上生活了,前不久对接某个第3方的厂商要发送照片给它们,于是就用上了这个东东,C#使用HttpClient发送文件的场景较为常见,尤其是基于 .net 6 以上来写一些底层的方法,这不,前几天就又封装了一下HttpClient发送文件到第3方的功能,或者你可以理解为其实就是C#的HttpClient上传文件。
为了使用 HttpClient 在请求中发送文件,将文件添加到 MultipartFormDataContent 对象中,并将该对象作为请求内容发送。这是一个例子:
var filePath = @ "C:\jhrs.com.png" ;
using ( var multipartFormContent = new MultipartFormDataContent ())
var fileStreamContent = new StreamContent ( File. OpenRead ( filePath )) ;
fileStreamContent. Headers . ContentType = new MediaTypeHeaderValue ( "image/png" ) ;
multipartFormContent. Add ( fileStreamContent, name: "file" , fileName: "jhrs.com.png" ) ;
var response = await httpClient. PostAsync ( "https://jhrs.com/files/" , multipartFormContent ) ;
response. EnsureSuccessStatusCode () ;
return await response. Content . ReadAsStringAsync () ;
var filePath = @"C:\jhrs.com.png";
using (var multipartFormContent = new MultipartFormDataContent())
{
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
multipartFormContent.Add(fileStreamContent, name: "file", fileName: "jhrs.com.png");
var response = await httpClient.PostAsync("https://jhrs.com/files/", multipartFormContent);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
var filePath = @"C:\jhrs.com.png";
using (var multipartFormContent = new MultipartFormDataContent())
{
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
multipartFormContent.Add(fileStreamContent, name: "file", fileName: "jhrs.com.png");
var response = await httpClient.PostAsync("https://jhrs.com/files/", multipartFormContent);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
这会发送以下 multipart/form-data POST 请求:
POST https: //jhrs.com/files/ HTTP/1.1
Content-Type: multipart/form-data; boundary= "44b2ed38-1ac7-4731-b2f4-f84bf159748d"
--44b2ed38-1ac7- 4731 -b2f4-f84bf159748d
Content-Disposition: form-data; name=file; filename=jhrs. com . png ; filename*=utf- 8 '' jhrs. com . png
POST https://jhrs.com/files/ HTTP/1.1
Host: jhrs.com
Content-Type: multipart/form-data; boundary="44b2ed38-1ac7-4731-b2f4-f84bf159748d"
Content-Length: 7279
--44b2ed38-1ac7-4731-b2f4-f84bf159748d
Content-Type: image/png
Content-Disposition: form-data; name=file; filename=jhrs.com.png; filename*=utf-8''jhrs.com.png
<bytes>
POST https://jhrs.com/files/ HTTP/1.1
Host: jhrs.com
Content-Type: multipart/form-data; boundary="44b2ed38-1ac7-4731-b2f4-f84bf159748d"
Content-Length: 7279
--44b2ed38-1ac7-4731-b2f4-f84bf159748d
Content-Type: image/png
Content-Disposition: form-data; name=file; filename=jhrs.com.png; filename*=utf-8''jhrs.com.png
<bytes>
在本文中,我将解释有关 MultipartFormDataContent 的一些细节,并展示一些其他文件发送场景。
C#使用HttpClient发送文件3月工作记录
C#使用HttpClient发送文件
先前调用第3方的接口,要求发送的表单数据里面要求有文件,【你可以理解为混合表单内容,即包含文件和其它参数(值是字符串,就跟web表单一样)】因程序直接使用的是.net 7来开发的,那么理所当然的使用HttpClient发送文件喽。
这就要求你构造 MultipartFormDataContent 参数,然后调用它的Add方法,Add方法有多个重载版本,满足不同的使用场景。
public void Add ( HttpContent content, string name, string fileName ) ;
public void Add(HttpContent content, string name, string fileName);
public void Add(HttpContent content, string name, string fileName);
name参数是表单字段名称。 将其设置为 Web API 定义的参数名称(如果它使用自动映射)。
fileName参数是原始文件名。 当您处置 MultipartFormDataContent 时,它会处置您添加到其中的所有 HttpContent 对象。此外,当您处置 StreamContent 时,它会处置底层文件流。由于这种级联处理,您只需要一个using 块 (如果您喜欢那种风格,也可以使用 using 声明 )。简而言之,MultipartFormDataContent 处理 StreamContent 对象,后者处理 FileStream 对象。
发送一个文件多字段表单数据
当您需要发送文件时,您可能需要将它与某个实体相关联。换句话说,您需要将其它字段与文件一起发送。最简单的方法是将所有内容添加到 MultipartFormDataContent。
C#使用HttpClient发送文件3月工作记录
例如,假设您要发送文件并且需要包含Title和UserId。除了添加文件之外,您还可以将标题和UserID 字段添加到表单数据中,如下所示:
var filePath = @ "C:\jhrs.com.png" ;
using ( var multipartFormContent = new MultipartFormDataContent ())
multipartFormContent. Add ( new StringContent ( "jhrs.com.user" ) , name: "UserId" ) ;
multipartFormContent. Add ( new StringContent ( "江湖人士网,一个分享赚被动收入的网站" ) , name: "Title" ) ;
var fileStreamContent = new StreamContent ( File. OpenRead ( filePath )) ;
fileStreamContent. Headers . ContentType = new MediaTypeHeaderValue ( "image/png" ) ;
multipartFormContent. Add ( fileStreamContent, name: "file" , fileName: "jhrs.com.png" ) ;
var response = await httpClient. PostAsync ( "https://jhrs.com/files/" , multipartFormContent ) ;
response. EnsureSuccessStatusCode () ;
return await response. Content . ReadAsStringAsync () ;
var filePath = @"C:\jhrs.com.png";
using (var multipartFormContent = new MultipartFormDataContent())
{
multipartFormContent.Add(new StringContent("jhrs.com.user"), name: "UserId");
multipartFormContent.Add(new StringContent("江湖人士网,一个分享赚被动收入的网站"), name: "Title");
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
multipartFormContent.Add(fileStreamContent, name: "file", fileName: "jhrs.com.png");
var response = await httpClient.PostAsync("https://jhrs.com/files/", multipartFormContent);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
var filePath = @"C:\jhrs.com.png";
using (var multipartFormContent = new MultipartFormDataContent())
{
multipartFormContent.Add(new StringContent("jhrs.com.user"), name: "UserId");
multipartFormContent.Add(new StringContent("江湖人士网,一个分享赚被动收入的网站"), name: "Title");
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
multipartFormContent.Add(fileStreamContent, name: "file", fileName: "jhrs.com.png");
var response = await httpClient.PostAsync("https://jhrs.com/files/", multipartFormContent);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
这将发送以下 multipart/form-data 请求。请注意,它包括 Title 和 UserId 字段的部分:
POST https: //jhrs.com/files/ HTTP/1.1
Content-Type: multipart/form-data; boundary= "00d335a2-0389-48e1-85d9-0daf70c2879e"
--00d335a2- 0389 - 48e1 -85d9-0daf70c2879e
Content-Type: text/plain; charset=utf- 8
Content-Disposition: form-data; name=UserId
--00d335a2- 0389 - 48e1 -85d9-0daf70c2879e
Content-Type: text/plain; charset=utf- 8
Content-Disposition: form-data; name=Title
--00d335a2- 0389 - 48e1 -85d9-0daf70c2879e
Content-Disposition: form-data; name=file; filename=jhrs. com . png ; filename*=utf- 8 '' jhrs. com . png
POST https://jhrs.com/files/ HTTP/1.1
Host: jhrs.com
Content-Type: multipart/form-data; boundary="00d335a2-0389-48e1-85d9-0daf70c2879e"
Content-Length: 7519
--00d335a2-0389-48e1-85d9-0daf70c2879e
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=UserId
jhrs.com.user
--00d335a2-0389-48e1-85d9-0daf70c2879e
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=Title
江湖人士网,一个分享赚被动收入的网站
--00d335a2-0389-48e1-85d9-0daf70c2879e
Content-Type: image/png
Content-Disposition: form-data; name=file; filename=jhrs.com.png; filename*=utf-8''jhrs.com.png
<bytes>
POST https://jhrs.com/files/ HTTP/1.1
Host: jhrs.com
Content-Type: multipart/form-data; boundary="00d335a2-0389-48e1-85d9-0daf70c2879e"
Content-Length: 7519
--00d335a2-0389-48e1-85d9-0daf70c2879e
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=UserId
jhrs.com.user
--00d335a2-0389-48e1-85d9-0daf70c2879e
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=Title
江湖人士网,一个分享赚被动收入的网站
--00d335a2-0389-48e1-85d9-0daf70c2879e
Content-Type: image/png
Content-Disposition: form-data; name=file; filename=jhrs.com.png; filename*=utf-8''jhrs.com.png
<bytes>
文件用字节数组发送
如果您已经有一个字节数组,并且不需要将文件作为文件流 加载,那么您可以使用 ByteArrayContent 而不是 StreamContent。这是一个例子:
using ( var multipartFormContent = new MultipartFormDataContent ())
var byteContent = new ByteArrayContent ( fileBytesFromDatabase ) ;
byteContent. Headers . ContentType = new MediaTypeHeaderValue ( "image/png" ) ;
multipartFormContent. Add ( byteContent, name: "file" , fileName: "jhrs.com.png" ) ;
var response = await httpClient. PostAsync ( "https://jhrs.com/files/" , multipartFormContent ) ;
response. EnsureSuccessStatusCode () ;
return await response. Content . ReadAsStringAsync () ;
using (var multipartFormContent = new MultipartFormDataContent())
{
var byteContent = new ByteArrayContent(fileBytesFromDatabase);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
multipartFormContent.Add(byteContent, name: "file", fileName: "jhrs.com.png");
var response = await httpClient.PostAsync("https://jhrs.com/files/", multipartFormContent);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
using (var multipartFormContent = new MultipartFormDataContent())
{
var byteContent = new ByteArrayContent(fileBytesFromDatabase);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
multipartFormContent.Add(byteContent, name: "file", fileName: "jhrs.com.png");
var response = await httpClient.PostAsync("https://jhrs.com/files/", multipartFormContent);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
这会生成以下请求:
POST https: //jhrs.com/files/ HTTP/1.1
Content-Type: multipart/form-data; boundary= "f4186b10-2cf4-4497-9a65-6e592d6cfce1"
--f4186b10-2cf4- 4497 -9a65- 6e592 d6cfce1
Content-Disposition: form-data; name=file; filename=house. png ; filename*=utf- 8 '' jhrs. com . png
POST https://jhrs.com/files/ HTTP/1.1
Host: jhrs.com
Content-Type: multipart/form-data; boundary="f4186b10-2cf4-4497-9a65-6e592d6cfce1"
Content-Length: 7243
--f4186b10-2cf4-4497-9a65-6e592d6cfce1
Content-Type: image/png
Content-Disposition: form-data; name=file; filename=house.png; filename*=utf-8''jhrs.com.png
<bytes>
POST https://jhrs.com/files/ HTTP/1.1
Host: jhrs.com
Content-Type: multipart/form-data; boundary="f4186b10-2cf4-4497-9a65-6e592d6cfce1"
Content-Length: 7243
--f4186b10-2cf4-4497-9a65-6e592d6cfce1
Content-Type: image/png
Content-Disposition: form-data; name=file; filename=house.png; filename*=utf-8''jhrs.com.png
<bytes>
发送多个文件
发送多个文件有两种方式:
使用相同的名称 参数发送多个文件。
使用自己的名称 参数发送每个文件。
您选择哪个选项取决于 Web API 的配置方式。这是第一个选项的示例——使用相同的名称 参数发送多个文件:
var filePaths = new string [] { @ "C:\jhrs.com.png" , @ "C:\znlive.com.png" } ;
using ( var multipartFormContent = new MultipartFormDataContent ())
foreach ( var filePath in filePaths )
var fileName = Path. GetFileName ( filePath ) ;
var fileStreamContent = new StreamContent ( File. OpenRead ( filePath )) ;
fileStreamContent. Headers . ContentType = new MediaTypeHeaderValue ( "image/png" ) ;
multipartFormContent. Add ( fileStreamContent, name: "files" , fileName: fileName ) ;
var response = await httpClient. PostAsync ( "https://jhrs.com/files/" , multipartFormContent ) ;
response. EnsureSuccessStatusCode () ;
return await response. Content . ReadAsStringAsync () ;
var filePaths = new string[] { @"C:\jhrs.com.png", @"C:\znlive.com.png" };
using (var multipartFormContent = new MultipartFormDataContent())
{
foreach(var filePath in filePaths)
{
var fileName = Path.GetFileName(filePath);
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
multipartFormContent.Add(fileStreamContent, name: "files", fileName: fileName);
}
var response = await httpClient.PostAsync("https://jhrs.com/files/", multipartFormContent);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
var filePaths = new string[] { @"C:\jhrs.com.png", @"C:\znlive.com.png" };
using (var multipartFormContent = new MultipartFormDataContent())
{
foreach(var filePath in filePaths)
{
var fileName = Path.GetFileName(filePath);
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
multipartFormContent.Add(fileStreamContent, name: "files", fileName: fileName);
}
var response = await httpClient.PostAsync("https://jhrs.com/files/", multipartFormContent);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
这会发送以下请求:
POST https: //jhrs.com/files/ HTTP/1.1
Content-Type: multipart/form-data; boundary= "92f8b9da-896f-41ff-8709-85a0b8d0ef08"
--92f8b9da-896f-41ff- 8709 -85a0b8d0ef08
Content-Disposition: form-data; name=files; filename=house. png ; filename*=utf- 8 '' jhrs. com . png
--92f8b9da-896f-41ff- 8709 -85a0b8d0ef08
Content-Disposition: form-data; name=files; filename=car. png ; filename*=utf- 8 '' znlive. com . png
POST https://jhrs.com/files/ HTTP/1.1
Host: jhrs.com
Content-Type: multipart/form-data; boundary="92f8b9da-896f-41ff-8709-85a0b8d0ef08"
Content-Length: 14442
--92f8b9da-896f-41ff-8709-85a0b8d0ef08
Content-Type: image/png
Content-Disposition: form-data; name=files; filename=house.png; filename*=utf-8''jhrs.com.png
<bytes>
--92f8b9da-896f-41ff-8709-85a0b8d0ef08
Content-Type: image/png
Content-Disposition: form-data; name=files; filename=car.png; filename*=utf-8''znlive.com.png
<bytes>
POST https://jhrs.com/files/ HTTP/1.1
Host: jhrs.com
Content-Type: multipart/form-data; boundary="92f8b9da-896f-41ff-8709-85a0b8d0ef08"
Content-Length: 14442
--92f8b9da-896f-41ff-8709-85a0b8d0ef08
Content-Type: image/png
Content-Disposition: form-data; name=files; filename=house.png; filename*=utf-8''jhrs.com.png
<bytes>
--92f8b9da-896f-41ff-8709-85a0b8d0ef08
Content-Type: image/png
Content-Disposition: form-data; name=files; filename=car.png; filename*=utf-8''znlive.com.png
<bytes>
请注意,每个文件都放在自己的部分(由边界字符串分隔)。
设置文件的内容类型
图像文件“jhrs.com.png”的内容类型为“image/png”,它被添加为文件内容标题,包含以下行:
fileStreamContent. Headers . ContentType = new MediaTypeHeaderValue ( "image/png" ) ;
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
这会在多部分请求的文件部分中设置 Content-Type 标头:
--f4186b10-2cf4- 4497 -9a65- 6e592 d6cfce1
Content-Disposition: form-data; name=file; filename=jhrs. com . png ; filename*=utf- 8 '' jhrs. com . png
--f4186b10-2cf4-4497-9a65-6e592d6cfce1
Content-Type: image/png
Content-Disposition: form-data; name=file; filename=jhrs.com.png; filename*=utf-8''jhrs.com.png
--f4186b10-2cf4-4497-9a65-6e592d6cfce1
Content-Type: image/png
Content-Disposition: form-data; name=file; filename=jhrs.com.png; filename*=utf-8''jhrs.com.png
如果您要集成的 Web API 要求您设置文件的 Content-Type,那么您必须明确设置它(它不会自动设置)。您可以根据文件的扩展名设置它(或者在适当的情况下对其进行硬编码)。这是一个例子:
var map = new Dictionary < string, string >( StringComparer. OrdinalIgnoreCase )
var filePath = @ "C:\jhrs.com.png" ;
var extension = Path. GetExtension ( filePath ) ;
if ( !map. TryGetValue ( extension, out string contentType ))
throw new Exception ( "不允许发送的类型。" ) ;
var fileStreamContent = new StreamContent ( File. OpenRead ( filePath )) ;
fileStreamContent. Headers . ContentType = new MediaTypeHeaderValue ( contentType ) ;
var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
[".png"] = "image/png",
[".jpg"] = "image/jpeg",
[".gif"] = "image/gif"
};
var filePath = @"C:\jhrs.com.png";
var extension = Path.GetExtension(filePath);
if (!map.TryGetValue(extension, out string contentType))
{
throw new Exception("不允许发送的类型。");
}
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
[".png"] = "image/png",
[".jpg"] = "image/jpeg",
[".gif"] = "image/gif"
};
var filePath = @"C:\jhrs.com.png";
var extension = Path.GetExtension(filePath);
if (!map.TryGetValue(extension, out string contentType))
{
throw new Exception("不允许发送的类型。");
}
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
有关映射的完整列表,请参阅 .NET FileExtensionContentTypeProvider 源代码。 由于该类只是 Dictionary<string, string> 的包装器,我建议添加您自己的映射,仅包含与您相关的文件扩展名(就像我在上面所做的那样)。
注意:如果你想使用 FileExtensionContentTypeProvider,它在 Microsoft.AspNetCore.StaticFiles 包中 。
【江湖人士】(jhrs.com)原创文章,作者:江小编,如若转载,请注明出处:https://jhrs.com/2023/46136.html
扫码加入电报群,让你获得国外网赚一手信息。
文章标题:C#使用HttpClient发送文件3月工作记录