使用服务堆栈返回对象列表时出现异常

本文关键字:异常 列表 对象 服务 堆栈 返回 | 更新日期: 2023-09-27 18:32:31

我试图让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");

"模型工厂"类是一个返回列表的数据库访问类。当我通过网络浏览器访问该服务时,一切似乎都很好。从服务返回的 JSON 启动:

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

并以以下结尾:

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

我的问题是,这里可能导致序列化/反序列化失败的原因是什么?

溶液

多亏了mythz的回答,我才能够弄清楚我做错了什么。我的误解在于到底有多少DTO类型以及它们的作用。在我的脑海里,我让它们以某种不正确的方式合并在一起。所以现在据我了解:

要返回的对象(在我的例子中,称为"ServiceCallModel":您希望客户端在 ServiceStack 完成其工作后拥有的实际类。就我而言,ServiceCallModel 是我的程序中的一个关键类,许多其他类使用和创建它。

请求

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

响应

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

此外,正如 Mythz 所说,我现在明白在请求 DTO 中添加"IReturn"的原因,以便客户端准确地知道服务器将发送回它的内容。就我而言,我正在使用ServiceCallModel列表作为Android中ListView的数据源。因此,很高兴能够告诉ListViewAdapter"响应。结果"实际上已经是一个有用的列表。

感谢Mythz的帮助。

使用服务堆栈返回对象列表时出现异常

此错误:

Type definitions should start with a '{' 

当 JSON 的形状与其预期不匹配时发生,对于此示例:

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

客户端期望服务返回ServiceCallResponse,但从提供的信息中不清楚这种情况正在发生 - 尽管错误表明它没有发生。

添加类型安全

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

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

为了让客户端猜测服务返回的内容,您只需在请求 DTO 上指定它:

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

这使您的客户拥有更简洁和类型的API,例如:

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

而不是:

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

有关详细信息,请参阅新 API 和 C# 客户端文档。