2017-09-29 9 views
0

WCFサービスからクライアントアプリケーションにカスタム例外をスローしようとしています。私はこれに関連すると思うほど多くのコードを記述しようとします。WCFサービスがクライアントにカスタム例外をスローする

例外:

using System.Runtime.Serialization; 

namespace App.Exceptions 
{ 
    /// <summary> 
    /// General App exception 
    /// </summary> 
    [DataContract] 
    public class AppException : System.Exception 
    { 
     private string strMessage = "An unknown exception occurred"; 

     /// <summary> 
     /// Creates a new instance of a App Exception 
     /// </summary> 
     public AppException() 
     { } 

     /// <summary> 
     /// Creates a new instance of a App Exception 
     /// </summary> 
     /// <param name="Message">Message to send as exception</param> 
     public AppException(string Message) 
     { strMessage = Message; } 

     public override string Message 
     { get { return strMessage; } } 
    } 
} 

サービスコード:

(...) 
using App.Exceptions; 

namespace App.Services 
{ 
    public class Service1 : IService1 
    { 
     public Service1() 
     { } 

     public void TestFunction() 
     { 
      throw new AppException(); 
     } 
    } 
} 

ServiceInterface:

(...) 

namespace App.Services.Interfaces 
{ 
    [ServiceContract] 
    public interface IService1 
    { 
     [OperationContract] 
     void TestFunction(); 
    } 
} 

クライアント:

(...) 
using App.Exceptions; 
(...) 

try 
{ 
    service.TestFunction(); 
} 
catch (AppException ex) 
{ 

} 

すべて正常に動作し、関数がサービスで呼び出され、例外がスローされます。参照は、クライアントとサーバーのいずれかでまったく同じです。私は喜んで、AppExceptionは同じネームスペースで参照されているので、大丈夫です。

私は別の例外を取得し、実際にそれはので、私は本当にブレークポイントをキャッチに設定された理由を理解していないよと異なる場合だけ見るためにFalseに設定も<serviceDebug includeExceptionDetailInFaults="True" />を設定し、するサービスapp.configに試してみましたAppExceptionは決してヒットしません。

EDIT:

サービスの設定:

<service name="App.Services.Service1"> 
    <endpoint address="" binding="basicHttpBinding" contract="App.Services.Interfaces.IService1"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
    <host> 
     <baseAddresses> 
     <add baseAddress="http://localhost:8733/Design_Time_Addresses/App.Services/Service1/" /> 
     </baseAddresses> 
    </host> 
    </service> 

クライアントの設定:

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
      <binding name="BasicHttpBinding_IService1" /> 
     </basicHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="http://localhost:8733/Design_Time_Addresses/App.Services/Service1/" 
      binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" 
      contract="Services.IService1" name="BasicHttpBinding_IService1" /> 
    </client> 
</system.serviceModel> 
+0

[クライアントへのWCF Webサービスカスタム例外エラー](https://stackoverflow.com/questions/1369882/wcf-web-service-custom-exception-error-to-client) – Marisa

+0

Iの可能性のある重複それもやってみた。 AppException catchは決してヒットしません。 – rgomez

+0

catch(AppException ex)またはcatch(FaultException ex)を使用しましたか?前者はうまくいかず、後者はすべきです。 – Marisa

答えて

0

あなたがに、サーバーから任意の未処理の例外またはそのような.NETまたは任意の例外をスローすることはできませんセキュリティと相互運用性の理由からクライアント(クライアントが哀れみを知りたい場合)は、これらの例外はデフォルトでは宣伝されませんwcfサービスからクライアントに送信されます。

例外を伝搬する代わりに、WCFはそれらをSOAP障害にシリアル化し、SOAP障害をクライアントに送信します。このカスタム例外をSOAP障害に含める必要があります。

最初servicecontractにどの操作がどのSOAP障害を投げることができるかを知らせます。

namespace App.Services.Interfaces 
{ 
    [ServiceContract] 
    public interface IService1 
    { 
     [FaultContract(typeOf(AppException))] 
     [OperationContract] 
     void TestFunction(); 
    } 
} 


using System.ServiceModel; 
public class Service1 : IService1 
    { 
     public Service1() 
     { } 

     public void TestFunction() 
     { 
      try 
      { 
      service.TestFunction(); 
      } 
      catch(Exception ex) 
      { 
       AppException app=new AppException(); 
       app.strMessage =ex.Message; 
       throw new FaultExcpetion<AppException>(app); 
      } 
     } 
    } 

さらに、フォルトの詳細とフォルトエラーが発生する可能性があります。クライアント側で上記の例外をキャッチします。

//client side 

    try 
       { 
        //call wcf service contract. 
       } 
       catch (FaultException<ServiceReference.AppException> ex) 
       { 

        label.Text=ex.Detail.strMessage ; 
       } 

もう一つの方法は、例外処理の集中管理方法のためのカスタムWCF IErrorHandler implementation.Referこのhttps://stackoverflow.com/a/8764782/6086968を使用することです。

Edit1:メタデータ用にapp.configを適切に設定する必要があります。

<service name="App.Services.Service1" behaviorConfiguration="mexendpoint"> 
     <endpoint address="" binding="basicHttpBinding" contract="App.Services.Interfaces.IService1"> 
      <identity> 
      <dns value="localhost" /> 
      </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://localhost:8733/Design_Time_Addresses/App.Services/Service1/" /> 
      </baseAddresses> 
     </host> 
     </service> 
<behaviors> 
    <serviceBehaviors> 
    <behavior name="mexendpoint"> 
     <serviceMetadata httpGetEnabled="true"/> 
     <serviceDebug includeExceptionDetailInFaults="true"/> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 
</system.serviceModel> 
+0

サービスインタフェースに '[FaultContract(typeof(AppException)]]を追加してそのプロジェクトをビルドすると、私はクライアントプロジェクトのサービス参照を更新できません。私は、クライアントと同じエラーの参照としてサービスプロジェクトを追加しようとしました - >エラー400メタデータは解決できない参照をcointains – rgomez

+0

あなたはサーバーサイドコードを構築できましたか?app.config xmlをどこに投稿できますか? wcfサービスのためのバインディングを定義する?また、完全なエラーメッセージを投稿してください。 –

+0

エラーは次のとおりです。 'メタデータには解決できない参照、'サービスのアドレス 'が含まれています。コンテンツタイプapplication/soap + xml; charset = utf-8はサービスでサポートされていませんでした。クライアントとサービスのバインドが一致していない可能性があります。リモートサーバーがエラーを返しました(415) 'application/soap + xml、charset = utf-8'のコンテンツタイプが 'text/xml'の予期されたタイプではないため、メッセージを処理できません。 chartset-utf8''...私は構成を含む質問を更新します。 – rgomez

関連する問題