2012-01-26 44 views
1

我有一個WCF REST服務運行在流(非緩衝)模式,它接收文件上傳爲HTTP請求正文中的原始字節。在閱讀傳入流(a MessageBodyStream)之前,我檢查了請求標題,並確保Content-Length適合該特定操作。中斷讀取傳入的請求在WCF REST

如果Content-Length大於允許的大小,我希望立即返回一個錯誤響應(通過拋出一個WebFaultException)而不用等待請求的其餘部分被傳輸。

但是,即使拋出異常,WCF似乎也試圖讀取流到最後 - 如果客戶端正在發送50 MB文件,則在發送響應之前將傳輸所有50 MB文件。

有什麼辦法可以避免這種情況,並中斷接收HTTP請求?

相關問題:Why is WCF reading input stream to EOF on Close()?

編輯:添加代碼摘錄

OperationContract和上傳的輔助方法:

[OperationContract] 
[WebInvoke(UriTemplate = /* ... */, Method = "POST", 
    ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] 
public void UploadMyFile(string guid, Stream fileStream) 
{ 
    string targetPath = /* targetPath */; 
    UploadFile(fileStream, targetPath, /* targetFileName */); 
} 


private bool UploadFile(Stream stream, string targetDirectory, 
    string targetFileName = null, int maximumSize = 1024 * 500, 
    Func<string, bool> tempFileValidator = null) 
{ 
    int size = 0; 
    int.TryParse(IncomingRequest.Headers[HttpRequestHeader.ContentLength], out size); 
    if (size == 0) 
    { 
     ThrowJsonException(HttpStatusCode.LengthRequired, "Valid Content-Length required"); 
    } 
    else if (size > maximumSize) 
    { 
     ThrowJsonException(HttpStatusCode.RequestEntityTooLarge, "File is too big"); 
    } 

    if (!FileSystem.SaveFileFromStream(stream, targetDirectory, targetFileName, tempFileValidator)) 
    { 
     ThrowJsonException(HttpStatusCode.InternalServerError, "Saving file failed"); 
    } 

    return true; 
} 
+0

向我們展示一些代碼。 '我檢查請求標題'你在哪裏做這個?你在哪裏閱讀流? – Aliostad

+0

@Aliostad,我發佈了一個摘錄。 – kpozin

+0

很好。謝謝.... – Aliostad

回答

0

HttpWebRequest一般HTTP請求不支持流在其下方是通過作爲服務器端概念的分塊編碼來實現。

我剛纔已經回答了這個問題太這是關係: IIS7 refuses chunked-encoded file upload

當你寫請求流,它被緩存在本地,直到發送,因爲它有化蛹的Content-Length頭。您可以在fiddler中驗證。

+0

我並不十分關心客戶端在做什麼(在這種情況下,我實際上是在寫入請求流之前在客戶端手動填充Content-Length標頭)。我只希望*服務器*能夠中止*接收請求*。我知道這在技術上是可行的,因爲WCF可以在超過配置的最大消息大小時切斷請求。我想從我自己的服務器代碼中完成此操作,當我的操作不喜歡有關請求的某些內容時。 – kpozin

1

您或許可以編寫可攔截請求正文和上下文的消息檢查器組件。

然後,您可以在檢查消息/上下文後拋出異常(如果您喜歡)。

HTH