0

ServiceStack 3 ベースのクライアント サーバー アーキテクチャを使用しています。リクエスト DTO に抽象型のプロパティが含まれ、それを実装する 2 つの異なる具象クラスを持つサービスを作成しようとしています。抽象型は、抽象クラスまたはインターフェースのいずれかです。ただし、どちらの場合も、サーバーはプロパティで null オブジェクトを受け取ります。

3 つのアセンブリと対応する名前空間があります: TestClientServer、およびCommonLibクライアントとサーバーの両方によって参照されます。

つまり、次の 3 つのアセンブリに分散されます。

namespace CommonLib.Services
{
    public class GetThing : IReturn<GetThingResponse> // request DTO
    {
        public IThisOrThat Context { get; set; }
    }

    public class GetThingResponse
    {
        public Dictionary<int, string> Result { get; private set; }

        public GetThingResponse(Dictionary<int, string> result) // response DTO
        {
            Result = result;
        }
    }
}

namespace CommonLib
{
    public interface IThisOrThat { }

    public class This : IThisOrThat { } // and so forth
}

namespace Server.Services
{
    public class GetThing Service : IService
    {
        public object Get(GetThing request)
        {
            var foo = request.Context; // this is null
        }
    }
}

namespace TestClient
{
    class Program
    {
        public const string WSURL = "http://localhost:61435/";

        static void Main(string[] args)
        {
            using (var client = new JsonServiceClient(WSURL))
            {
                var result = client.Get(new GetThing
                                   {
                                       Context = new CommonLib.This("context info")
                                   });
            }
}

Contextのプロパティをの代わりにGetThingタイプに変更すると、これは機能します。インターフェイスのままにするか、抽象クラスに変更すると、データは として送信されます。ThisIThisOrThatIThisOrThatnull

これはシリアル化の問題だと思います。インターフェースを抽象クラスに変更し、適切な属性で装飾しようとしましたKnownTypeが、ServiceStack のシリアライザーはこの恩恵を受けていないようです。これを行うためのトリックはありますか?

4

2 に答える 2

2

JsConfig.IncludeTypeInfo = true;クライアント側で有効にする必要があるため、シリアライザーはリクエストに型情報を含めます。これにより、タイプ定義を含む追加のプロパティ ( __type) が追加されるため、サービスはそれを何としてタイプするかを認識します。

デフォルトでは、リクエストはオブジェクトをインターフェイスを実装するクラスに逆シリアル化するための型情報を提供しないため、現在失敗しています。これは、以前に提起された問題です。

問題は、JSON クライアントが要求を行うときに、クラスIThisOrThatなどを実装するクラスをシリアル化することThisです。しかし、もう一方の端に到達すると、 ServiceStack.Text はオブジェクトを何に逆シリアル化するかを知りません。型情報が失われているので、それが何の種類かわかりませんIThisOrThat。したがって__type、リクエストに追加情報プロパティがないと、次のことが起こります。

シナリオ:

interface ISomething
{
    string Name;
}

class MySomething : ISomething
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class MySomethingElse : ISomething
{
    public string Name { get; set; }
    public int Size { get; set; }
}

次に、型指定されたオブジェクトを使用して JsonServiceClient から呼び出しを行います

client.Get(new MySomething { Name: "Duck", Age: 20 });

送信される JSON{ "Name":"Duck", "Age":20 }は、デシリアライザーが現在選択している型になりますか? それはMySomethingまたは、またはまだ知らないMySomethingElse別のものである可能性があります。ISomethingしたがって、結果を決定できないため、単純にnull.

通常、インターフェイスと DTO は混在しません。こちら を参照してください

于 2014-01-31T18:49:42.493 に答える