我已经安装了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解决方案?
答案 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中注册此模块。
现在尝试访问它应该成功的服务!