ServiceStack异常序列化行为

Chr*_*lid 2 error-handling serialization servicestack servicestack-text

免责声明:我对ServiceStack很新

鉴于以下服务:

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

        return new TestResponse();
    }
}
Run Code Online (Sandbox Code Playgroud)

和以下请求/响应DTO:

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

public class TestResponse
{
    public IList<Test> TestList { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

{
    "responseStatus": {
        "errorCode": "ArgumentException",
        "message": "Message is required",
        "errors": []
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

这是预期的行为吗?

更新

我应该包括只有在我的响应DTO的名称以Response结尾(区分大小写)时才会出现问题.如果我的请求/响应DTO分别被称为Foo和Bar,我会收到错误的格式正确的JSON响应.

myt*_*thz 5

首先,不要在DTO上使用接口,也不要ServiceStack错误响应使用文档,它说:


错误响应类型

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

如果存在:

{RequestDto}Response返回,而不管服务方法的响应类型的.如果{RequestDto}ResponseDTO具有ResponseStatus属性,则会填充它,否则将不返回ResponseStatus.

否则,如果不是:

通过ErrorResponse填充的ResponseStatus属性返回泛型.

服务客户端透明地处理不同的错误响应类型,并为无模式格式,如JSON/JSV /等有返回之间没有实际明显的区别ResponseStatus自定义或通用的ErrorResponse-因为它们都输出电线上的同样的反应.


鉴于New API允许您在保留错误信息的同时返回干净的响应,您的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; }
} 
Run Code Online (Sandbox Code Playgroud)

或者你可以不使用Response 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>();
    }
}
Run Code Online (Sandbox Code Playgroud)