Upload file using PUT verb in ASP.Net Web Api 2

前端 未结 1 1787
时光说笑
时光说笑 2020-12-31 16:18

I would like to expose an ASP.Net Web Api 2 action using the HTTP PUT verb to upload files. This is coherent with our REST model as the API represents a remote file system (

相关标签:
1条回答
  • 2020-12-31 16:25

    After a few tests it seems the server-side code I posted as an example is correct. Here is an example, stripped out of any authentication/authorization/error handling code:

    [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);
        }
    }
    

    A simple console app is enough to test it (using Web Api client libraries):

    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);
    }
    

    Edit 2018-05-09:

    As stated in this comment, if you plan to support file names with an extension ({filename}.{extension}) without forcing the client to append a trailing slash, you will need to modify your web.config to bind IIS to your web api application for these file types, as by default IIS will use a static file handler to handle what looks like file names (i.e. URLs with the last path segment containing a dot). My system.webServer section looks like:

    <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>
    

    Note that some file names will not be possible because of various limitations. For example you can't name a path segment . or .. because the RFC requires to replace it, Azure hosting services won't allow a colon as the last character of a path segment, and IIS forbids a set of characters by default.

    You may also want to increase IIS / ASP.NET file upload size limits:

    <!-- 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>
    
    0 讨论(0)
提交回复
热议问题