13

我已经安装了 VS 2012 并在一些 Web 项目中成功使用它,但它的某些东西导致我的 Web 服务项目中断。我还在web服务项目上使用VS 2010,2012年还没有打开。

一切都编译并正常工作,除非它试图在我引用的博客项目中创建一个类的实例,然后它会抛出这个错误:

调用 HttpRequest.GetBufferlessInputStream 后不支持此方法或属性。

我在项目中找不到明确使用GetBufferlessInputStream的任何地方。

如果我跳过博客代码,一切都会正确执行。

我找不到其他收到此错误的人来尝试缩小范围,任何想法从哪里开始?

   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



**编辑- 奖金问题

为什么这些 Framework 4.5 属性会影响我的 4.0 解决方案?

4

1 回答 1

29

注意:此问题已在 .net 4.5.1 中修复。您可以看到 4.5.1 的修复。拥有 .net 4.5.1 后,添加以下 appSetting 以切换回旧行为。

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

以下是如何创建 HttpModule 以强制 ReadEntityBodyMode 为“经典”:http: //blogs.msdn.com/b/praburaj/archive/2012/09/13/accessing-httpcontext-current-request-inputstream-property -在-aspnet 兼容性模式中抛出异常-this-method-or-property-is-not-supported-after-httprequest-getbufferlessinputstream-has-been-invoked.aspx

要回答您的其他问题(为什么这些 Framework 4.5 属性会影响我的 4.0 解决方案?):.net 4.5 是 .net 4.0 的就地升级。所以即使你的项目是针对 4.0 的,由于 VS 2012 安装了 4.5 运行时,4.5 的一些行为也会生效。

编辑

博客条目:

在 .net 4.5 中,WCF 利用缓冲区较少的输入流来获得可伸缩性优势。因此,当您尝试访问 HttpContext.Current.Request.InputStream 属性时,您可能会遇到以下异常,因为 InputStream 属性试图让您处理经典流,因为它们都不兼容。

“调用HttpRequest.GetBufferlessInputStream后,不支持此方法或属性 。”</p>

如果您有一个运行良好的 WCF 4.0 应用程序,但在将 .net 框架升级到 4.5 时,您会注意到服务在访问此属性时失败,以下是解决此问题的方法:

  • 在同一个 WCF 项目中添加一个简单的 HttpModule,它将在 WCF 读取之前访问每个请求的 InputStream 属性,这样它将强制 HttpContext.Request.ReadEntityBody 为“经典”并确保兼容性。

    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;    
        }    
     } 
    
  • <configuration> <modules>通过在设置中添加这些行,在您的 web.config 中注册此模块。

    <system.webServer>
        <modules>
            <!-- Register the managed module -->
            <add name="WcfReadEntityBodyModeWorkaroundModule" type="MyAssembly.WcfReadEntityBodyModeWorkaroundModule, MyAssembly" />
        </modules>
    
  • 如果您在经典模式下使用应用程序池,则需要将模块添加到 web.config 中的此部分:

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

如果您的项目无法修改,那么您可以在单独的程序集中编写此 Http 模块,单独 GAC 并在 web.config 中注册此模块。

现在尝试访问它应该为您成功的服务!

于 2012-09-14T00:25:21.903 回答