在读取HttpRequest.InputStream后,第一个请求在HTTP 400(错误请求)下失败

时间:2022-08-23 11:59:02

I develop an asmx web service (i.e. ASP.NET 2.0).

我开发了一个asmx web服务(即ASP)。NET 2.0)。

There's a piece of code that may read the contents of the HTTP request (via HttpContext.Current.Request.InputStream) while processing it. I realise that InputStream may only be read once for a request, and I make sure I never try to read it more than once.

有一段代码可以在处理HTTP请求时读取HTTP请求的内容(通过HttpContext.Current.Request.InputStream)。我意识到InputStream可能只会被读取一次请求,我确保我不会尝试读取它超过一次。

The problem seems to be that if InputStream happens to be read during the early stages of the application's lifecycle (e.g. after pskill w3wp, during Application_Start), the HTTP request fails with a HTTP 400 - Bad Request error, with no explanation given, no exception thrown and no entry in the httperr log. If it is read later (e.g. within the web method itself), requests run fine whether InputStream is read or not. Application_Start runs fine if InputStream isn't read.

问题似乎是,如果InputStream碰巧读在应用程序的生命周期的早期阶段(如pskill w3wp之后,在Application_Start),HTTP请求与HTTP 400错误请求错误失败,没有解释,没有异常,也没有在httperr日志条目。如果稍后读取(例如在web方法本身中),无论是否读取InputStream,请求都运行良好。如果InputStream没有读取,Application_Start运行良好。

Is this some sort of ASP.NET bug? IIS bug? Or am I doing something wrong by daring to read InputStream? And if so, is there another way to get a look at the "raw" contents of the request without disturbing the inner workings of IIS/ASP.NET?

这是某种ASP吗?网络错误?IIS漏洞?还是因为我敢于读InputStream而做错了什么?如果是这样,是否有其他方法可以在不影响IIS/ASP.NET内部工作的情况下查看请求的“原始”内容?

In short, adding this code within Application_Start is enough to reproduce this error:

简而言之,在Application_Start中添加此代码就足以重现此错误:

using (StreamReader reader = new StreamReader(HttpContext.Current.Request.InputStream))
    reader.ReadToEnd();

3 个解决方案

#1


1  

Couldn't find a way to read request contents during Application_Start without disturbing inner workings of ASP.NET/IIS. Instead, ended up making sure this doesn't happen until Application_Start is over (and also doesn't happen from the moment Application_End starts, which also turned out to be problematic and created access violations).

在Application_Start期间,无法找到一种方法来读取请求内容,而不会干扰ASP.NET/IIS的内部工作。相反,直到Application_Start结束时(而且也不会从Application_End启动的那一刻开始发生,这也被证明是有问题的,并创建了访问违例),才会发生这种情况。

#2


1  

You have to no use the using bloc because this has as effect to close the reader and by consequence to close the inputstream of httprequest

您不需要使用using块,因为这实际上关闭了阅读器,并因此关闭了httprequest的inputstream

#3


0  

I would suggest not attempting to read the Request.InputStream during Application_Start - it's used for initialising the application. Accessing the Request object from within Application_Start results in an exception "Request is not available in this context."

我建议不要试图阅读请求。在Application_Start期间输入流——它用于初始化应用程序。从Application_Start中访问请求对象会导致一个异常“请求在此上下文中不可用”。

The fact that you are wanting to read the input stream suggests you should be using Application_BeginRequest instead - this has access to request and response.

您想要读取输入流的事实表明,您应该使用Application_BeginRequest而不是这个—它可以访问请求和响应。

In Summary:

总而言之:

  1. Application_Start
    Fires once when the application starts. While usually triggered by the first request, it occurs before the first request is set up. Don't do request specific code in here as it doesn't have access to Request and Response.

    Application_Start在应用程序启动时触发一次。虽然通常由第一个请求触发,但它发生在设置第一个请求之前。不要在这里请求特定的代码,因为它没有访问请求和响应的权限。

  2. Application_BeginRequest
    Fires for every request before any page handlers are invoked - you can read the input, write to response, end the request, etc...

    在调用任何页面处理程序之前,Application_BeginRequest触发每个请求——您可以读取输入、写入响应、结束请求等等。

See these SO articles for more info:

更多信息请参见这些文章:

#1


1  

Couldn't find a way to read request contents during Application_Start without disturbing inner workings of ASP.NET/IIS. Instead, ended up making sure this doesn't happen until Application_Start is over (and also doesn't happen from the moment Application_End starts, which also turned out to be problematic and created access violations).

在Application_Start期间,无法找到一种方法来读取请求内容,而不会干扰ASP.NET/IIS的内部工作。相反,直到Application_Start结束时(而且也不会从Application_End启动的那一刻开始发生,这也被证明是有问题的,并创建了访问违例),才会发生这种情况。

#2


1  

You have to no use the using bloc because this has as effect to close the reader and by consequence to close the inputstream of httprequest

您不需要使用using块,因为这实际上关闭了阅读器,并因此关闭了httprequest的inputstream

#3


0  

I would suggest not attempting to read the Request.InputStream during Application_Start - it's used for initialising the application. Accessing the Request object from within Application_Start results in an exception "Request is not available in this context."

我建议不要试图阅读请求。在Application_Start期间输入流——它用于初始化应用程序。从Application_Start中访问请求对象会导致一个异常“请求在此上下文中不可用”。

The fact that you are wanting to read the input stream suggests you should be using Application_BeginRequest instead - this has access to request and response.

您想要读取输入流的事实表明,您应该使用Application_BeginRequest而不是这个—它可以访问请求和响应。

In Summary:

总而言之:

  1. Application_Start
    Fires once when the application starts. While usually triggered by the first request, it occurs before the first request is set up. Don't do request specific code in here as it doesn't have access to Request and Response.

    Application_Start在应用程序启动时触发一次。虽然通常由第一个请求触发,但它发生在设置第一个请求之前。不要在这里请求特定的代码,因为它没有访问请求和响应的权限。

  2. Application_BeginRequest
    Fires for every request before any page handlers are invoked - you can read the input, write to response, end the request, etc...

    在调用任何页面处理程序之前,Application_BeginRequest触发每个请求——您可以读取输入、写入响应、结束请求等等。

See these SO articles for more info:

更多信息请参见这些文章: