.net 为什么要“得到”;无法从关闭的文本阅读器中读取;

.net 为什么要“得到”;无法从关闭的文本阅读器中读取;,.net,sql-server,sql-server-2012,sqlclr,.net,Sql Server,Sql Server 2012,Sqlclr,我有一个SQLCLR函数,它从Web Api返回Json,下面是我的代码 [Microsoft.SqlServer.Server.SqlFunction] public static SqlString Funcion() { SqlString document; HttpWebRequest request = (HttpWebRequest)WebRequest.Create("URL"); request.Method = "GET"; request.C

我有一个SQLCLR函数,它从Web Api返回Json,下面是我的代码

[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()
我用ILSpy检查dll,我的代码看起来不一样
有人能帮我吗。我在一个应用程序cosole中尝试了这段代码,将结果写入到一个文件中,并且工作得非常完美

很难准确地说您已经将当前代码与注释掉/删除的代码分开了。但是在字符串中使用
ReadToEnd
返回字符串的一般概念是正确的方法

如果您不想让这段代码破坏SQL Server,您绝对需要做的一件事就是正确地处理所有一次性对象。您应该使用
using()
构造,因为它们将包含适当的
try…finally
结构,以确保所有资源都被正确地处置,无论在嵌套的资源集中的何处发生异常

现在,从ILspy拍摄的图像中显示的代码显示了直接的问题,因为它返回
readStream.ReadToEnd()
。一旦使用构造将代码放入适当的<代码>中,并在中间执行<代码>文档(= SqLoSd)ReaveStudio(Read toEnter)(/Cult>),这将按预期工作。

字符串文档;
HttpWebRequest请求=(HttpWebRequest)WebRequest.Create(“URL”);
request.Method=“GET”;
request.ContentLength=0;
request.UseDefaultCredentials=true;//不要使用CredentialCache.DefaultCredentials;
使用(HttpWebResponse=(HttpWebResponse)request.GetResponse())
{
使用(Stream receiveStream=response.GetResponseStream())
{
使用(StreamReader readStream=新StreamReader(receiveStream))
{
document=readStream.ReadToEnd();
}
}
}
返回新的SqlString(文档);

更新

  • 使用上述代码,O.P.仍然会收到
    无法从关闭的文本阅读器读取的错误
  • O.P.提到web服务返回大约8MB的响应
  • 使用上面的代码,我下载了一个11.6MB的文件,没有问题
  • 通过上面的代码,O.P.能够成功地从 没问题
  • 问题不在于返回数据类型的映射,因为将其映射到
    NVARCHAR(4000)
    而不是
    NVARCHAR(MAX)
    将导致以下错误:

    Msg 6522,第16级,状态1,第2行
    在执行用户定义例程或聚合“xxxxxx”期间发生.NET Framework错误:
    System.Data.SqlServer.TruncationException:尝试将大小为24233896字节的返回值或输出参数转换为大小限制为8000字节的T-SQL类型。
    System.Data.SqlServer.TruncationException:
    位于System.Data.SqlServer.Internal.CXVariantBase.StringToWSTR(字符串pstrValue,Int64 cbMaxLength,Int32 iOffset,EPadding ePad)


谢谢您的帮助!但是仍然得到了相同的错误:(,我在控制台应用程序中尝试了这段代码,将json写入文件,并且工作得非常完美。这可能与您正在调用的页面有关。我在VS 2015中将答案中的代码粘贴到了一个新的DB项目中,更改了“URL”作为一个
SqlString
input参数,它工作得很好。是的,它的web服务有问题,我试过了,效果很好,我会检查web,因为结果有800万个字符。谢谢你的帮助help@VictorHernandez为什么你没有提到预期的响应是8MB?这当然是一个相关的问题可能会影响此的详细信息。可能是SQL Server的CLR主机中的默认超时或最大大小不同(尽管使用SQL Server 2012的可能性较小)。控制台应用程序是否与SQL Server本身在同一台服务器上运行(不一定是运行SSMS的同一台计算机)?我将使用8MB的文件进行测试并报告。