Visual Studio 2012安装打破了我的2010 WCF项目

时间:2012-09-12 15:26:59

标签: wcf visual-studio-2012 runtime-error

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

除了尝试在我引用的weblog项目中创建类的实例之外,所有内容都编译并正常工作,然后它会抛出此错误:

调用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解决方案?

1 个答案:

答案 0 :(得分:28)

注意:此问题已在.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-in-aspnetcompatibility-mode-throws-exception-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属性会尝试让您处理Classic流,因为它们都不兼容。

  

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

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

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

    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中注册此模块。

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