2010-11-24 13 views
2

OData WebサービスへのPOSTを行うC#コードがあります。その結果、レコードがデータベースに挿入されます。主キー違反などの例外がある場合は、エラーメッセージをキャプチャしてログに記録します。ただし、メッセージはXML内に含まれています。ここに私の例外ハンドラがある:内部例外をWebExceptionから解析する方法

catch (WebException ex) 
{ 
    if (ex.Status == WebExceptionStatus.ProtocolError) 
    { 
     string responseText = string.Empty; 

     using (Stream responseStream = ((HttpWebResponse)ex.Response).GetResponseStream()) 
     { 
      using (StreamReader streamReader = new StreamReader(responseStream)) 
      { 
       responseText = streamReader.ReadToEnd(); 
      } 
     } 
     Debug.WriteLine(responseText); 
     return responseText; 
    } 
    else 
    { 
     Debug.WriteLine(ex.Message.ToString()); 
     return ex.Message.ToString(); 
    } 
} 

ここで私はresponseTextで得るものです:

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> 
    <code></code> 
    <message xml:lang="en-US">An error occurred while processing this request.</message> 
    <innererror> 
    <message>An error occurred while updating the entries. See the inner exception for details.</message> 
    <type>System.Data.UpdateException</type> 
    <stacktrace> at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)&#xD; 
    at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache)&#xD; 
    at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)&#xD; 
    at System.Data.Services.Providers.ObjectContextServiceProvider.SaveChanges()&#xD; 
    at System.Data.Services.DataService 1.HandleNonBatchRequest(RequestDescription description)&#xD; 
    at System.Data.Services.DataService 1.HandleRequest()</stacktrace> 
    <internalexception> 
     <message>Violation of PRIMARY KEY constraint 'PK_Customer_CustomerId'. Cannot insert duplicate key in object 'VertexBilling.Customer'.&#xD; 
The statement has been terminated.</message> 
     <type>System.Data.SqlClient.SqlException</type> 
     <stacktrace> at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)&#xD; 
    at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)&#xD; 
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()&#xD; 
    at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)&#xD; 
    at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()&#xD; 
    at System.Data.SqlClient.SqlDataReader.get_MetaData()&#xD; 
    at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)&#xD; 
    at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)&#xD; 
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)&#xD; 
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)&#xD; 
    at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)&#xD; 
    at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)&#xD; 
    at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)&#xD; 
    at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary 2 identifierValues, List 1 generatedValues)&#xD; 
    at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)</stacktrace> 
    </internalexception> 
    </innererror> 
</error> 

私はinnererrorのうち、internalexceptionの外にメッセージを取得する必要があります。それを行う最も簡単な方法は何ですか?

+0

BTW、ex.Messageは既に文字列です。 '.ToString()'を使う必要はありません –

答えて

0

最も簡単な方法は次のように正規表現を使用することが考えられます"<message>""</message>"の間で文字列を抽出するために、次の、非常に堅牢ではありません、それはXMLの精神ではありません

<message>(.+)</message> 

が、 XMLがあまり変わらない限り動作するはずです。また、アプリでまだXMLツールを使用していない場合は、この文字列を抽出するだけでは必ずしもそれを改善する必要はありません。

+0

問題は、内の内にがあり、内にがあります。 –

+0

@マーク:良い点。これは、*非常に単純なケースでない限り、正規表現を使ってXMLを処理するべきではない理由です。他の人の答えを試してみましょう。効率を上げるために、最初の "//"を "/"に変更します。 – LarsH

1

あなたはXMLツールキットを使用する必要があり、すでに.NETであなたの処分でそれを持っているし、テキストとしてXMLを処理するとき、それは曖昧さの問題を取り除く(その悪夢が起こるのを待って、上記のXMLで使用すると、2つのメッセージノードを持つ)

XmlDocumentオブジェクトへ
  1. ロード列
  2. 使用//エラー/ innerError/internalexception /メッセージのXPathは、代わりにあなたが/抽出にのInnerExceptionをデシリアライズするコードの小片を構築することができます必要なノード

を抽出しますExceptio他の呼び出しのために再利用することができます。

あなたがこれを行う方法がわからない場合、ハウラー、私は何かを強打します。

+0

"docNav = new XPathDocument(responseText);を使用して変換しようとしました。しかし、私は "パスの不正な文字" ArgumentExceptionを取得します。私は一重引用符をString.Emptyで置き換えようとしましたが、それは助けになりませんでした。 もしあなたがこの混乱を.Net Exceptionに変換するために何か荒れ狂うことができたら、それは非常に役に立ちます。 –

+0

実際、これを行う前に、odataにアクセスするためにどのlibを使用しましたか? http://odata.codeplex.com/のものを使用しましたか? – mmix

+0

私はVS 2010/.Net 4に何が入っていても使用しています。 –

関連する問題