Обработка ошибок WCF - PullRequest
       54

Обработка ошибок WCF

1 голос
/ 06 июля 2011

Я работаю на клиенте, который использует службу WCF. В различных случаях служба просто вызывает FaultException со связанным сообщением, информирующим о причине данной ошибки.

Некоторые из этих сбоев - это вещи, которые могут быть обработаны нашим клиентским приложением, но я не решаюсь просто попытаться выполнить какое-либо сопоставление строк в сообщении или причине FaultExceptions, чтобы определить, может ли это быть чем-то, что мы можем обработать или нет.

Я надеялся, что FaultCode на FaultException можно будет использовать для идентификации конкретного типа Fault, который мы могли бы обработать, но, похоже, это просто для определения нескольких ошибок SOAP. Пожалуйста, поправьте меня, если моя интерпретация неверна.

Я знаю, что может быть, что FaultException может быть вызвано, но я чувствую, что нереально ожидать, что новый тип должен быть создан для каждой причины ошибки.

Как вы справляетесь с этой ситуацией. В качестве надуманного примера. Рассмотрим сервис, который предоставляет следующие методы:

RecordDetails GetRecordById(string id)

void Add(RecordDetails record)

void Update(RecordDetailsUpdateRequest rdur)

Теперь в приведенном выше примере, если вы вызываете GetRecordById с несуществующим идентификатором, вы получаете исключение FaultException с сообщением «Запись не может быть найдена». Точно так же, если вы вызываете Добавить для уже существующей записи или Обновить для несуществующей записи, вы просто получаете FaultException с сообщением / Причиной, подробно описывающим причину сбоя. Мне нужно знать, существует ли запись или нет, чтобы определить, следует ли мне обновить или вставить. Как я уже упоминал, я не решаюсь просто сопоставлять строки, так как не могу контролировать, останутся ли они одинаковыми или нет.

Что вы ожидаете в этой ситуации (тип, связанный с FaultException, подробно описывающий RecordNotFoundException и т. Д.) Или некоторый универсальный тип, связанный с FaultException, который определяет конкретные детали, относящиеся к ошибке. Например, класс RecordOperationExcpetion с членами Code (константа или перечислимый идентификатор причины сбоя) вместе с удобным для пользователя сообщением.

По крайней мере, так я мог бы определить причину ошибки, не прибегая к сопоставлению строк.

Ваши мысли ценятся.

Ответы [ 2 ]

2 голосов
/ 06 июля 2011

Я бы пошел с тем, что вы сказали выше - тип, связанный с FaultException. Вы можете создать любое количество классов, представленных как DataContract, для обработки различных ошибок, а затем назначить их операциям службы WCF.

[DataContract]
public class RecordOperationException
{
    private int code;
    private string message;

    [DataMember]
    public int Code
    {
        get
        {
            return code;
        }
        set
        {
            code = value;
        }
    }

    [DataMember]
    public string Message
    {
        get
        {
            return message;
        }
        set
        {
            message = value;
        }
    }
}

Затем вы можете назначить этот класс как FaultException:

[OperationContract]
[FaultContract(typeof(RecordOperationException))]
RecordDetails GetRecordById(string id)

[OperationContract]
[FaultContract(typeof(RecordOperationException))]
void Add(RecordDetails record)

[OperationContract]
[FaultContract(typeof(RecordOperationException))]
void Update(RecordDetailsUpdateRequest rdur)

Затем вы можете выбросить соответствующее FaultException в ваших методах, по желанию.

Это избавит от необходимости сравнивать строки (это хорошая идея, ИМО).

0 голосов
/ 06 июля 2011

I всегда использует FaultExceptions и объявляет их как часть OperationContract, как это делает ваш код.

Однако я думаю, что в этом есть нечто большее.

Мы все знаем, что разделение интересов - это хорошо, и вы можете достичь этого с помощью своих сервисов, создав классы, реализующие IErrorHandler.

Затем они могут использоваться с вашим классом и обработкой ошибок.может быть отделен от вашей логики, делая более чистый способ сделать это.Это также означает, что вам не нужно повторять идентичные блоки по всему коду.

Это также можно использовать с универсальным FaultException.

Хороший ресурс: http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.aspx

...