Услуги по тестированию единиц услуг с пользовательской сериализацией / десериализацией
-
12-12-2019 - |
Вопрос
У меня есть проблемы с проблемой WebService, который имеет свой собственный механизм DE / сериализации.
Мой образец класса Task
, который используется 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();
}
}
.
Я основал свой код сериализации / десериализации на: http:// www. servicestack.net/servicestack.nortwind/vcard-format.htm и https://github.com/servicestack/servicestack.examples/blob/master/src/servicestack.northwind/serviceStack.northwind.ServiceInterface/vcardformat.cs
Мой базовый класс следующим образом:
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>());
}
}
.
и тест устройства, который не удается:
[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");
}
}
.
Исключение, которое я получаю при использовании Nunit 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 ''.
Как пропустить информацию о моей пользовательской сериализации / коду десулизации к генеракодичению?
Решение
Вы переопределяете общий формат сериализации XML (Application / XML) с пользовательской версией, которая сильно сочетается только для обработки 1 выход веб-сервиса - это очень редко то, что вы хотите, поскольку он предотвратит (то есть перерыв) ваши другие услуги от возврата XML. Если вы хотите вернуть пользовательский XML, просто ограничить услуги, которые нуждаются в этом, вернув строку XML вместо этого.
Вы не можете изменить реализацию XMLServicEclient, так как он сильно связан с сериализацией / десериализацией XML, которые использует ServiceStack. Вы должны использовать RAW HTTP-клиент для отправки точной полезной нагрузки XML. Вот пример, отправляющий RAW XML с веб-запросом .NET: https://stackoverflow.com/a/8046734/85785
Поскольку вы возвращаетесь и отправляете пользовательский XML, вы также можете переопределить настраиваемое связующее запрос для вашего веб-службы, поэтому у вас есть возможность исключить запрос, как вы хотите.
Смотрите страницу Wiki ниже для некоторых примеров, о том, как это сделать:
https://github.com/servicestack/servicestack/wiki/serialization-deserialization
Примечание. Возвращая пользовательский XML не идеальна, поскольку он по-прежнему многие из преимуществ сильного набранного, интеллектуального и самоуверенного и самоуверенного природы.