After-sales service for testing modules with custom serialization / deserialization

I have a problem with testing webservice, which has its own de / serialization mechanism.

My sample Task , which is used by TaskService :

 public class Task { public string TaskName { get; set; } public string AuxData { get; set; } public static void RegisterCustomSerialization(IAppHost appHost) { appHost.ContentTypeFilters.Register("application/xml", SerializeTaskToStream, DeserializeTaskFromStream); } public static void SerializeTaskToStream(IRequestContext requestContext, object response, Stream stream) { var tasks = response as List<Task>; if (tasks != null) { using (var sw = new StreamWriter(stream)) { if (tasks.Count == 0) { sw.WriteLine("<Tasks/>"); return; } sw.WriteLine("<Tasks>"); foreach (Task task in tasks) { if (task != null) { sw.WriteLine(" <Task type=\"new serializer\">"); sw.Write(" <TaskName>"); sw.Write(task.TaskName); sw.WriteLine("</TaskName>"); sw.Write(" <AuxData>"); sw.Write(task.AuxData); sw.WriteLine("</AuxData>"); sw.WriteLine(" </Task>"); } } sw.WriteLine("</Tasks>"); } } else { var task = response as Task; using (var sw = new StreamWriter(stream)) { if (task != null) { sw.WriteLine(" <Task type=\"new serializer\">"); sw.Write(" <TaskName>"); sw.Write(task.TaskName); sw.WriteLine("</TaskName>"); sw.Write(" <AuxData>"); sw.Write(task.AuxData); sw.WriteLine("</AuxData>"); sw.WriteLine(" </Task>"); } } } } public static object DeserializeTaskFromStream(Type type, Stream stream) { if (stream == null || stream.Length == 0) return null; // should throw exception? XDocument xdoc = XDocument.Load(stream); XElement auxData = xdoc.Root.Element("AuxData"); return new Task() { AuxData = auxData.Value }; } public override bool Equals(object obj) { Task task = obj as Task; if (task == null) return false; return TaskName.Equals(task.TaskName); } public override int GetHashCode() { return TaskName.GetHashCode(); } } 

I based my serialization / deserialization code on: http://www.servicestack.net/ServiceStack.Northwind/vcard-format.htm and https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/ServiceStack .Northwind / ServiceStack.Northwind.ServiceInterface / VCardFormat.cs

My base test class is as follows:

 public class SimpleRestTestBase : AppHostBase { public SimpleRestTestBase() : base( "SimpleRestTestBase", typeof(TaskService).Assembly) { Instance = null; Init(); } public override void Configure(Funq.Container container) { SetConfig(new EndpointHostConfig { DefaultContentType = ContentType.Xml } ); Task.RegisterCustomSerialization(this); Routes .Add<Task>("/tasks/{TaskName}") .Add<List<Task>>("/tasks"); container.Register(new List<Task>()); } } 

And the unit test fails:

 [TestFixture] public class SimpleTest : SimpleRestTestBase { [Test] public void TestMetodRequiringServer() { var client = (IRestClient)new XmlServiceClient("http://localhost:53967"); var data = client.Get<List<Task>>("/api/tasks"); } } 

The exception that I get when using nNnit test runner:

Testing.SimpleTest.TestMetodRequiringServer: System.Runtime.Serialization.SerializationException : Error in line 1 position 9. Expecting element 'ArrayOfTask' from namespace 'http://schemas.datacontract.org/2004/07/ServiceStackMVC'.. Encountered 'Element' with name 'Tasks', namespace ''.

How to pass information about my custom serialization / desemization code to XmlServiceClient ?

+2
source share
1 answer

You are redefining the general XML-Serialization format (application / xml) with a custom version that is heavily associated with processing only one web service output - this is very rare that you want, as this will prevent (i.e. break) all your other services return XML . If you want to return custom XML, just restrict the services that need it by returning the xml string instead.

You cannot change the implementation of XmlServiceClient, because it is closely related to the XML serialization / deserialization that ServiceStack uses. You must use a raw HTTP client to send accurate, useful XML information. Here's an example of sending raw XML with a .NET web request: fooobar.com/questions/585699 / ...

Since you are returning and submitting your own XML code, you can also override the binding of user requests for your web service so that you can deserialize the request as you want.

See the wiki page below for some examples of how to do this:

https://github.com/ServiceStack/ServiceStack/wiki/Serialization-deserialization

Note: custom XML return is not ideal as it misses many of the benefits of the strict, intelligent, and stubborn nature of ServiceStack.

+2
source

Source: https://habr.com/ru/post/943636/


All Articles