返回带有servicestack的对象列表时出现异常

时间:2013-09-24 13:41:09

标签: c# .net json servicestack dto

我试图让ServiceStack将对象列表返回给C#客户端,但我一直得到这个例外:

"... System.Runtime.Serialization.SerializationException: Type definitions should start with a '{' ...."

我想要回归的模型:

public class ServiceCallModel
{

    public ServiceCallModel()
    {
        call_uid = 0;
    }

    public ServiceCallModel(int callUid)
    {
        this.call_uid = callUid;
    }

    public int call_uid { get; set; }
    public int store_uid { get; set; }

    ...... <many more properties> ......

    public bool cap_expense { get; set; }
    public bool is_new { get; set; }
    // An array of properties to exclude from property building 
    public string[] excludedProperties = { "" };
}

回应:

public class ServiceCallResponse
{
    public List<ServiceCallModel> Result { get; set; }
    public ResponseStatus ResponseStatus { get; set; } //Where Exceptions get auto-serialized
}

服务:

public class ServiceCallsService : Service 
{
    // An instance of model factory
    ModelFactory MyModelFactory = new ModelFactory(); 

    public object Any(ServiceCallModel request)
    {
        if (request.call_uid != 0)
        {
            return MyModelFactory.GetServiceCalls(request.call_uid); 
        } else { 
            return MyModelFactory.GetServiceCalls() ; 
        }
    }
}

客户端使用以下方式访问服务:

        JsonServiceClient client = new ServiceStack.ServiceClient.Web.JsonServiceClient("http://172.16.0.15/");
        client.SetCredentials("user", "1234");
        client.AlwaysSendBasicAuthHeader = true;
        ServiceCallResponse response = client.Get<ServiceCallResponse>("/sc");

“model factory”类是一个返回列表的DB访问类。当我通过Web浏览器访问服务时,一切似乎都运行正常。从服务返回的JSON开始:

"[{"call_uid":70...."

结束于:

"....false,"is_new":true}]"

我的问题是,这可能会导致序列化/反序列化失败?

解决方案

感谢mythz的回答,我能够弄清楚我做错了什么。我的误解在于究竟有多少DTO类型,以及它们究竟是做什么的。在我看来,我把它们以某种不正确的方式合并在一起。所以现在我明白了:

要返回的对象(在我的例子中,称为“ServiceCallModel”:一旦ServiceStack完成其工作,您希望客户端拥有的实际类。在我的例子中,ServiceCallModel是我的程序中的一个关键类,许多其他类消耗并创造。

请求DTO:这是客户端发送到服务器的内容,包含与发出请求相关的任何内容。变量等

响应DTO:服务器发送回请求客户端的响应。这个包含单个数据对象(ServiceCallModel),或者在我的情况下......包含ServiceCallModel列表。

此外,正如Mythz所说,我现在理解在请求DTO中添加“IReturn”的原因是客户端将准确知道服务器将发回给它的内容。在我的例子中,我使用ServiceCallModel列表作为Android中ListView的数据源。因此能够告诉ListViewAdapter“response.Result”实际上已经是一个有用的列表了。

感谢Mythz的帮助。

1 个答案:

答案 0 :(得分:2)

此错误:

Type definitions should start with a '{' 

当JSON的形状与预期的形状不匹配时会发生这种情况,例如:

ServiceCallResponse response = client.Get<ServiceCallResponse>("/sc");

客户希望服务返回ServiceCallResponse,但是从提供的信息中发现这种情况并不清楚 - 虽然错误表明它不是。

添加类型安全

虽然它不会改变行为,但如果在服务中指定类型,则可以断言它返回预期类型,例如将object更改为ServiceCallResponse,例如:

public ServiceCallResponse Any(ServiceCallModel request)
{
    ...
}

为了保存客户猜测服务返回的内容,您可以在Request DTO上使用以下命令指定它:

public class ServiceCallModel : IReturn<ServiceCallResponse>
{
    ...
}

这可以让您的客户拥有更简洁和类型化的API,例如:

ServiceCallResponse response = client.Get(new ServiceCallModel());

而不是:

ServiceCallResponse response = client.Get<ServiceCallResponse>("/sc");

有关详细信息,请参阅New APIC# Clients文档。