|
WCF. возврат ошибок из методов сервиса
|
|||
---|---|---|---|
#18+
Добрый вечер, коллеги проектирую wcf-сервис, который будет использоваться не только .net-клиентами. возник вопрос, как лучше информировать клиента об эксепшенах (например, подключение к бд), ошибках валидации параметров метода и т.д. погуглив, нашел несколько вариантов: 1) для всего использовать FaultException. этот вариант мне не очень нравится, поскольку не логично иксепшены пробрасывать, когда у тебя, например, либо входной параметр не из нужного диапазона, либо какое-нибудь обязательное поле входной сущности не заполнено 2) создать класс, содеражащий ерроры. например так Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39.
этот вариант мне кажется более гибким. но здесь возникает сложность, которая заключается в следующем. если методы сервиса не должны ничего возвращать (например , методы для добавления, удаления строк в базу) то для таких методов как раз можно возвращаемым значением сделать тип OperationResult. а как быть если метод должен, например, коллекцию строк бд возвращать. куда этот OperationResult впихнуть? как out параметр? тоже считаю не очень хорошо. или же сделать эту коллекцию одним из свойств резалта? в общем вопрос. что скажете? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.11.2015, 18:53 |
|
WCF. возврат ошибок из методов сервиса
|
|||
---|---|---|---|
#18+
володька трынькин, На мой взгляд лучше все же использовать FaultContract. 1) для всего использовать FaultException. этот вариант мне не очень нравится, поскольку не логично иксепшены пробрасывать, когда у тебя, например, либо входной параметр не из нужного диапазона, либо какое-нибудь обязательное поле входной сущности не заполнено А почему не логично? Если у вас не заполнено обязательное поле, это вполне себе повод кинуть исключение, тем более что это стандартных механизм сообщить об ошибке. Я бы создал некий класс OperationFailedException, перехватывал бы все исключения и генерировал бы вышеупомянутое с описанием ошибки (при желании), т.е. примерно так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
Что касается создания кастомного result-класса, то можно добавить поле object Result (поле Description же есть, а при успешной выполнении операции, не требующей результата, оно скорее всего не будет инициализировано). Единственное что нужно, чтобы сериализатор умел получать актуальный тип объекта, а не пытался сериализовать как object. Вы указали, что сервисом будут пользоваться не только .net клиенты, соотв-но, скорее всего данные будут гоняться в каком-нибудь json, а ему все равно из чего будет состоять объект. Про protobuff и прочие не могу сказать. Или попробовать сделать обобщенным классом OperationResult<T>, но на счет этого я не уверен, т.к. не пробовал. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.11.2015, 21:04 |
|
WCF. возврат ошибок из методов сервиса
|
|||
---|---|---|---|
#18+
не заполнено обязательное поле, это вполне себе повод кинуть исключение исключение означает, что происходит какая-то ошибка, неожиданная ситуация при которой дальше никак нельзя работать. а если поле не заполнено, то это вполне себе штатное поведение, после которого просто необходимо клиента попросить заполнить это поле. на мой взгляд, первый вариант проще в реализации - все затачивается под FaultException и для клиента проще - он либо получает то, что ждет (коллекцию строк, либо void в случае, например, добавления) либо иксепшн. а вот во втором случае придется, как вы сказали, результат возвращать в виде object. и клиент будет еще гадать и лезть в документацию, чтобы посмотреть, какой реальный тип он получит. это не есть гуд... и попутно второй вопрос задам. как можно избавиться от дублирования кода в каждом методе. ведь у нас в каждом методе сервиса должен быть обработчик ошибок try-catch и причем с несколькими типами иксепшенов. это кстати будет при любом из двух способов. какие-то wrapper -ы писать?.. ребят, кто как реализует в своих сервисах? проблема, мне кажется, тривиальная ... |
|||
:
Нравится:
Не нравится:
|
|||
05.11.2015, 22:05 |
|
WCF. возврат ошибок из методов сервиса
|
|||
---|---|---|---|
#18+
авторисключение означает, что происходит какая-то ошибка, неожиданная ситуация при которой дальше никак нельзя работать. а если поле не заполнено, то это вполне себе штатное поведение, после которого просто необходимо клиента попросить заполнить это поле. Если у вас не заполнено обязательное поле, вы уже не можете работать дальше, вы не можете должным образом выполнить действие в контексте вашей операции. Это не означает "критический сбой" вроде OutOfMemory, но с точки зрения вашего кода это как раз таки "неожиданная ситуация при которой дальше никак нельзя работать" (в контексте данного запроса). Посмотрите на то, как это реализовано в ASP.NET. Фреймворк может перехватить исключение и транслировать его в соотв. статус-код HTTP, например, если вы выкините что-то вроде UnauthorizedException, можно смапить его на 401 код ошибки. Еще в качестве плюса - использование FaultContract не переводит канал в состояние Faulted. Вы точно определяете, что выполнение обращения к серверу может завершится неудачей и это нормально. А уже каким образом вы будете данную "неудачу" обрабатывать - кидать исключение повторно, пытаться анализировать и как-то восстановить систему (в вашем примере - предложить ввести требуемое поле) это уже решать клиенту. Но что использовать решать, конечно, вам. как можно избавиться от дублирования кода в каждом методе. ведь у нас в каждом методе сервиса должен быть обработчик ошибок try-catch и причем с несколькими типами иксепшенов. это кстати будет при любом из двух способов. какие-то wrapper -ы писать?.. Можно попробовать инструментирование кода (PostShart, Afterthrought), можно оставить код, связанный с обработкой ошибок в классе WCF сервиса, а всю логику вынести в другой класс. WCF сервис соотв-но будет делегировать работу этому внутреннему классу. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2015, 00:15 |
|
|
start [/forum/topic.php?fid=19&fpage=6&tid=1396836]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
1489ms |
get topic data: |
12ms |
get forum data: |
2ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
37ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
31ms |
get tp. blocked users: |
1ms |
others: | 8220ms |
total: | 9862ms |
0 / 0 |