13

I've installed VS 2012 and am successfully using it on some web projects, but something with it has caused my web service project to break. I'm still using VS 2010 on the web service project and have not opened it in 2012.

Everything compiles and works correctly except when it tries to create an instance of a class in my referenced weblog project, then it throws this error:

This method or property is not supported after HttpRequest.GetBufferlessInputStream has been invoked.

I can not find anywhere in the project where GetBufferlessInputStream is used explicitly.

If I jump over the weblog code, everything executes correctly.

I can't find anyone else who has received this error to try and narrow it down, any ideas where to start?

Stack

   at System.Web.HttpRequest.get_InputStream()
   at OAS.Web.Log.WebEvent..ctor(EventType type, HttpContext context, String applicationName)
   at OAS.Web.Log.WebTrace..ctor(HttpContext context, String applicationName)
   at OAS.Web.AdvisorServices.Extensions.OperationLoggerParameterInspector.BeforeCall(String operationName, Object[] inputs) in C:\SourceControl\OAS\IM.NET3.0\Web\AdvisorServices\OAS.Web.AdvisorServices.Extensions\OperationLogger\OperationLoggerParameterInspector.cs:line 54



**EDIT - Bonus Question

Why are these Framework 4.5 properties affecting my 4.0 solution?

Dustin Brooks
  • 2,544
  • 3
  • 23
  • 33
  • I suppose yes but... did you "clean" your solution? – zapico Sep 12 '12 at 15:44
  • 1
    Just cleaned and rebuilt, no change. A microsoft guy had an answer on here, but now its gone. Said I should try to create a HttpModule that should call the get_InputStream before the WCF module is called and it would force the ReadEntityBodyMode property to classic instead of none, but I wasn't sure how to force my module to get hit before the wcf one. – Dustin Brooks Sep 13 '12 at 15:31
  • Bonus: hate to do this to you, but see http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c05a8c02-de67-47a9-b4ed-fd8b622a7e4a. Short answer: .NET 4.5 is an in-place upgrade, and in effect fixes bugs in .NET 4.0. – John Saunders Sep 14 '12 at 21:27
  • I am from the WCF product team and looking for clarification but couldn't find a way to add comment so responding here as an answer. We are glad that the workaround worked for you but we also would like to know how common this will be for customers. To evaluate this, could you please tell if this code where you are hitting this is a 3rd party component that you are using or some custom code you are using in your project. Additionally, what exactly does this logging code do where you hit this? Thanks. – Piyush Joshi Sep 14 '12 at 23:49
  • @DustinBrooks Hello Dustin, I'm from Microsoft .NET Framework team. We would like to understand your scenario better, we're looking at addressing any issues in upcoming update. Could you contact us netfx45compat at Microsoft dot com? --Varun Gupta (From Microsoft .NET Framework Team) – Varun Dec 07 '12 at 06:24

1 Answers1

29

Note : This issue has been fixed in .net 4.5.1. You can see the fix with 4.5.1. Once you have .net 4.5.1 add the following appSetting to switch back to the old behavior.

<configuration>      
<appSettings>
      <add key="wcf:serviceHostingEnvironment:useClassicReadEntityBodyMode" value="true" />
</appSettings> 
</configuration>

Here is how you can create a HttpModule to force ReadEntityBodyMode to be "classic" : http://blogs.msdn.com/b/praburaj/archive/2012/09/13/accessing-httpcontext-current-request-inputstream-property-in-aspnetcompatibility-mode-throws-exception-this-method-or-property-is-not-supported-after-httprequest-getbufferlessinputstream-has-been-invoked.aspx

To answer your other question (Why are these Framework 4.5 properties are effecting my 4.0 solution?): .net 4.5 is an in-place upgrade of .net 4.0. So even if your project is targeting 4.0, since VS 2012 installs 4.5 runtime, some of the 4.5 behaviors take effect.

EDIT

Blog Entry:

In .net 4.5 WCF leveraged the buffer less input stream for scalability benefits. As a result when you try to access the HttpContext.Current.Request.InputStream property you may end up with the below exception, as the InputStream property tries to get you handle to the Classic stream as they both are incompatible.

“This method or property is not supported after HttpRequest.GetBufferlessInputStream has been invoked.”

If you had a WCF 4.0 app which worked perfectly but on upgrading your .net framework to 4.5 you notice the service failing on accessing this property, here is the way to work-around the issue:

  • Add a simple HttpModule in the same WCF project which will access the InputStream property for each request before WCF reads it so that it will enforce the HttpContext.Request.ReadEntityBody to be "Classic" and will ensure compatibility.

    public class WcfReadEntityBodyModeWorkaroundModule : IHttpModule    
    {    
        public void Dispose() { }
    
        public void Init(HttpApplication context) {    
            context.BeginRequest += context_BeginRequest;    
        }    
    
        void context_BeginRequest(object sender, EventArgs e) {
            //This will force the HttpContext.Request.ReadEntityBody to be "Classic" and will ensure compatibility..    
            Stream stream = (sender as HttpApplication).Request.InputStream;    
        }    
     } 
    
  • Register this module in your web.config by adding these lines in <configuration> <modules> setting.

    <system.webServer>
        <modules>
            <!-- Register the managed module -->
            <add name="WcfReadEntityBodyModeWorkaroundModule" type="MyAssembly.WcfReadEntityBodyModeWorkaroundModule, MyAssembly" />
        </modules>
    
  • If you are using an app pool in classic mode, you will need to add the module to this section in the web.config:

    <system.web>
        <httpModules>
            <add name="WcfReadEntityBodyModeWorkaroundModule" type="MyAssembly.WcfReadEntityBodyModeWorkaroundModule, MyAssembly" />
        </httpModules>
    

If your project cannot be modified, then you can write this Http module in a separate assembly, GAC it separately and register this module in the web.config.

Now try accessing the service it should succeed for you!

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Praburaj
  • 11,417
  • 1
  • 23
  • 20
  • 1
    I have no idea why, but this hasn't worked for me. I copied the WcfReadEntityBodyModeWorkaroundModule code and added the module configuration to web.config. The ReadEntityBodyMode is still Bufferless. I am using 4.5. Is there something more to it? – bsayegh Feb 07 '14 at 16:13
  • Thanks for this solution. It worked for me. Looks like this issue would have been fixed by now. – ihatemash Jan 19 '16 at 14:16