7

C#.NET WCF WebサービスでGZIP圧縮を有効にするのに問題があり、App.conf構成ファイルに何が欠けているか、またはでWebサービスを開始するために呼び出しを行うときに追加が必要なものを誰かが知っていることを期待していましたコード。

GZIPを追加するMicrosoftの例のダウンロードを指すリンク「ApplyingGZIPCompressionto WCF Services」をたどりましたが、この例はWebサービスの設定方法とは相関していません。

だから私のApp.confは次のようになります

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="MyService.Service1">
        <endpoint address="http://localhost:8080/webservice" binding="webHttpBinding" contract="MyServiceContract.IService"/>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior>
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <extensions>
      <bindingElementExtensions>
        <add name="gzipMessageEncoding" type="MyServiceHost.GZipMessageEncodingElement, MyServiceHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bindingElementExtensions>
    </extensions>
    <protocolMapping>
      <add scheme="http" binding="customBinding" />
    </protocolMapping>
    <bindings>
      <customBinding>
        <binding>
          <gzipMessageEncoding innerMessageEncoding="textMessageEncoding"/>
          <httpTransport hostNameComparisonMode="StrongWildcard" manualAddressing="False" maxReceivedMessageSize="65536" authenticationScheme="Anonymous" bypassProxyOnLocal="False" realm="" useDefaultWebProxy="True"/>
        </binding>
      </customBinding>
    </bindings>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

構成クラスとGZIPクラスをMSの例からプロジェクトにコピーし、関連するWebサービス構成を追加しただけです。Windowsサービスを開始するために使用しているコードは次のとおりです。

WebServiceHost webserviceHost = new WebServiceHost(typeof(MyService.Service1));
webserviceHost.Open();

Webサービスは正常に実行されますが、Fiddlerは、Webブラウザーから呼び出しを行うときに、GZIP圧縮で返される応答を検出しません。また、プログラムでGZIPを使用してWebサービスをセットアップして実行しようとしましたが、惨めに失敗しました。緑なので、他に何を設定する必要があるのか​​わかりません。アドバイスは素晴らしいです。

これをさらに深く掘り下げてみると、WebサービスをWebServiceHostオブジェクトとして実行しているため、app.confファイルのカスタムGZIPバインディングを、WebServiceHostのデフォルトのWebHTTPBindingオブジェクトでオーバーライドする必要があることがわかりました。 Webサービスからはエンコードされません。これを回避するために、カスタムGZIPバインディングをプログラムでコードに書き込むことにしました。

var serviceType = typeof(Service1);
var serviceUri = new Uri("http://localhost:8080/webservice");
var webserviceHost = new WebServiceHost(serviceType, serviceUri);
CustomBinding binding = new CustomBinding(new GZipMessageEncodingBindingElement(), new HttpTransportBindingElement());
var serviceEndPoint = webserviceHost.AddServiceEndpoint(typeof(IService), binding, "endpoint");
webserviceHost.Description.Endpoints[0].Behaviors.Add(new WebHttpBehavior { HelpEnabled = true });
webserviceHost.Open();

問題は、WebHttpBehaviorとのカスタムバインディングが許可されないことです。しかし、この動作を削除すると、REST Webサービスが醜くなり、コントラクトの入力としてStreamオブジェクトが期待されます。動作を構成する方法がわからないので、どんな助けも素晴らしいです。

4

4 に答える 4

4

これが、これに何日も費やした後に私が思いついたプログラムによる解決策です。app.configファイルでソリューションを構成する方法はわかりませんが、コードを使用するだけであることに注意してください。まず、このリンク をたどって、MicrosoftのコーディングサンプルのGZIPクラスを取得して修正します。次に、以下のサンプルコードを、独自のWebサービスを構成するための基礎として使用します。

//Some class class to start up the REST web service
public class someClass(){
    public static void runRESTWebservice(){
        webserviceHost = new WebServiceHost(typeof(Service1), new Uri("http://localhost:8080));
        webserviceHost.AddServiceEndpoint(typeof(IService), getBinding(), "webservice").Behaviors.Add(new WebHttpBehavior());
        webserviceHost.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
    }

    //produces a custom web service binding mapped to the obtained gzip classes
    private static Binding getBinding(){
        CustomBinding customBinding = new CustomBinding(new WebHttpBinding());
        for (int i = 0; i < customBinding.Elements.Count; i++)
        {
            if (customBinding.Elements[i] is WebMessageEncodingBindingElement)
            {
                WebMessageEncodingBindingElement webBE = (WebMessageEncodingBindingElement)customBinding.Elements[i];
                webBE.ContentTypeMapper = new MyMapper();
                customBinding.Elements[i] = new GZipMessageEncodingBindingElement(webBE);
            }
            else if (customBinding.Elements[i] is TransportBindingElement)
            {
                ((TransportBindingElement)customBinding.Elements[i]).MaxReceivedMessageSize = int.MaxValue;
            }
        }
        return customBinding;
    }
}

//mapper class to match json responses
public class MyMapper : WebContentTypeMapper{
    public override WebContentFormat GetMessageFormatForContentType(string contentType){
        return WebContentFormat.Json;
    }
}

//Define a service contract interface plus methods that returns JSON responses
[ServiceContract]
public interface IService{
    [WebGet(UriTemplate = "somedata", ResponseFormat = WebMessageFormat.Json)]
    string getSomeData();
}

//In your class that implements the contract explicitly set the encoding of the response in the methods you implement
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service1 : IService
{
    public string getSomeData()
    {
        WebOperationContext.Current.OutgoingResponse.Headers[HttpResponseHeader.ContentEncoding] = "gzip";
        return "some data";
    }
}

私はこのリンクをたどることによってこれを最もうまくいきました。

注:MicrosoftがGZIPをWCFにネイティブに組み込んでいないことは、大きなデータセットを返すRESTWebサービスの非常に重要な部分であることに少し戸惑います。

于 2012-10-10T09:18:01.880 に答える
3

WCFでネイティブにサポートされていないGZIPに関するコメントに応えて、.Net4.5に追加されました。ここを参照してください。

于 2012-12-31T22:18:49.620 に答える
0

RestServiceとIIS(> = 7.0)を使用している場合は、自分でこれを行う必要はありません。

IIS 7は、独自のアプリケーション(ASP.NET、MVC、WCFなど)で作成されたコンテンツの自動圧縮を可能にする動的圧縮をサポートしています。このスキームはコンテンツタイプのスニッフィングに基づいているため、あらゆる種類のWebアプリケーションフレームワークで機能します。

ここで完全なチュートリアルを見つけてください。

于 2012-10-09T11:01:59.270 に答える
0

何らかの理由で、上記の実装をJson+圧縮を使用した自己ホスト型WCFRESTで機能させることができず、XMLのみで機能しました。

しばらくイライラした後、ついに以下のごく最近のブログから解決策を見つけました。これがまだ同じことを探している人に役立つことを願っています。

https://blogs.msdn.microsoft.com/carlosfigueira/2016/02/23/using-automatic-format-selection-with-a-compression-encoder-in-self-hosted-scenarios/

于 2016-03-15T04:33:15.570 に答える