2010-11-24 79 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实例,并可以将其用于其他调用。

如果你不知道如何做到这一点,咆哮,我会砰的一声。