gpt4 book ai didi

wcf - 如何覆盖 WebServiceHostFactory MaxReceivedMessageSize?

转载 作者:行者123 更新时间:2023-12-04 11:13:32 26 4
gpt4 key购买 nike

那里有很多类似的问题,但我已经尝试了每个解决方案,但无济于事。

我们有一个使用 WebServiceHostFactory 初始化的 Web 服务,但如果向它抛出超过 64k 的数据,我们会收到“400 Bad Request”。通常,这可以通过提高 MaxReceivedMessageSize、MaxBufferSize 和 MaxBufferPoolSize 来解决。问题是使用 WebServiceHostFactory,Web.Config 被完全忽略。我在 ServiceModel 部分所做的任何更改都没有反射(reflect)在服务中。

完全放弃 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);
}
}

第一个不起作用,因为工厂创建了一个不能转换为 WebHttpBinding 的 CustomBinding。第二个不起作用,因为绑定(bind)元素似乎是只读的 - 无论我将元素设置为什么,都没有任何变化,我通过在“更改”它们后读回值来验证这一点。第三次是最后一次尝试在其中添加一个新的绑定(bind)元素,但当然这也失败了。

现在我们完全不知所措。我们怎样才能让这个东西运行呢?你以为会这么简单!

多谢你们

网络配置
<?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);
}
}

最佳答案

为了他人的利益,上述答案走上了正确的道路,但其中有很多错误,如果不进行更改将无法正常工作(因此 OP 无法使解决方案正常工作)。使用以下内容,它将为您“开箱即用”。

备注 - 提供以下所有构造函数并使用工厂中演示的构造函数重载非常重要,否则您将收到以下错误消息:

InitializeRuntime 要求对 Description 属性进行初始化。在 CreateDescription 方法中提供有效的 ServiceDescription 或覆盖 InitializeRuntime 方法以提供替代实现

自定义 ServiceHost 实现:

public class CustomServiceHost : ServiceHost
{
public CustomServiceHost()
{
}

public CustomServiceHost(object singletonInstance, params Uri[] baseAddresses) : base(singletonInstance, baseAddresses)
{
}

public CustomServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses)
{
}

protected override void OnOpening()
{
base.OnOpening();

foreach (var endpoint in this.Description.Endpoints)
{
var binding = endpoint.Binding;
var web = binding as WebHttpBinding;

if (web != null)
{
web.MaxBufferSize = 2147483647;
web.MaxReceivedMessageSize = 2147483647;
}

var myReaderQuotas = new XmlDictionaryReaderQuotas { MaxStringContentLength = 2147483647 };

binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, myReaderQuotas, null);
}
}
}

自定义 ServiceHostFactory 实现:
public sealed class CustomServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new CustomServiceHost(serviceType, baseAddresses);
}
}

只要类型正确,上面的 Service1.svc 标记就可以工作。我实际上使用这种技术来覆盖 WebServiceHost 并允许更大的 JSON 响应大小,但这些原则也应该适用于 ServiceHost。

关于wcf - 如何覆盖 WebServiceHostFactory MaxReceivedMessageSize?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8397532/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com