簡體   English   中英

使用ASP.Net Web Api 2中的PUT動詞上傳文件

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

我想使用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<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:\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} )支持文件名而不強制客戶端附加尾部斜杠,則需要修改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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM