2011-11-16 12 views
4

を返します。 web.configファイルでautomaticFormatSelectionEnabledを有効にすると、サービスはHTTPの「Accept」ヘッダーに基づいてXMLまたはJSONとしてシリアル化するかどうかを正しく選択します。私はブラウザでGETコマンドを発行するときWCF 4.0休憩サービスは、私がWCF 4.0 RESTサービスを持っているコンテンツタイプtext/htmlの

しかし、レスポンスボディはバックXMLとしてフォーマットが、HTTPのContent-Typeヘッダは「text/htmlの」あるいます。これにより、ブラウザは応答がXMLであることを認識せず、HTMLとしてレンダリングしようとします(もちろんうまくいきません)。これは、ブラウザで私のGETメソッドをテストすることをより困難にします。

automaticFormatSelectionEnabledを無効にすると、すべてが期待通りに機能します(レスポンスボディにXMLが含まれ、HTTPコンテンツタイプが "application/xml")。しかし、リクエストされた場合は自動的にJSONに切り替えることができます。

ブラウザを介して要求したときにコンテンツタイプが正しく戻ってくるようにするいくつかの方法はありますか?私は同じ問題に遭遇した

+0

テキスト/ HTMLの応答の本文は何ですか?それにはエラーメッセージが含まれていますか? – carlosfigueira

+0

ブラウザが使用しているaccept-Headerを調べるには、fiddlerのようなツールを使用します(または、デバッガを使用してWebOperationContext.Current.IncomingRequestを検査します)。少なくとも、あなたはそのような方法でブラウザの問題を排除することができます。 –

+0

ブラウザのAcceptヘッダーは "text/html、application/xhtml + xml、application/xml; q = 0.9、*/*; q = 0.8"です。これはFireFox標準/デフォルトです。レスポンス本文はXML(正しいものと予期されるXML)ですが、レスポンスのコンテンツタイプはtext/htmlなので、ブラウザはXMLドキュメントのように扱わず、HTMLとしてレンダリングしようとします。 –

答えて

3

、ここの周りの仕事があります。基本的には、レスポンスを送信するときにコンテンツタイプを変更する振る舞い拡張を作成する必要があります。

あなたのweb.configファイルのようなものが含まれる必要があるだろう。そして、あなたは最終的には、その後IDispatchMessageInspectorを実装するクラスをBehaviorExtensionElement

public class ServiceContentTypeBehaviorExtensionElement : BehaviorExtensionElement 
{ 
    protected override object CreateBehavior() 
    { 
     return new ServiceContentTypeMessageInspector(); 
    } 

    public override Type BehaviorType 
    { 
     get 
     { 
      return typeof(ServiceContentTypeMessageInspector); 
     } 
    } 
} 

から継承するクラスを作成し、する必要があります

<behaviors> 
    <serviceBehaviors> 
    <behavior name="WebServiceBehavior"> 
     <serviceMetadata httpGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="false" /> 
     <MessageInspector/> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 
<extensions> 
    <behaviorExtensions> 
    <add name="MessageInspector" 
      type="Namespace.ServiceContentTypeBehaviorExtensionElement, assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
    </behaviorExtensions> 
</extensions> 

をし、

public class ServiceContentTypeMessageInspector : IDispatchMessageInspector, IServiceBehavior 
{ 

    #region IDispatchMessageInspector 

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, 
     InstanceContext instanceContext) 
    { 
     return null; 
    } 

    public void BeforeSendReply(ref Message reply, object correlationState) 
    { 
     // inspect and/or modify the reply 
     if (WebOperationContext.Current.OutgoingResponse.Headers[HttpResponseHeader.ContentType] == "text/html; charset=utf-8" && 
      WebOperationContext.Current.OutgoingResponse.Format == WebMessageFormat.Xml) 
     { 
      WebOperationContext.Current.OutgoingResponse.Headers[HttpResponseHeader.ContentType] = "application/xml; charset=utf-8"; 
     } 
    } 

    #endregion 

    #region IServiceBehavior 

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, 
     ServiceHostBase serviceHostBase) 
    { 
     foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) 
     { 
      foreach (var endpoint in dispatcher.Endpoints) 
      { 
       endpoint.DispatchRuntime.MessageInspectors.Add(new ServiceContentTypeMessageInspector()); 
      } 
     } 
    } 

    public void AddBindingParameters(ServiceDescription serviceDescription, 
     ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, 
     BindingParameterCollection bindingParameters) 
    { 
    } 

    public void Validate(ServiceDescription serviceDescription, 
     ServiceHostBase serviceHostBase) 
    { 
    } 

    #endregion 
} 
:コンテンツタイプを変更することのハードワークを行いますIServiceBehavior

期待どおりに動作するはずです。

+0

本当に良いが、私はちょうどこれらのクラスのusingsを追加したい、おそらく彼らは助けるでしょう: ファーストクラス:System.ServiceModel.Configuration を使用して セカンドクラス: System.ServiceModel.Webを使用して; using System.ServiceModel; using System.ServiceModel.Dispatcher; using System.ServiceModel.Description; ; using System.ServiceModel.Description; using System.Net; using System.ServiceModel.Channels; using System.Collections.ObjectModel; – Khattab

+0

ソリューションのためにBevanに感謝します。また、これはASP.NET WebAPIで期待どおりに機能していることにも注意してください。 –

関連する問題