【问题标题】:ServiceStack exception serialization behaviourServiceStack 异常序列化行为
【发布时间】:2013-08-15 23:21:03
【问题描述】:

免责声明:我对 ServiceStack 还很陌生

鉴于以下服务:

public class TestService : Service
{
    public TestResponse Get(Test request)
    {
        if (String.IsNullOrEmpty(request.Message))
            throw new ArgumentException("Message is required");

        return new TestResponse();
    }
}

以及以下请求/响应 DTO:

[Route("/test", "GET")]
public class Test : IReturn<TestResponse>
{
    public string Message { get; set; }
}

public class TestResponse
{
    public IList<Test> TestList { get; set; }
}

当我尝试访问 /test 时,我希望得到以下响应:

{
    "responseStatus": {
        "errorCode": "ArgumentException",
        "message": "Message is required",
        "errors": []
    }
}

相反,我得到一个空的 JSON 响应。然而,它返回了正确的状态码(400 Bad Request)。

我认为在 ServiceStack 中以这种方式命名您的 DTO 是很常见的,先是Something,然后是SomethingResponse。为了让它将异常作为序列化的 ResponseStatus 对象返回,我发现我可以将我的请求 DTO 从 Test 重命名为 TestRequest 和/或在我的响应 DTO 中包含一个 ResponseStatus 属性。

这是预期的行为吗?

更新

我应该指出,仅当我的响应 DTO 的名称以 Response 结尾(区分大小写)时才会出现问题。如果我的请求/响应 DTO 分别称为 Foo 和 Bar,我会收到格式正确的 JSON 响应并显示错误。

【问题讨论】:

    标签: serialization error-handling servicestack servicestack-text


    【解决方案1】:

    首先,don't use interfaces on DTOsServiceStack Error Responses 上的文档说:


    错误响应类型

    抛出异常时返回的错误响应取决于是否存在常规命名的{RequestDto}Response DTO。

    如果存在:

    无论服务方法的响应类型如何,都会返回{RequestDto}Response。如果{RequestDto}Response DTO 具有 ResponseStatus 属性,则会填充该属性,否则不会返回任何 ResponseStatus

    否则,如果没有:

    一个通用的 ErrorResponse 被返回一个填充的 ResponseStatus 属性。

    Service Clients 透明地处理不同的错误响应类型,对于 JSON/JSV/等等无模式格式,在自定义或通用 @987654330 中返回 ResponseStatus 之间没有实际可见的区别@ - 因为它们都在线路上输出相同的响应。


    鉴于New API 允许您return clean responses 同时仍保留错误信息,您的 DTO 应该是:

    [Route("/test", "GET")]
    public class Test : IReturn<TestResponse>
    {
        public string Message { get; set; }
    }
    
    public class TestResponse
    {
        public List<Test> TestList { get; set; }
    
        public ResponseStatus ResponseStatus { get; set; }
    } 
    

    或者您可以不使用响应 DTO 并返回干净列表,例如:

    [Route("/test", "GET")]
    public class Test : IReturn<List<Test>>
    {
        public string Message { get; set; }
    }
    
    public class TestService : Service
    {
        public List<Test> Get(Test request)
        {
            if (String.IsNullOrEmpty(request.Message))
                throw new ArgumentException("Message is required");
    
            return new List<Test>();
        }
    }
    

    【讨论】:

    • 感谢您的回复。我不太明白你关于不在 DTO 上使用接口的评论。我在我的示例中拥有的唯一接口是 IReturn,我理解它是为了支持客户端的静态类型而被推荐的。我还认为,通过使用新 API,我不必添加 ResponseStatus 属性。
    • @ChristianHagelid 我指的是IList&lt;Test&gt; TestList 属性。
    • 这是有道理的。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 2010-12-15
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多