Ответ 1
Примечание. Эта проблема исправлена в .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 runtime, некоторые из 4.5 поведения вступают в силу.
ИЗМЕНИТЬ
Запись в блоге:
В .net 4.5 WCF запустил буферный поток меньше потока для преимуществ масштабируемости. В результате, когда вы пытаетесь получить доступ к свойству HttpContext.Current.Request.InputStream, вы можете получить исключение ниже, поскольку свойство InputStream пытается заставить вас обращаться к потоку Classic, поскольку оба они несовместимы.
"Этот метод или свойство не поддерживается после HttpRequest.GetBufferlessInputStream.
Если у вас было приложение WCF 4.0, которое отлично работало, но при обновлении вашей .net-структуры до версии 4.5 вы заметили, что служба не работает при доступе к этому свойству, вот способ обойти проблему:
-
Добавьте простой HttpModule в тот же проект WCF, который получит доступ к свойству InputStream для каждого запроса до того, как WCF прочитает его, чтобы он обеспечил соответствие 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; } }
-
Зарегистрируйте этот модуль в файле web.config, добавив эти строки в настройку
<configuration>
<modules>
.<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.
Теперь попробуйте получить доступ к сервису, который вам будет успешным!