【问题标题】:ServiceStack: Property in request DTO becomes null if type is abstractServiceStack:如果类型是抽象的,请求 DTO 中的属性变为空
【发布时间】:2014-01-31 17:11:00
【问题描述】:

我有一个基于 ServiceStack 3 的客户端-服务器架构。我正在尝试创建一个服务,其请求 DTO 包含一个具有抽象类型的属性,两个不同的具体类实现它。抽象类型可以是抽象类也可以是接口;但是,无论哪种情况,服务器都会在属性中收到一个空对象。

客户端和服务器都引用了三个程序集和相应的命名空间:TestClientServerCommonLib

也就是说,分布在三个程序集中:

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

如果我将GetThing 中的Context 属性更改为This 类型而不是IThisOrThat,则此方法有效。将其保留为接口,或者将IThisOrThat 更改为抽象类,导致数据以null 传输。

我假设这是一个序列化问题。我尝试将接口更改为抽象类并使用适当的KnownType 属性对其进行装饰,但ServiceStack 的序列化程序似乎并没有从中受益。有什么诀窍可以做到这一点吗?

【问题讨论】:

    标签: c# json .net-4.0 servicestack servicestack-bsd


    【解决方案1】:

    您需要在客户端启用JsConfig.IncludeTypeInfo = true;,因此序列化程序会在请求中包含类型信息。这将添加一个带有类型定义的额外属性 (__type),以便服务知道将其键入为什么。

    目前失败是因为默认情况下请求不提供类型信息来将对象反序列化为实现接口的类。这是previously raised 的问题。

    问题是当 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 } 反序列化器现在选择什么类型?它可能是MySomethingMySomethingElse,甚至是另一个它还不知道的ISomething。所以因为它不能决定结果只是null

    一般接口和 DTO 不会混用,see here

    【讨论】:

    • 宾果游戏。 ServiceStack.Text.JsConfig.IncludeTypeInfo = true;client.Get() 之前就可以了。
    【解决方案2】:

    我遇到了类似的问题,并意识到我没有 { get;放; } 应用于响应 DTO,因此我的对象的结果始终为 null...

    认为此信息也可以帮助任何搜索此信息的人...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-08
      相关资源
      最近更新 更多