Как вернуть стандартное сообщение об исключении / ошибке в WCF
В нашем приложении все данные контракта имеют одного родителя - OperationResponse
и это OperationResponse
содержит enum (тип enum OperationState
в собственности Result
) который представляет результат вызова (Ok, InvalidParams, Error).
Как я могу переписать поведение WCF после исключения - не возвращать состояние ошибки, а возвращать классическое сообщение, в моем случае OperationResponse, но со свойством Result = OperationState.Error?
Изменить: Я думаю, я на правильном пути, мне нужно реализовать IErrorHandler, но теперь я потерян, потому что я не знаю, как установить сообщение об ошибке в исходящее сообщение об ошибке...
public bool HandleError(Exception error)
{
// log error
return true; // we catch error and provide our custom message.
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
// create result message
var message = new OperationResponse
{
Result = OperationState.Error
};
// ok how to return message into ref fault?
}
Edit2: кажется, что это неразрешимая проблема без решения... Я нашел только те же вопросы без решения, как эта тема...:(
1 ответ
Я не уверен, что это именно то, что вы ищете, но это довольно управляемый способ обработки ошибок из WCF (и, возможно, других систем / контекстов).
Здесь мы создаем общий ServiceResponse<T>
, который может содержать любой тип ответа в свойстве Data
и информация о состоянии в Succeeded
а также StatusMessage
,
Использовать CreateServiceResponse()
чтобы обернуть, какой метод вы хотите вызвать внутри этого объекта. Таким образом, вы можете вернуть ServiceResponse
с Data
установить на результат от этого метода. Ниже приведен пример использования.
Возможно, вы можете настроить это, чтобы вернуть экземпляр вашего OperationResponse
с OperationState
вместо Succeeded
собственность используется здесь?
public class ServiceResponse<T>
{
public ServiceResponse()
{
// Initial default values:
Data = default(T);
Succeeded = true;
StatusMessage = string.Empty;
}
// Indicates whether the attempted operation was completed successfully.
[DataMember]
public bool Succeeded { get; set; }
// Error messages if an operation fails.
[DataMember]
public string StatusMessage { get; set; }
// The main results from any service-call.
[DataMember]
public T Data { get; set; }
[DataMember]
public String InnerExceptionMessage { get; set; }
public static ServiceResponse<T> CreateServiceResponse(Func<T> responseFunc)
{
var response = new ServiceResponse<T>();
try
{
response.Data = responseFunc.Invoke();
}
catch (Exception ex)
{
response = HandleException(responseFunc, ex);
}
return response;
}
private static ServiceResponse<T> HandleException(Func<T> responseFunc, Exception ex)
{
// Handle any exceptions here, and return a ServiceResponse with
// Succeeded = false, and the appropriate messages, etc.
}
}
Пример использования (при условии, что GetClients() вернет IEnumerable):
var response = ServiceResponse<IEnumerable<Client>>
.CreateServiceResponse(() => GetClients(clientGroupId));