Unit-Test-ServiceStack-Services mit benutzerdefinierter Serialisierung / Deserialisierung

StackOverflow https://stackoverflow.com//questions/9671493

  •  12-12-2019
  •  | 
  •  

Frage

Ich habe ein Problem beim Testen des Webservices, für den ein eigener De- / Serialisierungsmechanismus bereitgestellt wird.

Meine Probe Task klasse, die von verwendet wird 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();
    }
}

Ich habe meinen Serialisierungs- / Deserialisierungscode basierend auf: http://www.servicestack.net/ServiceStack.Northwind/vcard-format.htm und https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/ServiceStack.Northwind/ServiceStack.Northwind.ServiceInterface/VCardFormat.cs

Meine Basistestklasse ist wie folgt:

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>());
    }
}

Und der Komponententest, der fehlschlägt:

[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");
    }
}

Die Ausnahme, die ich bei der Verwendung von NUnit Test Runner bekomme, ist:

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 ''.

Wie übergebe ich Informationen zu meinem benutzerdefinierten Serialisierungs- / Deseialisierungscode an die XmlServiceClient?

War es hilfreich?

Lösung

Sie überschreiben das generische XML-Serialisierungsformat (application / xml) mit einer benutzerdefinierten Version, die stark gekoppelt ist, um nur 1 Webdienstausgabe zu verarbeiten - dies ist sehr selten das, was Sie wollen, da es verhindert (dh.brechen) alle Ihre anderen Dienste von der Rückgabe von XML ab.Wenn Sie benutzerdefiniertes XML zurückgeben möchten, beschränken Sie sich einfach auf die Dienste, die es benötigen, indem Sie stattdessen eine XML-Zeichenfolge zurückgeben.

Sie können die Implementierung von XmlServiceClient nicht ändern, da sie stark an die von ServiceStack verwendete XML-Serialisierung / Deserialisierung gekoppelt ist.Sie sollten einen rohen HTTP-Client verwenden, um genau die gewünschte XML-Nutzlast zu senden.Hier ist ein Beispiel zum Senden von rohem XML mit der .NET-Webanforderung:https://stackoverflow.com/a/8046734/85785

Da Sie benutzerdefiniertes XML zurückgeben und senden, möchten Sie möglicherweise auch den benutzerdefinierten Anforderungsordner für Ihren Webdienst überschreiben, damit Sie die Möglichkeit haben, die Anforderung nach Ihren Wünschen zu deserialisieren.

Auf der Wiki-Seite unten finden Sie einige Beispiele dafür:

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

Beachten:die Rückgabe von benutzerdefiniertem XML ist nicht ideal, da es viele der Vorteile der stark typisierten, intelligenten und meinungsstarken Natur von ServiceStack umgeht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top