tutorial consumir wcf rest soap

consumir - WCF IErrorHandler devolverá FaultException a SOAP y WebHttpException a los puntos finales POX y Json



wcf soap service c# (2)

En una aplicación REST en la que estoy trabajando, creé una nueva clase derivada de WebFaultException<T> que adjunta algunos datos adicionales a las excepciones de servicio capturadas. Llamar al método CreatingMessageFault() en la instancia de la clase derivada me permite devolver mis datos de excepción seleccionados del método ProvideFault() del controlador de errores como el error SOAP, permitiendo que WCF determine el formato de mensaje correcto.

Estoy usando webHttpBinding para enlazar todos menos algunos servicios de terceros.

Edición: Ejemplo de código agregado

public class ErrorHandler : IErrorHandler, IServiceBehavior { public virtual void ProvideFault( Exception error, MessageVersion version, ref Message fault ) { // Include next level of detail in message, if any. MyFaultException myFaultException = ((error is MyFaultException) && ((MyFaultException)error).Detail != null) ? new MyFaultException(error.Message + " - " + ((MyFaultException)error).Detail.Message, error) : new MyFaultException( error.Message, error ); MessageFault messageFault = myFaultException.CreateMessageFault(); fault = Message.CreateMessage( version, messageFault, myFaultException.Action ); } }

y

/// <summary> /// Class used to return exception data from my WCF services. /// </summary> /// <remarks> /// This class is used by a web service to pass exception data back and a /// data object to the client. This class inherits WebFaultException, which /// is handled specially by the WCF WebServiceHost2 service class and /// generates a WebException on the client. /// </remarks> public class MyFaultException : WebFaultException<BusinessFault> { public class MyFaultException : WebFaultException<BusinessFault> { public MyFaultException(string message) : this(HttpStatusCode.BadRequest, message) { } public MyFaultException(HttpStatusCode statusCode, string message) : base(new BusinessFault(message), statusCode) { } }

Luego, en su servicio, puede lanzar la excepción para pasar datos de fallas a su cliente:

try { // Successful operation proceeds normally. } catch (ApplicationException e) { // Failure generates MyFaultException. throw new MyFaultException("Operation failed with " + e.Message); }

Tengo un conjunto de servicios web SOAP que están envolviendo excepciones usando IErrorHandler, específicamente:

public sealed class ErrorHandler : IErrorHandler { public bool HandleError(Exception error) { return true; } public void ProvideFault(Exception error, MessageVersion version, ref Message fault) { // don''t wrap existing fault exceptions if ((error is FaultException)) return; // our basic service fault var businessFault = new BusinessFault { FaultMessage = error.Message, FaultReference = "Internal" }; // Resource based faultReason var faultReason = new FaultReason(Properties.Resources.BusinessFaultReason); var faultcode = FaultCodeFactory.CreateVersionAwareSenderFaultCode(InternalFaultCodes.BusinessFailure.ToString(), Service.Namespace); var faultException = new FaultException<BusinessFault>( businessFault, faultReason, faultcode); // Create message fault var messageFault = faultException.CreateMessageFault(); // Create message using Message Factory method fault = Message.CreateMessage(version, messageFault, faultException.Action); } }

Ahora he agregado puntos finales adicionales para Json y Pox que funcionan bien, a menos que se produzca una excepción. En el caso del punto final Json, la FaultException se devuelve como XML.

Soy consciente de otras publicaciones de SO que, en el caso de REST, sería mejor lanzar una WebHttpException:

throw new WebFaultException<BusinessFault>(detail, HttpStatusCode.BadRequest);

O anular las propiedades del mensaje de respuesta en ProveFault, por lo tanto:

var wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json); fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf); var rmp = new HttpResponseMessageProperty { StatusCode = System.Net.HttpStatusCode.BadRequest, StatusDescription = "See fault object for more information." }; fault.Properties.Add(HttpResponseMessageProperty.Name, rmp);

Sin embargo, MSDN tiene algunos comentarios interesantes sobre la WebHttpException saber:

Cuando se utiliza un punto final de WCF REST (WebHttpBinding y WebHttpBehavior o WebScriptEnablingBehavior), el código de estado HTTP en la respuesta se establece en consecuencia. Sin embargo, WebFaultException se puede usar con puntos finales que no son REST y se comporta como una FaultException normal.

Cuando se utiliza un punto final de WCF REST, el formato de respuesta del error serializado se determina de la misma manera que una respuesta sin error. Para obtener más información sobre el formato de REST de WCF, consulte Formato de REST de WCF.

Por lo tanto, sugeriría que necesito convertir mi método actual de Proveer Fault para proporcionar una nueva excepción WebHttpException (ajustando cualquier excepción existente o FaultExceptions) y luego SOAP también funcionará.

¿A alguien le gustaría probar cómo se vería (.Net4.0 por cierto)? ¡Quiero un controlador de errores para gobernarlos a todos!


Tenía la impresión de que usar webHttpBinding era una forma de obtener la funcionalidad "todo en uno" de JSON / POX / SOAP en lugar de usar enlaces separados para cada uno (es decir, basicHttpBinding , basicHttpBinding , etc.). Entonces, ¿no podría simplemente lanzar la WebHttpException y luego darles todos los detalles de error que necesitaba, independientemente de la tecnología?