Error "This Stream Does Not Support Seek Operations" in C#

Error This stream does not support seek operations in C#

You probably want something like this. Either checking the length fails, or the BinaryReader is doing seeks behind the scenes.

HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse();

byte[] b = null;
using( Stream stream = myResp.GetResponseStream() )
using( MemoryStream ms = new MemoryStream() )
{
int count = 0;
do
{
byte[] buf = new byte[1024];
count = stream.Read(buf, 0, 1024);
ms.Write(buf, 0, count);
} while(stream.CanRead && count > 0);
b = ms.ToArray();
}

edit:

I checked using reflector, and it is the call to stream.Length that fails. GetResponseStream returns a ConnectStream, and the Length property on that class throws the exception that you saw. As other posters mentioned, you cannot reliably get the length of a HTTP response, so that makes sense.

This stream does not support seek operations, using stream

A ResponseStream does indeed not support Seek operations. You can verify this by looking at the CanSeek property.

A simple solution:

using (var stream1 = response.GetResponseStream())
using (var stream2 = new MemoryStream())
{
stream1.CopyTo(stream2);
var messages = StaticImportFile.GetStoreProductImportMessages(stream2, 0, 1, true);
}

But this won't work well for very large streams (eg 100 MB and above)

Error Message as This stream does not support seek operations

To suggest a switch to HttpClient if possible:

I left out the header-configs for brevity, but it's definitely possible to do.

static string url = "https://einvoicing.internal.cleartax.co/v2/eInvoice/download?irns=11eaf48a909dda520db27ff35804d4b42df2c3b6285afee8df586cc4dbd10541";

static HttpClient client = new HttpClient(); // Use same instance over app lifetime!

static async Task DownloadCurrentAsync()
{
// config headers here or during instance creation
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode(); // <= Will throw if unsuccessful
using (FileStream fileStream = new FileStream("[file name to write]", FileMode.Create, FileAccess.Write, FileShare.None))
{
//copy the content from response to filestream
await response.Content.CopyToAsync(fileStream);
}
}

Note that this is now TAP, not the legacy Async pattern (APM).

Some additional considerations:

  • For resilience, I'd have a look into using "Polly" here. (I am not affiliated)
  • The client instance should probably be injected through IHttpClientFactory.

Addendum:

If the rest of your app is using exclusively APM, then you could have a look into Interop with Other Asynchronous Patterns and Types

This stream does not support seek operations while HTTPWebRequest making

This exception is thrown only when you call a method or a property that not compatible with the current stream (NetworkStream in your case). If you need to move backward you need to copy the content in a temporary stream (MemoryStream, FileStream, ...).

Your sample code doesn't have issue with this scenario. The exception you can see in Visual studio is because VS try to access to each property to display a value. When your code run, properties like 'Position' are not called and everything is fine.

To programmatically know if you can seek in a stream. use the property CanSeek of the stream.

DotNetZip fails with stream does not support seek operations

You'll have to download the data to a file or to memory, and then create a FileStream or a MemoryStream, or some other stream type that supports seeking. For example:

WebClient client = new WebClient();
client.DownloadFile(url, filename);
using (var fs = File.OpenRead(filename))
{
unzipFromStream(fs, outdir);
}
File.Delete(filename);

Or, if the data will fit into memory:

byte[] data = client.DownloadData(url);
using (var fs = new MemoryStream(data))
{
unzipFromStream(fs, outdir);
}

asp.net WebRequest stream throwing 'This stream does not support seek operations' error in debugger

If you check their documentation you will see:

Services within the EAN API are accessed via this standard base URL
format for all protocols

Which means that you need to do a GET request and paste search parameters in URL. So your code might look like that:

var url =
"http://api.ean.com/ean-services/rs/hotel/v3/avail" +
"?minorRev=99&cid=55505&apiKey=cbrzfta369qwyrm9t5b8y8kf&locale=en_US" +
"¤cyCode=USD&_type=json&hotelId=125719&arrivalDate=11/11/2015" +
"&departureDate=11/13/2015&includeDetails=true" +
"&includeRoomImages=true&room1=2,5,7";
var req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "GET";

using (var res = req.GetResponse())
{
using (var resStream = res.GetResponseStream())
{
using (var reader = new StreamReader(resStream))
{
var json = reader.ReadToEnd();
}
}
}

And you really don't need to mess with all these requests, responses and streams. If you are using .Net 4.5 then take a look at HttClient. With this class code will be very short:

using (var httpClient = new HttpClient())
{
var json = httpClient.GetStringAsync(url).Result;
}


Related Topics



Leave a reply



Submit