有很多类似的问题,但我已经尝试了所有的解决方案都没有成功。
我们有一个使用WebServiceHostFactory初始化的Web服务,但如果超过64k,就会出现“400 Bad Request”的错误。通常,这只需要增加MaxReceivedMessageSize、MaxBufferSize和MaxBufferPoolSize就可以解决。问题是使用WebServiceHostFactory时,完全忽略了Web.Config。在ServiceModel部分所做的任何更改都不会反映在服务中。
最好完全放弃WebServiceHostFactory,从头开始设置web.config,但没有它,我们的服务将无法运行。其中一种方法有一个流参数以及一些其他字符串参数。没有工厂,我们得到
System.InvalidOperationException: For request in operation Test to be a stream the operation must have a single parameter whose type is Stream
因此,删除工厂不是一个选择。我无法确定工厂正在执行什么操作来解决此错误,但我花了4天时间进行尝试,却没有取得任何进展。
我还尝试了一些在其他地方找到的示例,以编程方式覆盖MaxReceivedMessageSize:
protected override void OnOpening()
{
base.OnOpening();
foreach (var endpoint in Description.Endpoints)
{
//var binding = endpoint.Binding as WebHttpBinding;
//if (binding != null)
//{
// binding.MaxReceivedMessageSize = 20000000;
// binding.MaxBufferSize = 20000000;
// binding.MaxBufferPoolSize = 20000000;
// binding.ReaderQuotas.MaxArrayLength = 200000000;
// binding.ReaderQuotas.MaxStringContentLength = 200000000;
// binding.ReaderQuotas.MaxDepth = 32;
//}
//var transport = endpoint.Binding.CreateBindingElements().Find<HttpTransportBindingElement>();
//if (transport != null)
//{
// transport.MaxReceivedMessageSize = 20000000;
// transport.MaxBufferPoolSize = 20000000;
//}
var newTransport = new HttpTransportBindingElement();
newTransport.MaxReceivedMessageSize = 20000000;
newTransport.MaxBufferPoolSize = 20000000;
endpoint.Binding.CreateBindingElements().Add(newTransport);
}
}
第一个方法不起作用,因为工厂创建了CustomBinding,无法转换为WebHttpBinding。第二个方法不起作用,因为似乎绑定元素是只读的——无论我将元素设置为什么,都不会改变,我通过在“更改”它们后读取值进行了验证。第三个方法是最后的尝试,试图将一个新的绑定元素扔进去,但当然这也失败了。
现在我们完全不知所措。怎么才能让这个东西运行起来呢?你认为这应该很简单!
谢谢大家
Web.Config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<compilation targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="rest" maxReceivedMessageSize="500000000" />
</webHttpBinding>
</bindings>
<services>
<service name="SCAPIService" behaviorConfiguration="ServiceBehaviour">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="rest" contract="ISCAPIService" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
使用一个目前尚未成功的建议修复进行编辑:
public class MyServiceHost : WebServiceHost
{
public MyServiceHost()
{
}
public MyServiceHost(object singletonInstance, params Uri[] baseAddresses)
: base(singletonInstance, baseAddresses)
{
}
public MyServiceHost(Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
}
protected override void ApplyConfiguration()
{
base.ApplyConfiguration();
APIUsers.TestString += "here" + Description.Endpoints.Count.ToString();
foreach (var endpoint in this.Description.Endpoints)
{
var binding = endpoint.Binding;
APIUsers.TestString += binding.GetType().ToString();
if (binding is WebHttpBinding)
{
var web = binding as WebHttpBinding;
web.MaxBufferSize = 2000000;
web.MaxBufferPoolSize = 2000000;
web.MaxReceivedMessageSize = 2000000;
}
var myReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas();
myReaderQuotas.MaxStringContentLength = 2000000;
myReaderQuotas.MaxArrayLength = 2000000;
myReaderQuotas.MaxDepth = 32;
binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, myReaderQuotas, null);
}
}
}
class MyWebServiceHostFactory : WebServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new MyServiceHost(serviceType, baseAddresses);
}
}
ApplyConfiguration()
来添加终结点行为,但是WebServiceHost
直到OnOpening()
时才创建其终结点,所以这个方法帮助了我。 - kenchilada