2010-11-24 49 views
2

我有C#代碼執行POST到OData Web服務,這會導致將記錄插入到數據庫中。如果存在例外,例如主鍵違例,我想捕獲並記錄錯誤消息。但是,該消息包含在XML中。這裏是我的異常處理程序:如何從WebException響應中解析internalexception

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> 

我需要得到的消息出來internalexception出來的innererror的。最簡單的方法是什麼?

+0

順便說一句,ex.Message已經是一個字符串。你不需要使用`.ToString()` – 2010-11-24 23:01:35

回答

0

最簡單的的方法可能是使用正則表達式像下面提取"<message>""</message>"之間的字符串:

<message>(.+)</message> 

這不是非常強勁,它不是在XML的精神,但它應該工作,除非XML變化很大。如果你還沒有在你的應用中使用XML工具,那麼你不一定要將它們重新提取出來以提取這個字符串。

+0

問題是在我想要的內的內有一個,而我沒有在內有一個。 – 2010-12-14 22:10:52

+0

@Mark:好點。這就是爲什麼你不應該使用正則表達式來處理XML,除非它是一個非常簡單的情況。 :-)嘗試其他人的答案,除了將初始「//」更改爲「/」以獲得更高的效率。 – LarsH 2010-12-14 23:00:01

1

你應該使用XML工具包,你已經擁有了它在您的處置在.NET和治療XML時,文本(它是一場噩夢等待發生,在上面的XML你有兩個消息的節點)

它消除歧義的問題
  1. 負載字符串的XmlDocument
  2. 使用//錯誤/ innerError/internalexception /消息的xpath以提取所需要的節點

替代地可以構建一個小塊代碼這將提取/反序列化到的InnerException一個Exceptio n實例,並可以將其用於其他調用。

如果你不知道如何做到這一點,咆哮,我會砰的一聲。