WCF FaultException
-
23-12-2019 - |
Pregunta
Cuando la construcción de un servicio WCF, si me no se incluyen mi contrato para la FaultException en el servicio, soy capaz de crear un servicio WCF de referencia en el cliente con todos los miembros incluidos en la Referencia.cs archivo.
Si Me incluyen mi FaultException contrato, suceden dos cosas.
En el cliente de prueba de WCF, Tengo una "X"roja al lado del nombre del contrato (CreateFaultMessage)
Al crear el servicio WCF de referencia, no todos los miembros son incluido en la Referencia.cs archivo.
Yo estoy esperando que alguien pueda informarme de lo que estoy haciendo incorrectamente tan lejos como la creación de mi FaultException contrato, ya que no soy un WCF experto.
A continuación, el código de declaración de mi contrato en la interfaz.
[OperationContract]
[FaultContractAttribute(typeof(LogEventArgs), ProtectionLevel = ProtectionLevel.None)]
Exception CreateFaultMessage(Exception ex, string method);
A continuación, son métodos de la clase que implemente la interfaz. Aviso de la llamada a la CreateFaultMessage método en el bloque catch de la PostTransmissionRecord método.
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);
}
CÓDIGO ACTUALIZADO
DataContract clase
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;
}
}
.
.
.
Método de servicio tirar 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;
}
}
EL CÓDIGO DE CLIENTE DE LA CAPTURA DE LA FAULTEXCEPTION
catch (FaultException<LogEventArgs> ex)
{ ex.Detail.ApplicationID = "ShopProcessService";
ex.Detail.LogEventType = LogEventTypeEnum.Error;
serviceClient.Abort();
}
Solución
Para simplificar el enfoque de lanzar una FaultException
desde el servicio y la captura y el procesamiento en el lado del cliente, por favor siga este código:
Servicio:
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"))
}
}
Cliente:
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;
}
Estoy seguro de que esto iba a resolver sus problemas.:-)
Otros consejos
Por favor, intente definir el CustomFault (Mathfault en este ejemplo) como un contrato de datos en lugar del contrato de operación, como:
[DataContract]
public class MathFault
{
//...
}
en el lado del cliente:
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();
}
}
Ver más: Contrato de falla