5.8多部分表单内容
将请求的内容类型设置为 multipart/form-data 并发送多部分表单内容。
将请求的内容类型设置为 multipart/form-data 并发送多部分表单内容。
HTTP 声明式请求通过 MultipartAttribute 特性来设置多部分表单内容。相应的 HTTP 声明式提取器实现为 MultipartDeclarativeExtractor 类型,该类型负责解析 MultipartAttribute 和 MultipartFormAttribute 特性并构建 HttpRequestBuilder 实例所需的多部分表单内容配置。
public interface IHttpService : IHttpDeclarative{ // 添加常见表单项内容 [Post("https://furion.net/")] Task<string> PostStringAsync( [Multipart] int id, [Multipart] string name, [Multipart] object obj, [Multipart] Stream stream, [Multipart("bytes")] byte[] byteArray, // 自定义表单名,还可以通过 FileName 属性指定文件名 [Multipart] StringContent content [Multipart] MultipartFile file); // 添加文件内容 [Post("https://furion.net/")] Task<string> PostStringAsync( [Multipart(AsFileFrom = FileSourceType.None)] string none, // 不做任何操作 [Multipart("files", AsFileFrom = FileSourceType.Path, ContentType = "image/jpeg")] string filePath, // 从本地文件路径中添加,不传 Content-Type 将自动根据文件扩展名解析 [Multipart("files", AsFileFrom = FileSourceType.Base64String)] string base64String, // 从 Base64 字符串文件中添加,不传 Content-Type 将自动根据文件扩展名解析 [Multipart("files", AsFileFrom = FileSourceType.Remote)] string remote); // 从互联网文件地址中添加,不传 Content-Type 将自动根据文件扩展名解析 // 添加对象内容,AsFormItem 为 false 时,对象属性会被解析并遍历,其属性将作为独立的表单项进行设置 [Post("https://furion.net/")] Task<string> PostStringAsync([Multipart(AsFormItem = false)] object obj); // 推荐使用 [MultipartObject] // 设置多部分表单内容的边界 [MultipartForm("--------------------")] [Post("https://furion.net/")] Task<string> PostStringAsync([Multipart] int id); // 设置表单名称命名策略(转换器) [Post("https://furion.net/")] [MultipartForm(NamingPolicy = FormNamingPolicy.CamelCase)] Task<string> PostStringAsync([MultipartObject] object obj); // 冻结参数类型将被忽略 [Post("https://furion.net/")] Task<string> PostStringAsync([Multipart] CancellationToken cancellationToken);}包含文件(或二进制数据)的复杂表单#
在处理包含基础数据与文件(或二进制数据)的复杂表单时,可以使用 [MultipartObject] 特性标记对应的复杂类型。其中,文件字段推荐使用 MultipartFile 类型声明文件字段。示例接口定义如下:
public interface IHttpService : IHttpDeclarative{ [Post("https://furion.net/")] Task<string> PostStringAsync([MultipartObject] FormClass data);}对应的模型类定义如下:
public class FormClass // 支持属性 [AliasAs] 定义别名{ public int Id { get; set; } public string Name { get; set; } public MultipartFile File { get; set; } // public IFormFile File { get; set; } // 注意:需要按照以下步骤配置}注意:若使用 IFormFile 替代 MultipartFile,需确保已注册 FormFileContentProcessor。可通过全局调用 .AddHttpContentProcessors(() => [new FormFileContentProcessor()]) 来完成注册:
在 Startup.cs 或 Program.cs 文件中,配置并注册 HttpRemote 服务,以启用 IFormFile 内容处理器功能:
services.AddHttpRemote(builder =>{ builder.AddHttpContentProcessors(() => [ new FormFileContentProcessor() ]);});通过这种方式,框架会自动将对象中的基本类型属性作为普通表单项提交,并将 MultipartFile 类型的属性作为文件上传内容进行正确编码和传输。
MultipartAttribute 标记的参数通过底层的 httpRequestBuilder.SetMultipartContent 方法进行设置,支持任意非冻结类型的参数。以下代码示例展示了如何使用 HttpRequestBuilder 达到相同配置效果:
// 添加常见表单项内容HttpRequestBuilder.Post("https://furion.net") .SetMultipartContent(multipart => { multipart.AddFormItem(1, "id"); multipart.AddFormItem("Furion", "name"); multipart.AddFormItem(new { id = 1, name = "Furion" }, "obj"); multipart.AddStream(stream, "stream"); multipart.AddByteArray(bytes, "bytes"); multipart.Add(stringContent, "content"); multipart.AddFile(Multipart.CreateFromPath("路径")); });// 添加文件内容HttpRequestBuilder.Post("https://furion.net") .SetMultipartContent(multipart => { multipart.AddFileAsStream(@"C:\Workspaces\httptest.jpg", "files", contentType: "image/jpeg"); multipart.AddFileFromBase64String("77u/5rWL6K+V5paH5Lu25YaF5a65", "files"); multipart.AddFileFromRemote("https://furion.net/img/furionlogo.png", "files"); });// 添加对象内容,AsFormItem 为 false 时,对象会被解析并遍历,其属性将作为独立的表单项进行设置HttpRequestBuilder.Post("https://furion.net") .SetMultipartContent(multipart => { multipart.AddObject(new { id = 1, name = "furion" }); // AsFormItem 为 false 相当于不设置表单名 });// 设置多部分表单内容的边界HttpRequestBuilder.Post("https://furion.net") .SetMultipartContent(multipart => { multipart.SetBoundary("--------------------"); multipart.AddFormItem(1, "id"); });// 添加复杂表单内容HttpRequestBuilder.Post("https://furion.net") .SetMultipartContent(multipart => { multipart.AddObject(new FormClass { Id = 1, Name = "furion", File = MultipartFile.CreateFromPath("文件路径") }); });对比上述两种发送多部分表单内容的方法,HTTP 声明式请求方式的代码结构更加条理分明,更易于进行组织、维护和复用。
MultipartAttribute 包含以下构造函数和属性:
-
构造函数:
new():作用于参数,将参数作为多部分表单项内容。new(name):作用于参数,将参数作为多部分表单项内容,支持设置表单名。
-
属性:
Name:表单名称(string类型)。FileName:文件的名称(string类型)。ContentType:内容类型(string类型)。ContentEncoding:内容编码(string类型)。AsFileFrom:表示将字符串作为多部分表单文件的来源(FileSourceType类型),用于设置多部分表单文件内容,仅当参数为字符串类型时有效。FileSourceType枚举包含以下选项:None(默认值):不用作为文件的来源。Path:作为本地文件路径。Base64String:作为Base64字符串文件。Remote:作为互联网文件地址。
AsFormItem:表示是否作为表单的一项(bool类型),默认值为true(作为),仅当参数为对象类型时有效。为false(不作为) 时,对象会被解析并遍历,其属性将作为独立的表单项进行设置。
MultipartFormAttribute 包含以下构造函数和属性:
-
构造函数:
new():作用于方法,配置多部分表单内容属性。new(boundary):作用于方法,配置多部分表单内容属性,支持设置多部分表单内容的边界。
-
属性:
Boundary:多部分表单内容的边界(string类型)。默认值为:$"----{DateTime.Now.Ticks:x}"。OmitContentType:是否移除默认的多部分内容Content-Type(bool类型)。默认值为true。NamingPolicy:表单名称命名策略(转换器)(FormNamingPolicy类型)。默认值为FormNamingPolicy.None。