在ASP.Net Web Api 2中使用PUT动词上传文件

我想使用HTTP PUT动词公开ASP.Net Web Api 2动作来上传文件。 这与我们的REST模型一致,因为API代表远程文件系统(类似于WebDAV,但实际上是简化的),因此客户端选择资源名称(因此PUT是理想的,POST不是一个合理的选择)。

Web Api文档描述了如何使用multipart / form-data表单上载文件 ,但没有描述如何使用PUT方法执行此操作。

您将使用什么来测试这样的API(HTML多部分表单不允许PUT动词)? 服务器实现是否类似于web api文档中描述的多部分实现(使用MultipartStreamProvider ),或者应该如下所示:

 [HttpPut] public async Task PutFile(string resourcePath) { Stream fileContent = await this.Request.Content.ReadAsStreamAsync(); bool isNew = await this._storageManager.UploadFile(resourcePath, fileContent); if (isNew) { return this.Request.CreateResponse(HttpStatusCode.Created); } else { return this.Request.CreateResponse(HttpStatusCode.OK); } } 

经过几次测试后,我发布的服务器端代码似乎是正确的。 这是一个示例,从任何身份validation/授权/error handling代码中删除:

 [HttpPut] [Route(@"api/storage/{*resourcePath?}")] public async Task PutFile(string resourcePath = "") { // Extract data from request Stream fileContent = await this.Request.Content.ReadAsStreamAsync(); MediaTypeHeaderValue contentTypeHeader = this.Request.Content.Headers.ContentType; string contentType = contentTypeHeader != null ? contentTypeHeader.MediaType : "application/octet-stream"; // Save the file to the underlying storage bool isNew = await this._dal.SaveFile(resourcePath, contentType, fileContent); // Return appropriate HTTP status code if (isNew) { return this.Request.CreateResponse(HttpStatusCode.Created); } else { return this.Request.CreateResponse(HttpStatusCode.OK); } } 

一个简单的控制台应用程序足以测试它(使用Web Api客户端库):

 using (var fileContent = new FileStream(@"C:\temp\testfile.txt", FileMode.Open)) using (var client = new HttpClient()) { var content = new StreamContent(fileContent); content.Headers.ContentType = new MediaTypeHeaderValue("text/plain"); client.BaseAddress = new Uri("http://localhost:81"); HttpResponseMessage response = await client.PutAsync(@"/api/storage/testfile.txt", content); } 

编辑2018-05-09:

如此注释中所述 ,如果您计划支持带有扩展名( {filename}.{extension} )的{filename}.{extension}而不强制客户端附加尾部斜杠,则需要修改web.config以将IIS绑定到Web这些文件类型的api应用程序,默认情况下,IIS将使用静态文件处理程序来处理看起来像文件名的内容(即包含点的最后一个路径段的URL)。 我的system.webServer部分如下所示:

                   

请注意,由于各种限制,某些文件名将无法使用。 例如,您无法命名路径段. 或者因为RFC需要替换它,Azure托管服务不允许冒号作为路径段的最后一个字符,并且IIS默认禁止一组字符。

您可能还希望增加IIS / ASP.NET文件上载大小限制: