Я работаю над нашей интеграцией системы с некоторой службой xml, и я хотел бы знать, есть ли какие-либо рекомендации по обработке ответов, представляющих ошибки. Например, у меня есть запрос:
<FindSmthPls>
<Login>MyLogin</Login>
<Password>MyPassword</Password>
<SomeAttributes>...</SomeAttribute>
</FindSmthPls>
И ответ:
<FindSmthResponse>
<SomeResults>...</SomeResults>
</FindSmthResponse>
Но в случае, если служба xml возвращает ошибку в формате:
<Error>
<ErrorCode>1</ErrorCode>
<ErrorMessage>Sorry but we cannot find anything for your request!</ErrorMessage>
</Error>
Я не могу десериализовать этот xml в FindSmthResponse, поэтому я должен обрабатывать ошибки следующими способами:
try
{
return Deserialize<T>(xml);
}
//for the cases when I cannot deserialize response
//I can assume that service returned an error
catch (InvalidOperationException ex)
{
var error = Deserialize<TError>(xml);
throw new XmlException(error);
}
Но, как вы можете видеть из моего примера ответа с ошибкой выше, не все ошибки являются плохими, некоторые из них просто говорят, что вернуть нечего. Поэтому, когда я обрабатываю эту ошибку, я должен добавить smth:
catch (XmlException e)
{
//workaround for cases when service returns errors like: result is empty
if (_safeErrors.Any(c =>
c.Key.Equals(e.XmlError.Code, StringComparison.InvariantCultureIgnoreCase) &&
c.Value.Equals(e.XmlError.Message, StringComparison.InvariantCultureIgnoreCase)))
{
return null;
}
throw new XmlApiException(e);
}
В этом решении по крайней мере два минуса:
Конечно, это решение работает, но я действительно хочу знать, может быть, есть несколько лучших практик, как мы можем обрабатывать разные ответы xml для одного запроса xml?
ps, обратите внимание, что служба XML, с которой я интегрируюсь, может вернуть ошибку с кодом 1 как для реального исключения, например: неправильный логин и пустой результат поиска.
Я бы предложил что-то вроде этого:
<FindSmthResponse>
<Header>
<Errors>
<Error>
<Code>0</Code>
<Detail>Success</Detail>
</Error>
</Errors>
</Header>
<SomeResults>...</SomeResults>
</FindSmthResponse>
Вы даже можете создать определение заголовка, поскольку оно является собственником xsd, если вы их используете, и затем оно может использоваться для любых ваших служб. Просто добавьте свой элемент в заголовок службы, а затем, когда вы смотрите, вы можете десериализовать всю вещь, а затем проверить, есть ли ошибки в другой части вашей логики.