3

我正在与 C# 中的 MS Dynamics GP WebServices 集成,但我不确定如何处理异常。

如果我使用不存在的 ID 执行 GetCustomer,W​​eb 服务会返回一个“通用”SoapException 并且消息是“未找到业务对象”。因此,我看到确定它是无效 ID 而不是任何其他错误的唯一方法是解析错误消息,我发现这个解决方案非常脆弱。我的 GP 版本是英语,在客户网站上它会是法语,我不知道网络服务消息会是哪种语言。我正在考虑捕捉它,解析消息并抛出更有意义的错误类型。

你看到更好的选择了吗?

4

5 回答 5

1

我有一篇博客文章详细介绍了我如何在 WCF 中克服这个问题(尽管如您所见,我不介意解析错误消息以获取详细信息)。这是它的肉:

catch (FaultException soapEx)
{
    MessageFault mf = soapEx.CreateMessageFault();
    if (mf.HasDetail)
    {
        XmlDictionaryReader reader = mf.GetReaderAtDetailContents();
        Guid g = reader.ReadContentAsGuid();
    }
}

获得 GUID 后,您可以使用它来查询 GP Web 服务以获取错误的详细信息。

于 2009-01-15T22:39:32.493 回答
1

不幸的是,eConnect API 和 GP Web 服务都返回一般错误,很高兴您不必解析 eConnect 错误。

好消息是,错误通常是静态的,因此您可以为它们构建解析器。创建自定义异常绝对是使用这种类型的 Web 服务的好方法。

于 2009-01-15T21:23:50.850 回答
0

对于对该主题感兴趣的人的信息,Jacob Proffitt 的回应看起来像是要走的路。这是 Dynamics GP 文档中的一个狙击手:

catch(SoapException soapErr)
{
    // If a validation exception occurred, the logid will be in a child node
    if(soapErr.Detail.HasChildNodes == true)
    {
        // Create a guid for the logid value in the soap exception
        Guid guid = new Guid(soapErr.Detail.InnerText);

        // Get the validation result object
        validationResult = wsDynamicsGP.GetLoggedValidationResultByKey(guid, context);

        // Display the number of validation exceptions
        MessageBox.Show("Number of validation exceptions: " +
        validationResult.Errors.Length.ToString());
    }

}

但在我引用的情况下:GetCustomer with an unexisting ID,“soapErr.Detail.HasChildNodes”行是假的,所以它失败了。

网络服务似乎充满了有趣的行为,这将比我预期的要长:(。

于 2009-01-16T18:42:10.673 回答
0

您是否可以控制 WebService 代码?

在这种情况下,我将返回带有更易于解析的简单错误代码的 SoapExceptions,并让客户端应用程序根据解析的错误代码决定要显示的消息。

您可以在 WebService 上使用“错误代码”枚举以使代码更具可读性。

//Example
enum ErrorCodes
{
  BusinessObjectNotFound = 1000,
  AnotherPossibleError = 1002
}

try
{
//Code
}
Catch(BusinessObjectNotFoundException bex)
{
  throw new SoapException(ErrorCodes.BusinessObjectNotFound);
  //Or maybe...
  //throw new SoapException(((int)ErrorCodes.BusinessObjectNotFound).ToString());
}
于 2009-01-15T21:11:07.570 回答
0

我开始讨厌全科医生了。这可能是“糟糕的形式”,但这是我所做的:

try
{
    // query service for object by key
}
catch (System.ServiceModel.FaultException e)
{
    if (e.Message == "Business object not found.")
    {
        // create new object
    }
    else
    {
        // log the exception appropriately
    }
}
于 2011-11-08T20:21:35.853 回答