posted at 2021.5.17 09:15 by Administrator
Web API通常不使用视图,如果调用客户端直接向服务器发送文件内容,而不是通过HTML<form>方式提交,那么Action方法使用IFormFile类型的参数是无法接收到数据的。一个简单的解决方法是直接从HttpContext对象中读取请求正文,并且这种方法也不用考虑content-type,正文都是二进制数据,以流的形式读入。
下面将演示一个允许客户端直接上传文件的Web API,并使用HTTP头来提供文件名。
该实例包含两个项目,除了主要的ASP.NET Core应用项目,还包括一个控制台TestClient项目,用于测试Web API的调用。
首先是ASP.NET Core项目的实现部分。
步骤1:定义控制器,包含UploadFile方法。
public class GuangBuController : Controller
{
[HttpPost]
public ActionResult UploadFile()
{
var request = HttpContext.Request;
Stream stream = request.Body;
byte[] data = null;
// 读取正文内容
using(MemoryStream ms = new MemoryStream())
{
stream.CopyTo(ms);
data = ms.ToArray();
}
// 提取文件名
string fileName = request.Headers["file-name"];
// 返回状态码 200
return Ok($"已成功上传文件 {fileName??"未知"},大小为 {data.Length} 字节");
}
}
由于此处仅做演示,并没有保存接收到的文件内容,所以只向调用方返回一条上传成功的应答消息。HttpRequest.Body属性就是HTTP请求的正文内容,以流的形式公开,并且是只读的。上述代码中,先将数据复制到内存流中,再转换为字节数组。
步骤2:在应用程序的Program类中修改对正文大小的限制。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseKestrel(o=>
{
o.Limits.MaxRequestBodySize = 5000000000;
});
MaxRequestBodySize属性限制的是请求正文的最大长度,一般只需要修改这一选项。
接下来实现一个测试的客户端项目。
步骤3:声明一些稍后要使用到的变量。
// 请求 URL
string url = "http://localhost:5000/guangbu/uploadfile";
// 测试文件名
string FileName = "sample.dat";
// 产生字节数
int byteCount = 8000;
步骤4:生成随机字节,稍后用于提交到Web服务器。
byte[] bytes = new byte[byteCount];
Random rand = new Random();
rand.NextBytes(bytes);
步骤5:向服务器发起请求,并接收响应消息。
using(HttpClient client = new HttpClient())
{
// 设置 HTTP 头
client.DefaultRequestHeaders.Add("file-name", FileName);
// 创建正文内容
ByteArrayContent content = new ByteArrayContent(bytes);
// 发起请求
Console.WriteLine("正在发送数据,请稍候……");
HttpResponseMessage response = await client.PostAsync(url, content);
string respmsg = await response.Content.ReadAsStringAsync();
Console.WriteLine($"服务器返回消息:\n{respmsg}");
}
步骤6:运行应用程序,结果如图所示。
7bc17ae6-7f5a-4f7c-a2b9-613ca2d5dba1|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04
Tags: Web, 程序, 代码, 方法, 类, 数据
IT技术