7

似たような質問がたくさんありますが、私はそれらのすべての解決策をすべて試しましたが、役に立ちませんでした。

WebServiceHostFactory で初期化する Web サービスがありますが、64k を超える値がスローされると、「400 Bad Request」が返されます。通常、これは MaxReceivedMessageSize、MaxBufferSize、および MaxBufferPoolSize を増やすことで解決されます。問題は、WebServiceHostFactory を使用すると、Web.Config が完全に無視されることです。ServiceModel セクションで行った変更は、サービスにまったく反映されません。

WebServiceHostFactory を完全に捨てて、web.config をゼロから設定するだけでもいいのですが、サービスはそれなしでは動作しません。メソッドの 1 つには、ストリーム パラメータとその他の文字列パラメータがあります。工場がなければ、

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 を作成するため、最初の方法は機能しません。バインディング要素が読み取り専用であるように見えるため、2番目は機能しません-要素を何に設定しても、何も変更されません。値を「変更」した後に値を読み戻すことで確認しました。3 つ目は、そこに新しいバインディング要素を投げ込もうとする最後の溝の試みでしたが、もちろんこれも失敗しました。

今、私たちは完全に途方に暮れています。どうすればこれを実行できますか?あなたはそれがとても簡単だと思うでしょう!

みんなありがとう

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);
        }
    }
4

2 に答える 2

8

他の人の利益のために、上記の答えは正しい道をたどりますが、それに多くのエラーがあり、変更なしでは機能しません(したがって、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にも適用されるはずです。

于 2012-01-11T04:46:06.450 に答える
4

独自のカスタム サービス ホストを実装している場合は、"ApplyConfiguration" というメソッドをオーバーライドして、バインディングに必要なすべての構成プロパティを関連付けることができるはずです。以下に示すように、いくつかのサンプルコード:

編集: servicehost ファクトリの実装を追加する

public class MyServiceHost : System.ServiceModel.ServiceHost
{
    public MyServiceHost () { }

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

    }

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

    }

protected override void ApplyConfiguration()
            {
                Console.WriteLine("ApplyConfiguration (thread {0})", System.Threading.Thread.CurrentThread.ManagedThreadId);
                base.ApplyConfiguration();
                foreach (ServiceEndpoint endpoint in this.Description.Endpoints)
                {
                    Binding binding = endpoint.Binding;
                    var binding = endpoint.Binding;
                    if(binding is WebHttpBinding)
                    {
                        var web = binding as WebHttpBinding;
                        web.MaxBufferSize = 2000000;
                        web.MaxReceivedMessageSize = 2000000;
                    }
                    var myReaderQuotas = new XmlDictionaryReaderQuotas();
                    myReaderQuotas.MaxStringContentLength = 5242880;
                    binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, myReaderQuotas, null); 
                }
            }

}

上記は、各バインディングの構成をオーバーライドし、MaxStringContentLength を設定します。

public sealed class MyServiceHostFactory : System.ServiceModel.Activation.ServiceHostFactory
    {
        public override System.ServiceModel.ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
        {
            return base.CreateServiceHost(constructorString, baseAddresses);
        }

        protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            return new MyServiceHost(serviceType, baseAddresses);
        }
    }

これで、私の Service.svc ファイルのマークアップは次のようになります。

<%@ ServiceHost Language="C#" Debug="true" Factory="Sample.MyServiceHostFactory" Service="Sample.ReaderQuotasService" CodeBehind="ReaderQuotasService.svc.cs" %>
于 2011-12-06T11:52:31.423 に答える