2

独自の逆シリアル化メカニズムが提供されている Web サービスのテストに問題があります。

で使用されている私のサンプル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.Northwind/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 テスト ランナーを使用するときに発生する例外は次のとおりです。

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

カスタムのシリアライゼーション/デシリアライゼーション コードに関する情報を に渡すにはどうすればよいXmlServiceClientですか?

4

1 に答える 1

2

一般的な XML シリアライゼーション形式 (application/xml) を、1 つの Web サービス出力のみを処理するように強く結合されたカスタム バージョンでオーバーライドしています。他のすべてのサービスが妨げられる (つまり壊れる) ため、これが必要になることはほとんどありません。 XML を返すことから。カスタム XML を返したい場合は、代わりに xml 文字列を返すことで、それを必要とするサービスに限定してください。

ServiceStack が使用する XML シリアライゼーション/デシリアライゼーションに強く結合されているため、XmlServiceClient の実装を変更することはできません。生の HTTP クライアントを使用して、必要な正確な XML ペイロードを送信する必要があります。.NET の Web リクエストで生の XML を送信する例を次に示します: https://stackoverflow.com/a/8046734/85785

カスタム XML を返したり送信したりするため、Web サービスのカスタム リクエスト バインダーをオーバーライドして、必要に応じてリクエストを逆シリアル化できるようにすることもできます。

これを行う方法の例については、以下の wiki ページを参照してください。

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

注: カスタム XML を返すことは、ServiceStack の強い型付け、インテリジェント、独断的な性質の利点の多くを回避するため、理想的ではありません。

于 2012-03-12T19:34:55.033 に答える