【问题标题】:Error Message as "This stream does not support seek operations"错误消息为“此流不支持查找操作”
【发布时间】:2020-09-17 12:04:24
【问题描述】:

我尝试使用 C# 代码中的 webRequest 从下面的代码打开。我尝试了下面的代码,但我收到错误消息 “此流不支持搜索操作”。请检查下面的代码并建议如何执行此操作。

    private static void DownloadCurrent() {
    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://einvoicing
        .internal.cleartax.co/v2/eInvoice/download?
        irns=11eaf48a909dda520db27ff35804d4b42df2c3b6285afee8df586cc4dbd10541");
    webRequest.Method = "GET";
    webRequest.ContentType = "application/pdf";
    webRequest.Headers.Add("owner_id", "78c6beda-54a2-11ea-b064-0af3f8b02c24");
    webRequest.Headers.Add("gstin", "29AAFCD5862R000");
    webRequest.Timeout = 3000;
    webRequest.BeginGetResponse(new AsyncCallback(PlayResponeAsync), webRequest);
}

private static void PlayResponeAsync(IAsyncResult asyncResult) {
    long total = 0;
    long received = 0;
    HttpWebRequest webRequest = (HttpWebRequest)asyncResult.AsyncState;

    try {
        using (HttpWebResponse webResponse = 
            (HttpWebResponse)webRequest.EndGetResponse(asyncResult)) {
            byte[] buffer = new byte[1024];

            FileStream fileStream = File.OpenWrite("[file name to write]");
            using (Stream input = webResponse.GetResponseStream()) {
                total = input.Length;

                int size = input.Read(buffer, 0, buffer.Length);
                while (size > 0) {
                    fileStream.Write(buffer, 0, size);
                    received += size;

                    size = input.Read(buffer, 0, buffer.Length);
                }
            }

            fileStream.Flush();
            fileStream.Close();
        }
    }
    catch (Exception ex) { }
}

【问题讨论】:

  • 你在哪得到这个?
  • 解决问题:是否可以选择切换到 HttpClient?
  • 你能有示例代码吗?
  • @jrh 很公平;我的大脑停顿了一下;我正在考虑服务 PDF
  • 看来 OP 的异常很可能出现在 total = input.Length 行。这当然可以抛出这样的异常,并且在这种情况下似乎可能应该,因为除非在完全阅读之前无法确定长度,这有点会破坏它是流的意义。 (可能有一个 Content-Length 标头,但不需要。)

标签: c#


【解决方案1】:

建议切换到 HttpClient如果可能

为简洁起见,我省略了 header-configs,但绝对可以这样做。

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);
     }
}

请注意,这现在是 TAP,而不是旧的异步模式 (APM)。

一些额外的注意事项:

  • 为了恢复能力,我想在这里使用“Polly”。 (我隶属于)
  • 可能应该通过 IHttpClientFactory 注入客户端实例。

附录:

如果您的应用程序的其余部分仅使用 APM,那么您可以查看 Interop with Other Asynchronous Patterns and Types

【讨论】:

  • "为了弹性" -- 是的,不幸的是,Microsoft HttpClientFtpWebRequest 和其他类似的类有一些 serious problems。我通常不喜欢第三方库,但在这种情况下,我认为通过查看其他选项您几乎没有什么可失去的,我很确定这些错误从未得到修复。
  • 感谢回复...但我在 pdf 文件中找不到内容。请检查我更新的代码。
  • 我看到了建议的修改。问题是:您需要在调用 GetAsync 之前设置标题。
  • @jrh Polly 为您提供“策略”,您可以在其中非常舒适地配置“重试”或“超时”、“回退”等。它与 DI 和 IHttpFactory 很好地集成,并且 - 尽管是第 3 方 - 被广泛使用。这就是“弹性”在这里的含义。
  • 为什么上面的代码在 Visual Studio 2010 中不起作用??
猜你喜欢
  • 2011-03-26
  • 1970-01-01
  • 2014-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-27
  • 2011-09-11
相关资源
最近更新 更多