c# – 在ASP.Net Web Api 2中使用PUT动词上传文件
我想使用HTTP PUT动词公开ASP.Net Web Api 2动作来上传文件.这与我们的REST模型一致,因为API代表一个远程文件系统(类似于WebDAV,但实际上是简化的),因此客户端选择资源名称(因此PUT是理想的,POST不是一个合理的选择).
Web Api文档描述了how to upload files using multipart/form-data forms,但没有描述如何使用PUT方法. 您将使用什么来测试这样的API(HTML多部分表单不允许PUT动词)?服务器实现是否类似于the web api documentation中描述的多部分实现(使用MultipartStreamProvider),或者应该如下所示: [HttpPut] public async Task<HttpResponseMessage> 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); } } 解决方法
经过几次测试后,我发布的服务器端代码似乎是正确的.这是一个示例,从任何身份验证/授权/错误处理代码中删除:
[HttpPut] [Route(@"api/storage/{*resourcePath?}")] public async Task<HttpResponseMessage> 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:temptestfile.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: 如this comment中所述,如果您计划支持带扩展名({filename}.{extension})的文件名而不强制客户端附加尾部斜杠,则需要修改web.config以将IIS绑定到Web api这些文件类型的应用程序,默认情况下IIS将使用静态文件处理程序来处理看起来像文件名的内容(即包含点的最后一个路径段的URL).我的system.webServer部分如下所示: <system.webServer> <handlers> <!-- Clear all handlers,prevents executing code file extensions or returning any file contents. --> <clear /> <!-- Favicon static handler. --> <add name="FaviconStaticFile" path="/favicon.ico" verb="GET" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" /> <!-- By default,only map extensionless URLs to ASP.NET --> <!-- (the "*." handler mapping is a special syntax that matches extensionless URLs) --> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> <!-- API endpoints must handle path segments including a dot --> <add name="ExtensionIncludedUrlHandler-Integrated-4.0" path="/api/storage/*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> <httpProtocol> <customHeaders> <remove name="X-Powered-By" /> </customHeaders> </httpProtocol> </system.webServer> 请注意,由于各种限制,某些文件名将无法使用.例如,您无法命名路径段.或者..因为RFC要求替换它,Azure托管服务将不允许冒号作为路径段的最后一个字符,并且IIS默认禁止一组字符. 您可能还希望增加IIS / ASP.NET文件上载大小限制: <!-- Path specific settings --> <location path="api/storage"> <system.web> <httpRuntime maxRequestLength="200000000" /> </system.web> <system.webServer> <security> <requestFiltering> <requestLimits maxAllowedContentLength="200000000" /> </requestFiltering> </security> </system.webServer> </location> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |