Getting debug output from WCF 4 REST Template - wcf

I'm trying to see the exception that's being thrown in my WCF service but all I get from the response is:
"The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs."
Since I'm doing it the "REST" way, I don't have these options in my web.config. So, how can I enable "IncludeExceptionDetailInFaults" when using the WCF 4 REST Template?

Here's what I came up with:
Under the standardEndpoint in your web.config, turn on faultExceptionEnabled
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" faultExceptionEnabled="true">
Then, for custom messages to show, the thrown exceptions must be a FaultException. Here's an example of one that I use:
if (!Enum.GetNames(typeof(Models.Games.GsfCurrencyPrice.Sections)).Contains(section)) throw new FaultException<ArgumentException>(new ArgumentException("Value must be one of the following: " + string.Join(", ", Enum.GetNames(typeof(Models.Games.GsfCurrencyPrice.Sections))), "section"));
which produces the following response when thrown:
<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none"><Code><Value>Sender</Value></Code><Reason><Text xml:lang="en-US">The creator of this fault did not specify a Reason.</Text></Reason><Detail><ArgumentException xmlns="http://schemas.datacontract.org/2004/07/System" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema"><ClassName i:type="x:string" xmlns="">System.ArgumentException</ClassName><Message i:type="x:string" xmlns="">Value must be one of the following: Buy, Sell</Message><Data i:nil="true" xmlns=""/><InnerException i:nil="true" xmlns=""/><HelpURL i:nil="true" xmlns=""/><StackTraceString i:nil="true" xmlns=""/><RemoteStackTraceString i:nil="true" xmlns=""/><RemoteStackIndex i:type="x:int" xmlns="">0</RemoteStackIndex><ExceptionMethod i:nil="true" xmlns=""/><HResult i:type="x:int" xmlns="">-2147024809</HResult><Source i:nil="true" xmlns=""/><WatsonBuckets i:nil="true" xmlns=""/><ParamName i:type="x:string" xmlns="">section</ParamName></ArgumentException></Detail></Fault>
Hope this helps.

Related

Error handling in spring integration

I have three different systems. I am using Spring integration to sync data in all these system.
System 1 calls --- > System 2 via http:inbound gateway
<int-http:inbound-gateway id="gateway"
path="/save" supported-methods="POST, PUT"
request-channel="requestChannel" reply-channel="replyChannel"
request-payload-type="com.model.Request"
mapped-request-headers="source" error-channel="errorChannel" />
System 2 will call service method to persist data which returns response if request is valid else throws exception
<int:service-activator ref="serviceMethod"
method="saveIfValid" input-channel="requestChannel"
output-channel="serviceOutput" />
<int:recipient-list-router id="id1"
input-channel="serviceOutput">
<int:recipient channel="system1" />
<int:recipient channel="system3" />
</int:recipient-list-router>
I need to send service method response to system 1 and system 3 only if operation is successful.
After calling service method, based on service method response, request for system 3 will be generated using transformer. After transformer I am putting request in mq queue.
<int:transformer id="transformer1"
method="convert" input-channel="system3"
output-channel="jmsInput">
<bean
class="com.transformer.System3Transformer" />
</int:transformer>
<int-jms:outbound-channel-adapter id="adapter"
channel="jmsInput" destination-name="queueName">
</int-jms:outbound-channel-adapter>
Updated JMS outbound code
<int-jms:outbound-channel-adapter id="jms1"
channel="jmsIn" destination-name="queueName">
<int-jms:request-handler-advice-chain>
<bean
class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
<property name="onSuccessExpression" value="T(Boolean).TRUE" />
<property name="successChannelName" value="afterSuccessDeleteChannel" />
<property name="onFailureExpression" value="T(Boolean).FALSE" />
<property name="failureChannelName" value="afterFailRenameChannel" />
</bean>
</int-jms:request-handler-advice-chain>
</int-jms:outbound-channel-adapter>
My question is
if service class fails I need to send error response and stop the flow
if service method successful persisted data, but transformation fails, system 1 should get success response and error should be logged.
Here as I am using error channel in outbound adapter, even if error occurs in transformer it is returned to system 1.
please suggest how can i handle error without using global error channel and how to handle error in jms outbound adapter.
thank you for answering my quesion
For the first case you should really just rely on the exception propagation - the flow stops and error is sent to the system1 as an HTTP response.
For the second (transformer) case you should take a look into the ExpressionEvaluatingRequestHandlerAdvice and use it with the <request-handler-advice-chain> for the <transformer>.
The same can be applied for the <int-jms:outbound-channel-adapter>, if you should acknowledge to the system1.
http://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html#expression-advice
https://github.com/spring-projects/spring-integration-samples/tree/master/intermediate/retry-and-more

Adress Mismatch at the end point dispatcher

I have a WCF service which using the Web-Http Adapter through BizTalk. When I am trying to call the wcf service. I am getting the error below.
<?xml version="1.0"?>
-<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
-<Code>
<Value>Sender</Value>
-<Subcode>
<Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">
a:DestinationUnreachable
</Value>
</Subcode>
</Code>
-<Reason>
<Text xml:lang="en-US">The message with To 'https://biztalkt01.abc.org/ELIMS/ELIMS-CGA1/Service1.svc/?specimenid=abc001234'' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.</Text>
</Reason>
</Fault>
When I google for this error I can see this code needed to be added in to the service code
[ ServiceBehavior(AddressFilterMode=AddressFilterMode.Any)]
But not sure where is the service code for this service.
The above folder is wat I am seeing with respect to the service created in C:\inetpub\wwwroot\ELIMS\ELIMS-CGA1. Does the code needs to added in to any of these files or the files in the App_Data.
You need to configure your port settings properly for the adapter. This is not related to the WCF configuration files, but to the receive location settings in BizTalk itself. You have to set up the Address and the BtsHttpUrlMapping elements; see https://msdn.microsoft.com/en-us/library/jj572859.aspx for more information on these particular elements.

wso2 : ESB faultsequence

how to use faultsequence of proxy in esb
i want to use faultsequence when occur a fault in EndPoint. for example i stop service1 using jconsole and want to route message to service2 when call proxy service. but when i call proxy using soapui it show fault this message : The system is attempting to access an inactive service..
<target>
<inSequence >
<send>
<endpoint name="cal" >
<address uri="http://localhost:9763/services/service1/"/>
</endpoint>
</send>
</inSequence>
<faultSequence>
<log level="custom">
<property name="text" value="An unexpected error occured for service"/>
<property name="message" expression="get-property('ERROR_MESSAGE')"/>
</log>
<send>
<endpoint>
<address uri="http://localhost:9763/services/service2/"/>
</endpoint>
</send>
</faultSequence>
please guide me!
When your endpoint 1 is inactive it returns a soap fault and you want it to go to the fault sequence. But at the moment that fault sequence is considered as a response and it is sent to the client (soap ui).
In WSO2 ESB 4.5.0 onwards, there is a new property FORCE_ERROR_ON_SOAP_FAULT added. By setting this property, soap faults will be directed to fault sequence. You can do your next logics when you are in the fault sequence (for example invoking another sequence).
Refer [1] for a sample proxy service.
[1] http://maharachchi.blogspot.com/2012/09/now-you-can-send-soapfaults-to-fault.html
I believe your exact scenario is apart of your main end point if it faild you need to route the message to secondary endpoint.
Correct approach to your implementation is not using the fault sequence right approach is using fail over endpoint. You can find reference document at [1][2].
For sample you can refer "Sample 53: Failover sending among 3 endpoints" [3].
[1].http://wso2.org/project/esb/java/3.0.1/docs/endpoint_guide.html#FoEp
[2].http://docs.wso2.org/wiki/display/ESB403/Failover+Endpoint
[3].http://wso2.org/project/esb/java/3.0.1/docs/samples/endpoint_mediation_samples.html
Thank You,
Dharshana.

Error accesing published WS proxy in WSO2 ESB 4.6: EPR not found

I deployed exactly the same WS-proxy in 4.5.1 and 4.6. With 4.5.1 it works correctly, but with 4.6 I get:
ERROR - AxisEngine The endpoint reference (EPR) for the Operation not found is /services/registro.registroHttpSoap11Endpoint and the WSA Action = . If this EPR was previously reachable, please contact the server administrator.
The source is the following:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="registro" transports="http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<outSequence>
<send/>
</outSequence>
<endpoint>
<address uri="http://localhost:15080/SIGEM_RegistroPresencialWS/services/ServicioRegistroWebService"/>
</endpoint>
</target>
<publishWSDL uri="http://localhost:15080/SIGEM_RegistroPresencialWS/services/ServicioRegistroWebService?wsdl"/>
<description></description>
</proxy>
What do I have to do for 4.6. to make it work?
Thanx.
To enhance ESB performance pass-through transport has been enabled by default starting from ESB 4.6.0 version that is not the case for ESB 4.5.1. It seems your proxy service depends on SOAP body based dispatching but pass-through transport does not support for SOAP body based dispatching. SOAP body based dispatching build the message body and use first element's local name for dispatching which effect to proxy performance badly that is the reason it was not supported in pass-through transport. We are in a process to fix this limitation for future ESB releasees without loosing any advantage of pass-through transport.
BTW for the moment you can use one of the following workarounds.
When sending a messages to the proxy service append operation name to the endpoint URL
e.g - http://serverName/app/serviceName/operationName
Modify client level code to send expected SOAPAction value ( like Try-It case)
I'm not sure your backend service's WSDL defined "" as the value of SOAPAction if that is the case you may modified the backend service to have value other than "" per each operation. AS an example for JAX-WS services you can use #WebMethod annotation for this.
e.g - #WebMethod(action="XXXX")
Note : In case if your backend WSDL defining a value other than "" for SOAPAction while your client send message with SOAPAction="" then it's a violation of service contract by the client and need to be fixed on client level.
I have faced the same problem with wso2 ESB 4.7 and the web service is also developed by me for the company.
What worked for me is adding soapAction attribute to wsdl soap:operation element like below.
<soap:operation soapAction="http://localhost:8080/MyWebApp/services/hello" style="document"/>

WCF content type mismatch

Have just deployed a WCF project to IIS.
However when I try to add the service reference to a test project, Visual Studio gives the following:
The document was understood, but it could not be processed.
- The WSDL document contains links that could not be resolved.
- There was an error downloading 'http://server1.local/WCFServices/serv1/serv1.svc?xsd=xsd0'.
- The underlying connection was closed: An unexpected error occurred on a receive.
- Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
- An existing connection was forcibly closed by the remote host
Metadata contains a reference that cannot be resolved: 'http://server1.local/WCFServices/serv1/serv1.svc?wsdl'.
Content Type application/soap+xml; charset=utf-8 was not supported by service http://server1.local/WCFServices/serv1/serv1.svc?wsdl. The client and service bindings may be mismatched.
The remote server returned an error: (415) Cannot process the message because the content type 'application/soap+xml; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'..
If the service is defined in the current solution, try building the solution and adding the service reference again.
So there's a problem, which I sorta get. The content type of the service is mismatched from what the client is expecting.
So, how do I fix it?
Check the App.Config or Web.Config of your client and check the ServiceModel. Most probably there is a customBinding which is different from what the WCF service is sending.
As this is the first post google shows up for this error, I want to participate with my solution:
I got a similar error while changing code in a system that was working well, but updating the reference on my development system failed. The reference is located inside a silverlight project and is related to a WCF integrated in the surrounding website (standard confiduration I guess). My error message included "WCF Metadata contains a reference that cannot be resolved: 'Some funny path'. The content type text/html; charset=utf-8 of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8)." My website uses authorization roles, thats where the problem/solution was based. For updating the service reference I had to allow all users:
<?xml version="1.0"?>
<configuration>
<system.web>
<!--<authorization>
<allow users="*"/>
</authorization>-->
<authorization>
<deny users="?"/>
<allow roles="role-1,role-2"/>
<deny users="*"/>
</authorization>
</system.web>
</configuration>