2017-01-13 8 views
1

У меня есть функция SQL CLR, возвращающих 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 кто-то может помочь. Я пробовал этот код в приложении, чтобы записать результат в файл и отлично работает

ответ

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

  • С кода выше, распродано еще получает Cannot read from a closed TextReader ошибку.
  • O.P. отметил, что веб-служба возвращает ответ примерно 8 МБ.
  • С приведенным выше кодом я загрузил 11,6 МБ файл без проблем.
  • С кодом выше, 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

. Мне нужно будет проверить это позже .. –

Смежные вопросы