Contributions
SoapUI Mock Service Dynamic Proxy
The business driver: Companies may not have message routing infrastructure and the mock proxy provides the poor-man’s alternative!Your company may have multiple non-production environments but the connectivity to 3rd party partners are limited to specific environments only. You can switch the environment internally without impacting connectivity to 3rd party. Service Mocking is easy- you get the wsdl and import into a SoapUi project and add a Mock Service! It takes little effort to turn the mock service as dynamic proxy and run it as service (unattended). Find the details at: http://www.aspnet4you.com/wcf/index.php/2013/03/22/soapui-mock-service-proxy/1.2KViews0likes0CommentsSerialization of Generic and Nullable (DateTime?, XElement)
You are done with coding and getting ready to test your services. Now you realized that some of your objects/properties are not serializable. Don't be discouraged, keep reading! I was working with XElement (a .Net type) as it would allow you to pass any xml. Well, everything was good until I ran the test on SoapUI. I was rewared with sometime like XElement is not marked as serializable when I was testing a .net Remoting service with Soap Formatter! I had to implement my own serialization to overcome the problem. Eventhough this example is showing how to handle serialization of XElement but you can apply the same logic for Nullable and Generic types (i.e. DateTime?, int?, Dictionary, etc.). using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; using System.Runtime.Serialization; using System.Xml; namespace Prodip.Concept.Common { [Serializable] public class Response : ISerializable { public Response(){} /// <summary> /// Deserialization Constructor /// </summary> /// <param name="info"></param> /// <param name="context"></param> public Response(SerializationInfo info, StreamingContext context) { try { AnyAsXmlString = new XElement("AnyAsXmlString"); AnyAsXmlString.Add(XElement.Parse((string)info.GetValue("AnyAsXmlString", typeof(string)))); } catch { AnyAsXmlString = null; } } /// <summary> /// AnyAsXmlString property is used to pass XML data between client and server. XElement is not /// serializable and Xml is converted to string when serialized (must to work with non .net clients). /// You can pass any data from server but client has to know the schema out-of-band. AnyAsXmlString /// is used for unknown or ever chaging data contract. /// </summary> public XElement AnyAsXmlString { get; set; } /// <summary> /// Custom Serialization is provided to avoid null reference during soap serialization. /// You can apply the same approach to serialize Nullable DateTime or Generics. /// Note: You must call GetObjectData on the base if you have inherited the class or you have to /// handle each property in your class if GetObjectData is not available at the base (i.e. objects in 3rd party dll). /// </summary> /// <param name="info"></param> /// <param name="context"></param> void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (AnyAsXmlString != null) { info.AddValue("AnyAsXmlString", AnyAsXmlString.ToString(SaveOptions.None)); } } } }2.1KViews0likes0CommentsRe: Passing nullable datetimes
Have a look at this article. It's more work but you can leave behind the hard-to-debug serialization issue. This works at the .net server-side but you may have problem displaying the response in the SoapUI response window because SoapUi does not do custom serialization. Soap serialization in .Net Framework viewtopic.php?f=5&t=147203.3KViews0likes0CommentsSoap serialization in .Net Framework
Soap serialization is tricky and it is much more harder if your class objects don't explicitly implement ISerializable interface. .Net Soap serializer does not know how to map the property of Employee unless you know the name of the underlying backing fields (funny looking names!). You have to scratch your head to figure out the backing field names or you can implement the ISerializable interface to gaurantee the serialization (you can even debug it!). using System; using System.Xml.Serialization; using System.Runtime.Serialization; namespace My.Concept.Contract { [Serializable] public class Employee //: ISerializable { public string Name { get; set; } public int Id { get; set; } public Employee() { } //public Employee(SerializationInfo info, StreamingContext context) //{ // Name = (string)info.GetValue("Name", typeof(string)); // Id = (int)info.GetValue("Id", typeof(int)); //} //public void GetObjectData(SerializationInfo info, StreamingContext context) //{ // info.AddValue("Name", Name); // info.AddValue("Id", Id); //} } } //this is implementation operation //ns=My.Concept.Server //class=SampleRemoteService //dll=My.Concept.Server public int TestByRef(int any, ref Employee employee) { any = 123; employee.Id = 123; employee.Name = "Jimmy"; return any; }1.5KViews0likes0CommentsRe: SoapUI Request Handcrafted for .Net Remoting Service
Here is little more.. Soap serialization is tricky and it is much more harder if your class objects don't explicitly implement ISerializable interface. .Net Soap serializer does not know how to map the property of Employee unless you know the name of the underlying backing fields (funny looking names!). You have to scratch your head to figure out the backing field names or you can implement the ISerializable interface to gaurantee the serialization (you can even debug it!). using System; using System.Xml.Serialization; using System.Runtime.Serialization; namespace My.Concept.Contract { [Serializable] public class Employee //: ISerializable { public string Name { get; set; } public int Id { get; set; } public Employee() { } //public Employee(SerializationInfo info, StreamingContext context) //{ // Name = (string)info.GetValue("Name", typeof(string)); // Id = (int)info.GetValue("Id", typeof(int)); //} //public void GetObjectData(SerializationInfo info, StreamingContext context) //{ // info.AddValue("Name", Name); // info.AddValue("Id", Id); //} } } //this is implementation operation //ns=My.Concept.Server //class=SampleRemoteService //dll=My.Concept.Server public int TestByRef(int any, ref Employee employee) { any = 123; employee.Id = 123; employee.Name = "Jimmy"; return any; }634Views0likes0CommentsSoapUI Request Handcrafted for .Net Remoting Service
SoapUI is an wonderful time saving tool to test your codes. Yes, it does allow you to add wsdl and auto configure the request envelop but would not it be nice if you know how to handcraft the soap request when you don't have the wsdl? Here is a simple example that I used to test .net remoting service but you can apply the same steps to configure request to test services running on other technologies. <!-- SoapUI Request Handcrafted for .Net Remoting Service. --> <!-- This request attach header of data contract type. The DLL is strongly named. --> <!-- The header is added to LogicalCallContext. --> <!-- Add Soapheader: SOAPAction = http://schemas.microsoft.com/clr/nsassem/namespace-of-service.ServiceClassName/ServiceDLLName#AddOperation --> <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/clr/nsassem/namespace-of-service.ServiceClassName/ServiceDLLName"> <soapenv:Header> <h4:__CallContext href="#ref-3" xmlns:h4="http://schemas.microsoft.com/clr/soap/messageProperties"/> <a1:LogicalCallContext id="ref-3" xmlns:a1="http://schemas.microsoft.com/clr/ns/System.Runtime.Remoting.Messaging"> <ClientInformation href="#ref-6"/> </a1:LogicalCallContext> <ns2:DataContractClassNameNoNameSpace id="ref-6" xmlns:ns2="http://schemas.microsoft.com/clr/nsassem/DataContractNamespace.ContractClassName/DataContractDLLName%2C%20Version%3D1.0.0.0%2C %20Culture%3Dneutral%2C%20PublicKeyToken%1Ea568g78r589r35s1"> <DataContractProperty1>Any</DataContractProperty1> <DataContractProperty2>${=java.util.UUID.randomUUID()}</DataContractProperty2> <DataContractProperty3>${=new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(new Date())}</DataContractProperty3> </ns2:DataContractClassNameNoNameSpace > </soapenv:Header> <soapenv:Body> <ns1:AddOperation soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <Value1 xsi:type="xsd:long">500</Value1> <Value2 xsi:type="xsd:long">123</Value2> </ns1:AddOperation> </soapenv:Body> </soapenv:Envelope>1.1KViews0likes1Comment