We have a WCF service with defined class (class was autogenerated from XML using http://xmltocsharp.azurewebsites.net/ ):
namespace CRMtoQLM.DAL
{
[Serializable]
[DataContract(Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
[DataMember]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "soapenv", Namespace = "http://www.w3.org/2000/xmlns/")]
[DataMember]
public string Soapenv { get; set; }
[XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
[DataMember]
public string Xsd { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
[DataMember]
public string Xsi { get; set; }
}
//[Serializable]
[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
[DataContract(Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
[XmlElement(ElementName = "notifications", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataMember]
public Notifications Notifications { get; set; }
}
//[Serializable]
[XmlRoot(ElementName = "notifications", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataContract(Namespace = "http://soap.sforce.com/2005/09/outbound")]
public class Notifications
{
[XmlElement(ElementName = "OrganizationId", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataMember]
public string OrganizationId { get; set; }
[XmlElement(ElementName = "ActionId", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataMember]
public string ActionId { get; set; }
[XmlElement(ElementName = "SessionId", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataMember]
public string SessionId { get; set; }
[XmlElement(ElementName = "EnterpriseUrl", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataMember]
public string EnterpriseUrl { get; set; }
[XmlElement(ElementName = "PartnerUrl", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataMember]
public string PartnerUrl { get; set; }
[XmlElement(ElementName = "Notification", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataMember]
public Notification Notification { get; set; }
[XmlAttribute(AttributeName = "xmlns")]
[DataMember]
public string Xmlns { get; set; }
}
//[Serializable]
[XmlRoot(ElementName = "Notification", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataContract(Namespace = "http://soap.sforce.com/2005/09/outbound")]
public class Notification
{
[XmlElement(ElementName = "Id", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataMember]
public string Id { get; set; }
[XmlElement(ElementName = "sObject", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataMember]
public SObject SObject { get; set; }
}
//[Serializable]
[XmlRoot(ElementName = "sObject", Namespace = "http://soap.sforce.com/2005/09/outbound")]
[DataContract(Namespace = "http://soap.sforce.com/2005/09/outbound")]
public class SObject
{
[XmlElement(ElementName = "Id", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
[DataMember]
public string Id { get; set; }
[XmlElement(ElementName = "Asset_Account_City__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
[DataMember]
public string Asset_Account_City__c { get; set; }
[XmlElement(ElementName = "Asset_Account_Country__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
[DataMember]
public string Asset_Account_Country__c { get; set; }
[XmlElement(ElementName = "Asset_Account_Name__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
[DataMember]
public string Asset_Account_Name__c { get; set; }
[XmlElement(ElementName = "Asset_Customer_ID__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
[DataMember]
public string Asset_Customer_ID__c { get; set; }
[XmlElement(ElementName = "Expiration_Date__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
[DataMember]
public string Expiration_Date__c { get; set; }
[XmlElement(ElementName = "License__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
[DataMember]
public string License__c { get; set; }
[XmlElement(ElementName = "Reader_Code__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
[DataMember]
public string Reader_Code__c { get; set; }
[XmlElement(ElementName = "Reader_Quantity__c", Namespace = "urn:sobject.enterprise.soap.sforce.com")]
[DataMember]
public string Reader_Quantity__c { get; set; }
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
[DataMember]
public string Type { get; set; }
[XmlAttribute(AttributeName = "sf", Namespace = "http://www.w3.org/2000/xmlns/")]
[DataMember]
public string Sf { get; set; }
}
}
IService.cs defined like this:
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "Test",
RequestFormat = WebMessageFormat.Xml)]
//[XmlSerializerFormat]
string Test(Envelope parameter);
and implementation:
public string Test(Envelope parameter)
{
return "";
}
but "parameter" in Test function contains NULL objects. I know there is a problem with XML deserialization but can't figure out where exactly.
EDIT: this is the request that I'm sending via Postman
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<notifications xmlns="http://soap.sforce.com/2005/09/outbound">
<OrganizationId>123456</OrganizationId>
<ActionId>123456</ActionId>
<SessionId>123456</SessionId>
<EnterpriseUrl>https://eu8.salesforce.com/</EnterpriseUrl>
<PartnerUrl>https://eu8.salesforce.com/</PartnerUrl>
<Notification>
<Id>123456</Id>
<sObject xsi:type="sf:Asset" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
<sf:Id>123456</sf:Id>
<sf:Asset_Account_City__c>123456</sf:Asset_Account_City__c>
<sf:Asset_Account_Country__c>123456</sf:Asset_Account_Country__c>
<sf:Asset_Account_Name__c>123456</sf:Asset_Account_Name__c>
<sf:Asset_Customer_ID__c>123456</sf:Asset_Customer_ID__c>
<sf:Expiration_Date__c>123456</sf:Expiration_Date__c>
<sf:License__c>123456</sf:License__c>
<sf:Reader_Code__c>123456</sf:Reader_Code__c>
<sf:Reader_Quantity__c>123456</sf:Reader_Quantity__c>
</sObject>
</Notification>
</notifications>
</soapenv:Body>
</soapenv:Envelope>
SOAP-based bindings unpack the SOAP envelope for you, so you shouldn't need to define the SOAP envelope types. The WebHttpBinding which you say you're using, which doesn't know anything about SOAP, would expect that the contract type (the argument of your service method IService.Test
) would match the entire HTTP body, so I see the logic of what you're doing, however I don't think it's necessary to work against the framework like this.
To fix this scenario do a couple of things:
Notifications
string Test(Notifications notifications)
<endpoint address="/relativeaddress/" binding="basicHttpBinding" ... />
WebInvokeAttribute
, but to be on the safe side, remove it. It's superfluous for a SOAP binding because SOAP is always POST. I don't think you need to delete the Envelope
and Body
types but they won't do anything if they're not referenced, which is what you want. WCF bindings understand the SOAP envelope natively and don't need it to be specified, it's the content of the SOAP Body element that types need to be provided for.
Your XML sample contains a single instance of Notification
under Notifications
but the name implies that this child element could be repeating - if it is, I don't think the generated classes will work for you because the Notifications
class has a singular Notification
property - the generator you linked to has no way to know this so I don't fault it in any way. I added a copy of the Notification
element as a sibling and ran it through again - this time it generated a list member:
[XmlElement(ElementName="Notification", Namespace="http://soap.sforce.com/2005/09/outbound")]
public List<Notification> Notification { get; set; }
You can use the xsd.exe
tool supplied with Visual Studio (I think) to generate classes - see the documentation . I wouldn't be surprised if that web tool is driving this behind the scenes but I'd trust xsd.exe
to generate classes that have the best possible compliance with what WCF expects of them.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.