Reputation: 6467
I am writing a WCF service that should handle a predefined SOAP/XML format that I have no control over.
Here is my exposed service contract:
[OperationContract]
[WebInvoke(Method = "POST")]
bool SavePets(Pets Pets);
The SOAP that this service expects is:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<SavePets xmlns="http://tempuri.org">
<Pets>
<Dog>
<Name>Fido</Name>
</Dog>
<Dog>
<Name>Duke</Name>
</Dog>
<Cat>
<Name>Max</Name>
</Cat>
</Pets>
</SavePets>
</s:Body>
</s:Envelope>
However, I need for either the method name (SavePets) or the parameter name (Pets) to be removed, as such, so the service does not expect it:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<Pets>
<Dog>
<Name>Fido</Name>
</Dog>
<Dog>
<Name>Duke</Name>
</Dog>
<Cat>
<Name>Max</Name>
</Cat>
</Pets>
</s:Body>
</s:Envelope>
I'm not using DataContracts or MessageContracts. My Pets class looks like this:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.233")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false, Namespace = "http://tempuri.org")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org", IsNullable = true)]
public partial class Pets
{...
}
Upvotes: 3
Views: 3523
Reputation: 87293
To remove one of those elements, you can use an unwrapped message contract (a type decorated with [MessageContract(IsWrapped = false)]
). The code below shows one service which could receive that request.
public class StackOverflow_12733486
{
[ServiceContract(Namespace = "")]
[XmlSerializerFormat]
public interface ITest
{
[OperationContract]
SavePetsResponse SavePets(SavePetsRequest request);
}
public class Service : ITest
{
public SavePetsResponse SavePets(SavePetsRequest request)
{
return new SavePetsResponse { Result = true };
}
}
[MessageContract(IsWrapped = false)]
public class SavePetsRequest
{
[MessageBodyMember]
public Pets Pets { get; set; }
}
[MessageContract(WrapperNamespace = "")]
public class SavePetsResponse
{
[MessageBodyMember]
public bool Result { get; set; }
}
public class Pets
{
[XmlElement(ElementName = "Dog")]
public string[] Dogs;
[XmlElement(ElementName = "Cat")]
public string[] Cats;
}
static Binding GetBinding()
{
var result = new BasicHttpBinding();
return result;
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(ITest), GetBinding(), "");
host.Open();
Console.WriteLine("Host opened");
ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(), new EndpointAddress(baseAddress));
ITest proxy = factory.CreateChannel();
Pets pets = new Pets { Cats = new string[] { "Max" }, Dogs = new string[] { "Fido", "Duke" } };
proxy.SavePets(new SavePetsRequest { Pets = pets });
((IClientChannel)proxy).Close();
factory.Close();
WebClient c = new WebClient();
c.Headers[HttpRequestHeader.ContentType] = "text/xml";
c.Headers["SOAPAction"] = "urn:ITest/SavePets";
string reqBody = @"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
<s:Body>
<Pets>
<Dog>Fido</Dog>
<Dog>Duke</Dog>
<Cat>Max</Cat>
</Pets>
</s:Body>
</s:Envelope>";
Console.WriteLine(c.UploadString(baseAddress, reqBody));
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
Upvotes: 4