c# - "El creador de esta falla no especificó una Excepción de Reason"
.net wcf (10)
Al utilizar try try fuertemente tipado, pude resolver el error "El creador de esta falla no especificó una Razón".
Tengo el siguiente código en el servicio WCF para arrojar un error personalizado en función de ciertas situaciones. Recibo una excepción "El creador de este error no especificó una Razón". ¿Qué estoy haciendo mal?
//source code
if(!DidItPass)
{
InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");
throw new FaultException<InvalidRoutingCodeFault>(fault);
}
//operation contract
[OperationContract]
[FaultContract(typeof(InvalidRoutingCodeFault))]
bool MyMethod();
//data contract
[DataContract(Namespace="http://myuri.org/Simple")]
public class InvalidRoutingCodeFault
{
private string m_ErrorMessage = string.Empty;
public InvalidRoutingCodeFault(string message)
{
this.m_ErrorMessage = message;
}
[DataMember]
public string ErrorMessage
{
get { return this.m_ErrorMessage; }
set { this.m_ErrorMessage = value; }
}
}
Después de algunas investigaciones adicionales, el siguiente código modificado funcionó:
if(!DidItPass)
{
InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");
throw new FaultException<InvalidRoutingCodeFault>(fault, new FaultReason("Invalid Routing Code - No Approval Started"));
}
La actualización de la referencia del servicio en el cliente resolvió el problema. Lo mismo podría funcionar para ti.
La respuesta corta es que no está haciendo nada incorrecto, simplemente leyendo los resultados incorrectamente.
En el lado del cliente cuando detecta el error, lo que se captura es del tipo System.ServiceModel.FaultException<InvalidRoutingCodeFault>
.
Su objeto InvalidRoutingCodeFault
está realmente en la propiedad .detail
de FaultException. ASI QUE....
// codigo del cliente
private static void InvokeMyMethod()
{
ServiceClient service = new MyService.ServiceClient();
try
{
service.MyMethod();
}
catch (System.ServiceModel.FaultException<InvalidRoutingCodeFault> ex)
{
// This will output the "Message" property of the System.ServiceModel.FaultException
// ''The creator of this fault did not specify a Reason'' if not specified when thrown
Console.WriteLine("faultException Message: " + ex.Message);
// This will output the ErrorMessage property of your InvalidRoutingCodeFault type
Console.WriteLine("InvalidRoutingCodeFault Message: " + ex.Detail.ErrorMessage);
}
}
La propiedad Message de FaultException es lo que se muestra en la página de error, de modo que si no está poblada como en la publicación de John Egerton, verá el mensaje "El creador de este error no especificó una Razón". Para poblarlo fácilmente, use el constructor de dos parámetros cuando arroje la falla en el servicio de la siguiente manera, pasando su mensaje de error desde su tipo de falla:
InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");
throw new FaultException<InvalidRoutingCodeFault>(fault, new FaultReason(fault.ErrorMessage));
Puede probar esto en la configuración del servidor (comportamientos -> comportamientosServicio -> comportamiento):
<serviceDebug includeExceptionDetailInFaults="true" />
Resolví este problema usando un constructor de dos parámetros.
// service method implementation
throw new FaultException<FormatFault>(fault,new FaultReason(fault.CustomFaultMassage));
CustomFaultMassage es propiedad del contrato de datos.
Si no desea recibir notificaciones sobre tales excepciones, vaya a Depurar -> Excepciones y desmarque "Usuario no controlado" para "Excepciones de Common Language Runtime" o para excepciones específicas.
También se puede encontrar esta excepción si no se especifica el atributo FaultContract (typeof (className)) para el método.
Tengo un código exactamente como Rashmi y obtuve el error "El creador de este error ...". Estaba sucediendo cuando estaba depurando en VS2010. Encontré esta publicación:
que explicaba un par de opciones de depuración que necesitaba desactivar. Problema resuelto.
serviceDebug includeExceptionDetailInFaults="true"
NO es la solución
El siguiente código funciona incluso con serviceDebug includeExceptionDetailInFaults="false"
// data contract
[DataContract]
public class FormatFault
{
private string additionalDetails;
[DataMember]
public string AdditionalDetails
{
get { return additionalDetails; }
set { additionalDetails = value; }
}
}
// interface method declaration
[OperationContract]
[FaultContract(typeof(FormatFault))]
void DoWork2();
// service method implementation
public void DoWork2()
{
try
{
int i = int.Parse("Abcd");
}
catch (FormatException ex)
{
FormatFault fault = new FormatFault();
fault.AdditionalDetails = ex.Message;
throw new FaultException<FormatFault>(fault);
}
}
// client calling code
private static void InvokeWCF2()
{
ServiceClient service = new ServiceClient();
try
{
service.DoWork2();
}
catch (FaultException<FormatFault> e)
{
// This is a strongly typed try catch instead of the weakly typed where we need to do -- if (e.Code.Name == "Format_Error")
Console.WriteLine("Handling format exception: " + e.Detail.AdditionalDetails);
}
}
No es necesario agregar el motivo de la falla si no es necesario. Solo asegúrese de que el atributo FaultContract sea correcto