I created a C # webservice through a WSDL from another webservice made in PHP. All calls work but the parameters sent in xml always arrive null.
This is my code:
[WebService(Namespace = "urn:PGSMS")]
[GeneratedCode("System.Xml", "2.0.50727.3082")]
[System.Xml.Serialization.SoapType(Namespace = "urn:PGSMS")]
[SoapDocumentService(RoutingStyle = SoapServiceRoutingStyle.RequestElement)]
[System.Web.Script.Services.ScriptService]
public class PGSMS : System.Web.Services.WebService, PGSMSPortType
{
[WebMethod]
[OperationContract(Action = "urn:PGSMS#PGSMS")]
public string envioAvulso(string token, string carteira, string msg, string fones, string data, string retorno, string dadocliente)
{
IntegraBellinati.envioAvulsoRequest envio = new IntegraBellinati.envioAvulsoRequest();
envio.token = token;
envio.msg = msg;
envio.fones = fones;
envio.carteira = carteira;
envio.data = data;
envio.dadocliente = dadocliente;
envio.retorno = retorno;
IntegraBellinati.IntegraBellinati integra = new IntegraBellinati.IntegraBellinati();
return integra.envioAvulso(envio);
}
}
[System.ServiceModel.ServiceContract(Namespace = "urn:PGSMS", ConfigurationName = "PGSMSPortType")]
public interface PGSMSPortType
{
string envioAvulso(string token, string carteira, string msg, string fones, string data, string retorno, string dadocliente);
}
The method sendsAvulso executes normally, but all methods arrive null.
This is the xml that my client is trying to post:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:PGSMS" xmlns:types="urn:PGSMS/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<tns:envioAvulso>
<token xsi:type="xsd:string">xxxxxxxxxxxxxxxx</token>
<carteira xsi:type="xsd:string">12</carteira>
<msg xsi:type="xsd:string">Teste de msg</msg>
<fones xsi:type="xsd:string">41988326802</fones>
<data xsi:type="xsd:string">2017-10-09 00:00:00</data>
<retorno xsi:type="xsd:string">12</retorno>
<dadocliente xsi:type="xsd:string">12</dadocliente>
</tns:envioAvulso>
</soap:Body>
</soap:Envelope>
Using SoapUI I was able to make the post and received the correct parameters, it generated this xml.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:PGSMS">
<soapenv:Header/>
<soapenv:Body>
<urn:envioAvulso>
<urn:token>?</urn:token>
<urn:carteira>?</urn:carteira>
<urn:msg>?</urn:msg>
<urn:fones>?</urn:fones>
<urn:data>?</urn:data>
<urn:retorno>?</urn:retorno>
<urn:dadocliente>?</urn:dadocliente>
</urn:envioAvulso>
</soapenv:Body>
</soapenv:Envelope>
But my client can not change his xml. What can I be doing wrong?
Thank's
Related
I try to access to my webmethods with SOAP UI but it works only for the first one and I don't undestand why.
My Webservices methods :
[SoapHeader ("AuthenticationInfo", Required=true)]
[WebMethod(EnableSession = true)]
public string HelloWorld()
{
if (!(AuthenticationInfo.Username == "test" && AuthenticationInfo.Password == "test"))
{
throw new Exception();
// I put that in the aim to get an error, I'll modify this later
}
return "OK";
}
[SoapHeader("AuthenticationInfo", Required = true)]
[WebMethod]
public string Authenticate(string MethodName)
{
if (!(AuthenticationInfo.Username == "test" && AuthenticationInfo.Password == "test")
{
throw new Exception();
}
else
{
HelloWorld();
}
return "aaaa";
}
[WebMethod]
public int Calcul(int a, int b)
{
return a+b ;
}
When I put this XML in SOAP UI :
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<AuthHeader xmlns="http://tempuri.org/">
<Username>test</Username>
<Password>test</Password>
<key>string</key>
</AuthHeader>
</soap:Header>
<soap:Body>
<HelloWorld xmlns="http://tempuri.org/" />
</soap:Body>
</soap:Envelope
It works perfectly, I get the return of HelloWord() Method.
But if I put :
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Calcul xmlns="http://tempuri.org/">
<a>1</a>
<b>1</b>
</Calcul>
</soap:Body>
</soap:Envelope>
It invokes again HelloWorld() method. My URL which I use in SOAP UI is :"http://localhost:62353/MyWebService.asmx", so I try a new request with the last XML at the URL "http://localhost:62353/MyWebService.asmx/Calcul" and i have an error.
Have you I Idea ? May I'm in the wrong way to use SOAP UI ?
To reply to Kosala W :
I get an UI like that where I can click on the methods. The calcul methods works only here because this methos doesn't need the SoapHeader.
Here is the response :
When you specify the URL in SOAP UI you need to add ?wsdl at the end like that : http://localhost:62353/MyWebService.asmx?wsdl Then I refresh the project in SOAP UI and all the methods appears
I'm adding a property to my model with an enum.
public class ChildCareCentreEntryReservation : BasketItem, ILockableBasketItem
{
....
[DataMember]
public ChildCareCentreEntryReservationStatusTypes ChildCareCentreEntryReservationStatusType { get; set; }
}
[DataContract(Namespace = Constants.Namespace)]
public enum ChildCareCentreEntryReservationStatusTypes
{
[EnumMember]
VoorlopigIngeschreven = 0,
[EnumMember]
DefinitiefIngeschreven = 1,
[EnumMember]
Geannuleerd = 2
}
In my form I Create a ChildCareCentreEntryReservation object:
var reservation = new ChildCareCentreEntryReservation();
reservation.ChildCareEntryPeriodId = _entryPeriod.Id;
reservation.ChildCareCentreId = _centre.Id;
reservation.PersonId = _person.Id;
reservation.Comment = txtComment.Text;
reservation.ChildCareCentreEntryReservationStatusType = (ChildCareCentreEntryReservationStatusTypes)cboStatusName.SelectedIndex;
I add the ChildCareCentreEntryReservation object to a list:
var basketItems = new List<BasketItem> { reservation };
Then I send an array to the service by calling the function LockBasketItems:
LockBasketResult lockBasketResult = Service.LockBasketItems(basketItems.ToArray(), Context);
Everything builds and works correctly but my service doesn't receive my last added property.
Fiddler inspectors result (client request to service):
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<BasketItems xmlns="http://www./">
<BasketItem xsi:type="ChildCareCentreEntryReservation">
<RuleNamesToIgnore xsi:nil="true"/>
<ChildCareEntryPeriodId>13ccefb3-f1e4-4f64-8fb8-b07cf30d2fca</ChildCareEntryPeriodId>
<ChildCareCentreId>8cc85f37-da5d-46c5-9bb4-d6efa8448176</ChildCareCentreId>
<PersonId>56e341bb-ac05-40dc-a39a-082ae4ff087e</PersonId>
<ChildCareCentrePeriodIds>
<guid xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">61c43967-8781-4d83-a117-963c5734491f</guid>
</ChildCareCentrePeriodIds>
<LockTicket xsi:nil="true"/>
<Comment/>
<PeriodOptions xsi:nil="true"/>
</BasketItem>
</BasketItems>
<Context xmlns="http://www./">
<Language>NL</Language>
<ShopId>00000000-0000-0000-0000-000000000550</ShopId>
<SessionId>de824345-14f3-44c7-99fd-f9a073e9b51b</SessionId>
</Context>
Fiddler inspectors result (service response to client):
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<ActivityId CorrelationId="d1daee11-20e2-4e98-8774-9bffe4e2e4f3" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">728e68a9-17ff-44a0-b4ad-f455f403be5e</ActivityId>
</s:Header>
<s:Body>
<LockBasketResult xmlns="http://www./" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<BasketItems>
<BasketItem i:type="ChildCareCentreEntryReservation">
<DivisionId>00000000-0000-0000-0000-000000000000</DivisionId>
<Id>00000000-0000-0000-0000-000000000000</Id>
<Quantity>1</Quantity>
<RuleNamesToIgnore xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
<UnitPrice>0</UnitPrice>
<ChildCareEntryPeriodId>13ccefb3-f1e4-4f64-8fb8-b07cf30d2fca</ChildCareEntryPeriodId>
<ChildCareCentreId>8cc85f37-da5d-46c5-9bb4-d6efa8448176</ChildCareCentreId>
<PersonId>56e341bb-ac05-40dc-a39a-082ae4ff087e</PersonId>
<ChildCareCentrePeriodIds xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<a:guid>61c43967-8781-4d83-a117-963c5734491f</a:guid>
</ChildCareCentrePeriodIds>
<LockTicket i:type="ChildCareCentreEntryReservationLockTicket">
<ExpirationTime>2013-10-08T17:27:06</ExpirationTime>
<Id>13a984f8-5d97-4f87-aa52-7523849cc6f5</Id>
</LockTicket>
<Comment/>
<PeriodOptions xmlns:a="http://schemas.datacontract.org/"/>
<ChildCareCentreEntryReservationStatusType>VoorlopigIngeschreven</ChildCareCentreEntryReservationStatusType>
</BasketItem>
</BasketItems>
<IsLocked>true</IsLocked>
<ValidationResult i:nil="true"/>
</LockBasketResult>
In my Reference.cs i'm seeing the property is correctly added.
Any idea what i am missing?
I'm using ASP.NET
Solution
I had to set ChildCareCentreEntryReservationStatusTypeSpecified to true
reservation.ChildCareCentreEntryReservationStatusTypeSpecified = true;
Solved
I had to set ChildCareCentreEntryReservationStatusTypeSpecified to true
reservation.ChildCareCentreEntryReservationStatusTypeSpecified = true;
So I'm trying to call a webservice with PHP and SOAP, but it doesn't seem to be doing it correctly and I can't figure out why. Here is the PHP:
$client = new SoapClient($wsdl, array('trace' => 1));
print_r($client->__getFunctions());
$params->param1 = "satsys";
$params->param2 = "0A259772-983C-4EFB-834E-6184F8E9F4E7";
$params->param3 = null;
$response = $client->SetHardwareProfile($params);
var_dump($response);
echo "Last Request: ".$client->__getLastRequest();
echo "Last Response: ".$client->__getLastResponse();
And here is the Output:
Array
(
[0] => ValidateLicenseKeyResponse ValidateLicenseKey(ValidateLicenseKey $parameters)
[1] => CreateProviderResponse CreateProvider(CreateProvider $parameters)
[2] => SetHardwareProfileResponse SetHardwareProfile(SetHardwareProfile $parameters)
[3] => UpdateCurrentVersionResponse UpdateCurrentVersion(UpdateCurrentVersion $parameters)
[4] => SoftwareUpdateAvailableResponse SoftwareUpdateAvailable(SoftwareUpdateAvailable $parameters)
[5] => GetSoftwareUpdateResponse GetSoftwareUpdate(GetSoftwareUpdate $parameters)
)
object(stdClass)#3 (1) {
["SetHardwareProfileResult"]=>
bool(false)
}
And the XML:
<?xml version="1.0" encoding="UTF-8"?>
<!--Last Request:-->
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
<SOAP-ENV:Body>
<ns1:SetHardwareProfile/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
<!--Last Response:-->
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<SetHardwareProfileResponse xmlns="http://tempuri.org/">
<SetHardwareProfileResult>false</SetHardwareProfileResult>
</SetHardwareProfileResponse>
</s:Body>
</s:Envelope>
Now from what I have read, it's that request that's a problem, because instead of looking like that, it should look like this:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
<SOAP-ENV:Body>
<ns1:SetHardwareProfile>
<customerId xsi:type="xsd:string">satsys</customerId>
<providerGuid xsi:type="xsd:string">0A259772-983C-4EFB-834E-6184F8E9F4E7</providerGuid>
<other xsi:type="xsd:string"></other>
</ns1:SetHardwareProfile>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Here is the service contract, for good measure (written in C#):
using System;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Collections.Generic;
namespace ProviderSync
{
[ServiceContract]
public interface IProviderSync
{
[OperationContract]
bool SetHardwareProfile(String customerId, String providerGuid, List<Device> hardware);
}
}
Okay, so the problem is that with SOAP, unlike with other languages, the parameters have to have their exact names. So the above chunk of PHP code should actually read like this:
$client = new SoapClient($wsdl, array('trace' => 1));
print_r($client->__getFunctions());
$params->customerId = "satsys";
$params->providerGuid = "0A259772-983C-4EFB-834E-6184F8E9F4E7";
$params->hardware = null;
$response = $client->SetHardwareProfile($params);
var_dump($response);
echo "Last Request: ".$client->__getLastRequest();
echo "Last Response: ".$client->__getLastResponse();
Because they're declared by the service contract as:
bool SetHardwareProfile(String customerId, String providerGuid, List<Device> hardware);
I am not sure why exactly this is the case, or if this is the case in all forms of SOAP calls, but that change fixed this problem for me.
Here is the XML response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="somehttp..">
<soap:Body>
<get4GAddressResponse xmlns="http://somelink/">
<get4GCAddressResult>
<located>true</located>
<matchStatus>S</matchStatus>
<errorCode>0</errorCode>
<message>Single Address Match</message>
<addressList>
<anyType xsi:type="Address">
<street>4301 some St</street>
<city>ABC</city>
<state>TX</state>
<zip>78751</zip>
<longitude>-97.700000</longitude>
<latitude>30.308000</latitude>
<coverageTypes>
<anyType xsi:type="NetworkCoverage">
<type>4G</type>
<isCovered>false</isCovered>
</anyType>
</coverageTypes>
</anyType>
</addressList>
</get4GAddressResult>
</get4GAddressResponse>
</soap:Body>
</soap:Envelope>"
I am trying to get the values from XML element: 'isCovered'
I am able to retrieve the values from
<located>true</located>
<matchStatus>S</matchStatus>
<errorCode>0</errorCode>
<message>Single Address Match</message>
But I need value for IsCovered.
C# code:
Location result = new TestWebService.Location();
result = get4GAddress(street, city, state, zip);
if (result != null)
{
if (result.errorCode.Equals("0"))
{
locationresult = new LocationResponse();
locationresult.located = result.located;
locationresult.addressList = result.addressList;
locationresult.matchStatus = result.matchStatus;
locationresult.message = result.message;
}
}
You can use the SoapFormatter to deserialize your response stream.
I've got a simple C# web service proxy class that I created with WSDL.exe. I am invoking a method on the remote web service, and it is including a bunch of WS-Addressing and WS-Security headers that I do not want (and that the server is choking on). Here is an example of the raw soap request:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsa:Action></wsa:Action>
<wsa:MessageID>urn:uuid:22f12267-b162-4703-a451-2d1c5c5a619b</wsa:MessageID>
<wsa:To>http://example.com/wstest</wsa:To>
<wsse:Security>
<wsu:Timestamp wsu:Id="Timestamp-5c9f0ef0-ab45-421d-a633-4c4fad26d945">
<wsu:Created>2009-04-15T16:27:25Z</wsu:Created>
<wsu:Expires>2009-04-15T16:32:25Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soap:Header>
<soap:Body>
<Func1 xmlns="http://example.com">
<arg_1 xmlns="">blah</arg_1>
<arg_2 xmlns="">blah2</arg_2></arg_2>
</Func1>
</soap:Body>
</soap:Envelope>
But I don't care about the WS-Addressing/WS-Security stuff. I've done nothing to include it. The .NET WSE 3.0 package seems to be adding them by default. Is there any way to get rid of these? I can see no properties on my proxy object that allow me to remove these sections. I've tried:
proxyObject.Addressing.Clear();
proxyObject.Security.Clear();
Those cause a null reference exception when I invoke my web service method.
I want the SOAP request to look like this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
</soap:Header>
<soap:Body>
<Func1 xmlns="http://example.com">
<arg_1 xmlns="">blah</arg_1>
<arg_2 xmlns="">blah2</arg_2></arg_2>
</Func1>
</soap:Body>
</soap:Envelope>
Thanks in advance
Well, I ended up using a technique I have used in the past. I created classes that implement SoapFilter and PolicyAssertion which allow me to modify the raw XML of the SOAP request before it is sent. Below is an example:
public class MyPolicy : SoapFilter
{
public override SoapFilterResult ProcessMessage(SoapEnvelope envelope)
{
// Remove all WS-Addressing and WS-Security header info
envelope.Header.RemoveAll();
return SoapFilterResult.Continue;
}
}
public class MyAssertion : PolicyAssertion
{
public override SoapFilter CreateClientInputFilter(FilterCreationContext context)
{
return null;
}
public override SoapFilter CreateClientOutputFilter(FilterCreationContext context)
{
return new MyPolicy();
}
public override SoapFilter CreateServiceInputFilter(FilterCreationContext context)
{
return null;
}
public override SoapFilter CreateServiceOutputFilter(FilterCreationContext context)
{
return null;
}
}
Then in your web service proxy's contructor you apply the policy:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.1433")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="MyBinding", Namespace="http://example.com")]
public partial class MyWebClient : WebServicesClientProtocol {
// ... member variables here
/// <remarks/>
public MyWebClient()
{
this.Url = "http://example.com";
if ((this.IsLocalFileSystemWebService(this.Url) == true)) {
this.UseDefaultCredentials = true;
this.useDefaultCredentialsSetExplicitly = false;
}
else {
this.useDefaultCredentialsSetExplicitly = true;
}
// Apply policy here
Policy policy = new Policy();
policy.Assertions.Add(new MyAssertion());
this.SetPolicy(policy);
}
}
to remove the addressing header i used the below code in one of my app.
public override void SecureMessage(SoapEnvelope envelope, Security security)
{
//remove addressing Header from envelope
AddressingHeaders objAH = new AddressingHeaders(envelope);
objAH.RemoveXml(envelope);
//Add Wahtever security token you want to add.
security.Tokens.Add(bla-bla-bla);
}
I used SecureMessage function because i wanted to add security tokens,but same code can be used in ProcessMessage function.
I wonder if your problem might not also have ben resolved by simply not using WSE?
Based on the answer in this page, I added the code below to remove specific header (by tagname) recursively from XML.
Public Overrides Function ProcessMessage(ByVal envelope As SoapEnvelope) As SoapFilterResult
' Remove all WS-Addressing and WS-Security header info
RemoveTag(envelope.DocumentElement, "wsa:Action")
RemoveTag(envelope.DocumentElement, "wsa:MessageID")
RemoveTag(envelope.DocumentElement, "wsa:To")
Return SoapFilterResult.[Continue]
End Function
Private Sub RemoveTag(ByVal XE As System.Xml.XmlElement, ByVal TagName As String)
For Each N As XmlNode In XE
If N.ChildNodes.Count > 0 Then
RemoveTag(N, TagName)
End If
If N.Name = TagName Then
XE.RemoveChild(N)
End If
Next
End Sub
I found the easiest way to remove these addressing and security headers was to change the web service configuration to use BasicHttpBinding instead of WSHttp binding.