2017-01-13 75 views
1

我有一個SQL CLR函數,從Web API返回JSON的「不能從一個封閉的TextReader讀」,在這裏上課我的代碼爲什麼還要

[Microsoft.SqlServer.Server.SqlFunction] 
public static SqlString Funcion() 
{ 
    SqlString document; 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("URL"); 
    request.Method = "GET"; 
    request.ContentLength = 0; 
    request.Credentials = CredentialCache.DefaultCredentials; 
    HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
    Stream receiveStream = response.GetResponseStream(); 
    StreamReader readStream = new StreamReader(receiveStream); 
    document = (SqlString)readStream.ReadToEnd(); 
    return document; 
} 

我刪除下面的代碼,因爲我認爲這是問題

 //response.Close(); 
    //readStream.Close(); 

,但我仍然剛開錯誤

System.ObjectDisposedException: Cannot read from a closed TextReader System.ObjectDisposedException: 
at System.IO.__Error.ReaderClosed() 
at System.IO.StreamReader.ReadToEnd() 
at UserDefinedFunctions.Funcion() 

我檢查的dll withILSpy和我的代碼看起來不同 enter image description here 有人可以幫助我。我試過這個代碼在一個應用程序cosole寫結果在一個文件中,並完美的作品

回答

2

很難說正如你已經從註釋/刪除代碼中分離出當前代碼。但將ReadToEnd轉換爲字符串以返回字符串的一般概念是正確的方法。

如果你不想讓這段代碼垃圾你的SQL Server,你絕對需要做的一件事就是正確處理所有的一次性對象。您應該使用using()構造,因爲它們將包含適當的try...finally結構,以確保所有資源都正確放置,而不管嵌套集中的哪個位置發生異常。

現在,從ILspy獲取的圖像中顯示的代碼顯示了即時問題,因爲它返回readStream.ReadToEnd()。一旦將代碼放入正確的using構造中,並在中間執行document = (SqlString)readStream.ReadToEnd(),則這將按預期工作。

string document; 
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("URL"); 
request.Method = "GET"; 
request.ContentLength = 0; 
request.UseDefaultCredentials = true; // don't use CredentialCache.DefaultCredentials; 

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
{ 
    using (Stream receiveStream = response.GetResponseStream()) 
    { 
    using (StreamReader readStream = new StreamReader(receiveStream)) 
    { 
     document = readStream.ReadToEnd(); 
    } 
    } 
} 

return new SqlString(document); 

UPDATE

  • 通過上面的代碼,O.P.仍然得到Cannot read from a closed TextReader錯誤。
  • O.P.提到網絡服務返回大約8 MB的響應。
  • 隨着上面的代碼,我下載了一個11.6 MB的文件沒有問題。
  • 通過上面的代碼,O.P.能夠成功地從 https://jsonplaceholder.typicode.com/中成功檢索到響應,沒有任何問題。
  • 問題是返回的數據類型,因爲它映射到的替代NVARCHAR(4000)NVARCHAR(MAX)導致以下錯誤映射:

    Msg 6522, Level 16, State 1, Line 2
    A .NET Framework error occurred during execution of user-defined routine or aggregate "xxxxxx":
    System.Data.SqlServer.TruncationException: Trying to convert return value or output parameter of size 24233896 bytes to a T-SQL type with a smaller size limit of 8000 bytes.
    System.Data.SqlServer.TruncationException:
          at System.Data.SqlServer.Internal.CXVariantBase.StringToWSTR(String pstrValue, Int64 cbMaxLength, Int32 iOffset, EPadding ePad)

+0

感謝您的幫助!但仍然得到相同的錯誤:(, –

+0

我試圖在控制檯應用程序中的代碼來寫一個文件中的JSON和完美的作品 –

+0

我將不得不稍後檢查.. –

相關問題