I'm trying to connect a C# app to a PeopleSoft WSDL web service. I've been through the standard processes of adding the service reference, and fought some battles to get the Username/Password included in the request. That's all working, but when the response comes back, I end up with a exception trying to parse the response:
System.ServiceModel.Security.MessageSecurityException: Security processor was unable to find a security header in the message. This might be because the message is an unsecured fault or because there is a binding mismatch between the communicating parties. This can occur if the service is configured for security and the client is not using security.
Server stack trace: at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessageCore(Message& message, TimeSpan timeout) at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout) at System.ServiceModel.Security.SecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates) at System.ServiceModel.Channels.SecurityChannelFactory1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelFactory1.SecurityRequestChannel.Request(Message message, TimeSpan timeout) at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at WSDLTesting.PeopleSoft.QAS_QRY_SERVICE_PortType.QAS_EXECUTEQRYSYNC_OPER(QAS_EXEQRY_SYNC_REQ_MSGVERSION_1 request) at WSDLTesting.PeopleSoft.QAS_QRY_SERVICE_PortTypeClient.WSDLTesting.PeopleSoft.QAS_QRY_SERVICE_PortType.QAS_EXECUTEQRYSYNC_OPER(QAS_EXEQRY_SYNC_REQ_MSGVERSION_1 request) in c:\Projects\WSDLTesting\WSDLTesting\Service References\PeopleSoft\Reference.cs:line 5867 at WSDLTesting.PeopleSoft.QAS_QRY_SERVICE_PortTypeClient.QAS_EXECUTEQRYSYNC_OPER(QAS_EXEQRY_SYNC_REQ_MSGType QAS_EXEQRY_SYNC_REQ_MSG) in c:\Projects\WSDLTesting\WSDLTesting\Service References\PeopleSoft\Reference.cs:line 5873 at WSDLTesting.Program.Main(String[] args) in c:\Projects\WSDLTesting\WSDLTesting\Program.cs:line 44
My app.config currently looks like this:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="QAS_QRY_SERVICE_Binding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://service.url/PSIGW/PeopleSoftServiceListeningConnector/PSFT_FS91DEV2" binding="basicHttpBinding" bindingConfiguration="QAS_QRY_SERVICE_Binding" contract="PeopleSoft.QAS_QRY_SERVICE_PortType" name="QAS_QRY_SERVICE_Port" />
</client>
</system.serviceModel>
and my application is current run like this:
var connection = new PeopleSoft.QAS_QRY_SERVICE_PortTypeClient();
connection.ClientCredentials.UserName.UserName = "XXXXXX";
connection.ClientCredentials.UserName.Password = "YYYYYY";
var param = new PeopleSoft.QAS_EXEQRY_SYNC_REQ_MSGType();
param.QAS_EXEQRY_SYNC_REQ = new PeopleSoft.QAS_EXEQRY_SYNC_REQ_TypeShape();
param.QAS_EXEQRY_SYNC_REQ.QueryName = "SOIAP_OBJECT_STATUS";
param.QAS_EXEQRY_SYNC_REQ.isConnectedQuery = PeopleSoft.isConnectedQuery_TypeDef1.N;
param.QAS_EXEQRY_SYNC_REQ.OwnerType = "PUBLIC";
param.QAS_EXEQRY_SYNC_REQ.BlockSizeKB = "0";
param.QAS_EXEQRY_SYNC_REQ.MaxRow = "9999";
param.QAS_EXEQRY_SYNC_REQ.OutResultType = PeopleSoft.OutResultType_TypeDef1.WEBROWSET;
param.QAS_EXEQRY_SYNC_REQ.OutResultFormat = PeopleSoft.OutResultFormat_TypeDef1.NONFILE;
param.QAS_EXEQRY_SYNC_REQ.Prompts = new PeopleSoft.Prompts_TypeDefPROMPT1[] {
new PeopleSoft.Prompts_TypeDefPROMPT1() { FieldValue = "Data1", UniquePromptName = "BIND1" } ,
new PeopleSoft.Prompts_TypeDefPROMPT1() { FieldValue = "Data2", UniquePromptName = "BIND2" } ,
new PeopleSoft.Prompts_TypeDefPROMPT1() { FieldValue = "Data3", UniquePromptName = "BIND3" } ,
};
try {
var results = connection.QAS_EXECUTEQRYSYNC_OPER( param );
Console.WriteLine( results.QAS_QUERYRESULTS_STATUS_RESP.status );
} catch( FaultException e ) {
DisplayFault( e );
} catch( Exception e ) {
if( e.InnerException != null && e.InnerException is FaultException ) {
DisplayFault( e.InnerException as FaultException );
} else {
Console.WriteLine( e.ToString() );
}
}
Console.WriteLine( "Done" );
Console.ReadLine();
Any ideas?
The configuration for the binding was defaulted to mode="Transport" without the message tag, but that yielded other issues. I also tried basicHttpsBinding and wsHttpBinding, but that didn't work. Could be something I did wrong, but most of the settings were the same and I get the same error message back. I've turned on tracing to get the packet information, and the response is coming back properly. I've also taken the same SOAP message and used SOAPUI and it works properly, so I assume the problem is somewhere in my C# configuration, not the SOAP itself.
Is there some other setting I should try? Because I'm an outside contractor trying to integrate with a client PeopleSoft system, I have limited access to the settings of the connection itself, but if there is some information that I can gather and/or thing to try, I'm more than happy to pass them on if it looks like it may help.
Thanks, Matt