WCF FaultException
При создании службы WCF, если я не включаю свой контракт для FaultException в службу, я могу создать ссылку на службу WCF на клиенте со всеми элементами, включенными в файл Reference.cs.
Если я включу свой контракт FaultException, произойдут две вещи.
В тестовом клиенте WCF у меня есть красный крестик рядом с именем контракта (CreateFaultMessage)
Когда я создаю ссылку на службу WCF, не все члены включаются в файл Reference.cs.
Я надеюсь, что кто-нибудь сможет сообщить мне, что я делаю неправильно, если я создаю свой контракт FaultException, так как я не эксперт WCF.
Ниже приведено объявление кода моего контракта в интерфейсе.
[OperationContract]
[FaultContractAttribute(typeof(LogEventArgs), ProtectionLevel = ProtectionLevel.None)]
Exception CreateFaultMessage(Exception ex, string method);
Ниже приведены методы в классе, которые реализуют интерфейс. Обратите внимание на вызов метода CreateFaultMessage в блоке catch метода PostTransmissionRecord.
public bool PostTransmissionRecord(TransmissionRecord transmissionRecord)
{
bool blnUpdated = false;
try
{
blnUpdated = TransmissionRecordGateway.InsertData(transmissionRecord);
LogMessage.WriteEventLog("Transmission records updated successfully", "Ryder.ShopProcessService.SOA", 3, null);
return blnUpdated;
}
catch (Exception ex)
{
LogMessage.WriteEventLog("Class: ShopProcessService" + CrLf + "Method: PostTransmissionRecord" + CrLf + "Error: " + ex.Message + CrLf + "InnerException: " + ex.InnerException + CrLf + "Source: " + ex.Source + CrLf + "StackTrace: " + ex.StackTrace, "Ryder.ShopProcessService.SOA", 1, null);
IssueRemedyTicket("Class: ShopProcessService" + CrLf + "Method: PostTransmissionRecord" + CrLf + "Error: " + ex.Message + CrLf + "InnerException: " + ex.InnerException + CrLf + "Source: " + ex.Source + CrLf + "StackTrace: " + ex.StackTrace);
CreateFaultMessage(ex, "UpdateSearchInventory");
return blnUpdated;
}
}
public Exception CreateFaultMessage(Exception ex, string method)
{
LogEventArgs detail = new LogEventArgs();
detail.ApplicationID = "ShopProcessService";
detail.ExceptionMessage = ex.Message;
detail.LogEventType = LogEventTypeEnum.Error;
detail.Method = method;
detail.Source = ex.Source;
detail.StackTrace = ex.StackTrace;
if (ex.InnerException != null)
detail.InnerExceptionMessage = ex.InnerException.ToString();
else
detail.InnerExceptionMessage = null;
throw new FaultException<LogEventArgs>(detail);
}
ОБНОВЛЕННЫЙ КОД
Класс DataContract
namespace Ryder.Enterprise.DataTransferObjects
{
[Serializable, DataContract(Name = "LogEventArgs", Namespace = "http://www.Ryder.com/SOA/DataContracts/2014/02/17")]
public class LogEventArgs
{
private string applicationID;
private string method;
private LogEventTypeEnum logEventType;
private string exceptionMessage;
private string innerExceptionMessage;
private string stackTrace;
private string source;
[DataMember(Name = "ApplicationID")]
public string ApplicationID
{
get
{
return applicationID;
}
set
{
applicationID = value;
}
}
.
.
.
Служебный метод метания FAULTEXCEPTION
public bool UpdateSpotCheckInventory(SpotCheck transferObject)
{
bool blnUpdated = false;
try
{
blnUpdated = SpotCheckCollectionGateway.UpdateData(transferObject);
LogMessage.WriteEventLog("SpotCheck records updated successfully", "Ryder.ShopProcessService.SOA", 3, null);
return blnUpdated;
}
catch (Exception ex)
{
//throw fault exception here on service
return blnUpdated;
}
}
КОД КЛИЕНТА, Улавливающий НЕИСПРАВНОСТЬ
catch (FaultException<LogEventArgs> ex)
{ ex.Detail.ApplicationID = "ShopProcessService";
ex.Detail.LogEventType = LogEventTypeEnum.Error;
serviceClient.Abort();
}
2 ответа
Для упрощения подхода броска FaultException
от службы, а также отлова и обработки на стороне клиента, пожалуйста, следуйте этому коду:
Обслуживание:
public bool UpdateSpotCheckInventory(SpotCheck transferObject)
{
bool blnUpdated = false;
try
{
blnUpdated = SpotCheckCollectionGateway.UpdateData(transferObject);
LogMessage.WriteEventLog("SpotCheck records updated successfully", "Ryder.ShopProcessService.SOA", 3, null);
return blnUpdated;
}
catch (Exception ex)
{
//throw fault exception here on service
throw new FaultException("A fatal exception occurred while processing your request", new FaultCode("1000"))
}
}
Клиент:
catch (FaultException ex)
{
ex.Detail.ApplicationID = "ShopProcessService";
ex.Detail.LogEventType = LogEventTypeEnum.Error;
serviceClient.Abort();
// You can also access the custom message and error code sent from the service...
String customErrorCode = ex.Code.Name;
String customErrorMessage = ex.Reason;
}
Я уверен, что это решит ваши проблемы.:-)
Пожалуйста, попробуйте определить CustomFault(в этом примере MathFault) как договор на данные, а не договор на эксплуатацию, например:
[DataContract]
public class MathFault
{
//...
}
На стороне клиента:
static void Main(string[] args)
{
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
try
{
int value1 = 22;
int value2 = 0;
int result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
client.Close();
}
catch (FaultException<MathFault> e)
{
Console.WriteLine("FaultException<MathFault>: Math fault while doing " + e.Detail.Operation + ". Problem: " + e.Detail.ProblemType);
client.Abort();
Console.ReadLine();
}
}
Смотрите больше: Fault Contract