我编写了自定义ServiceRunner并重写了HandleException方法。我可以看到,如果服务中存在未处理的异常,HandleException方法返回的对象将成为服务响应。我希望返回服务在成功时返回的相同responseDTO类型。我有没有办法在HandleException中访问,遇到异常的服务的responseDTO类型?
编辑: 根据收到的答复,我实现了服务(在F#中),其DTO /服务类型定义如下:
type CS()=
interface IReturn<Op<list<Y>,list<E>>>
member val key = List<int>() with get,set
type CSService() =
interface IService
member this.Get(request: CS)=
//service code here returning Op<list<Y>,seq<E>> type
因此,我期望在HandleException中收到的类型是Op<list<Y>,list<E>>
(Y和E是在bin文件夹中可用的dll中定义的已知类型)
根据建议我尝试了以下两个选项,因为WebRequestUtils在两个命名空间中都可用:
Type test1 = ServiceStack.WebRequestUtils.GetErrorResponseDtoType(request.GetType());//error
Type test2 = ServiceStack.ServiceClient.Web.WebRequestUtils.GetErrorResponseDtoType(request.GetType());
对于test1,我收到以下异常:
Could not load type 'ServiceStack.ErrorResponse' from assembly 'ServiceStack.Interfaces, Version=3.9.71.0, Culture=neutral, PublicKeyToken=null'.
堆栈追踪:
at ServiceStack.WebRequestUtils.GetErrorResponseDtoType(Type requestType)
at M.ServiceStackWebAPP.MyCustomServiceRunner`1.HandleException(IRequestContext requestContext, TRequest request, Exception ex) in d:\Projects\ServiceStack\M.WebService\MyCustomServiceRunner.cs:line 167
at ServiceStack.ServiceHost.ServiceRunner`1.Execute(IRequestContext requestContext, Object instance, TRequest request)
at ServiceStack.ServiceHost.ServiceRunner`1.Process(IRequestContext requestContext, Object instance, Object request)
at ServiceStack.ServiceHost.NServiceExec`1.Execute(IRequestContext requestContext, Object instance, Object request, String requestName)
at ServiceStack.ServiceHost.NServiceRequestExec`2.Execute(IRequestContext requestContext, Object instance, Object request)
at ServiceStack.ServiceHost.ServiceController.<>c__DisplayClass15.<>c__DisplayClass17.<RegisterNServiceExecutor>b__14(IRequestContext reqCtx, Object req)
at ServiceStack.ServiceHost.ServiceController.ManagedServiceExec(ServiceExecFn serviceExec, Object service, IRequestContext requestContext, Object dto)
at ServiceStack.ServiceHost.ServiceController.<>c__DisplayClass15.<RegisterNServiceExecutor>b__13(IRequestContext requestContext, Object dto)
at ServiceStack.ServiceHost.ServiceController.Execute(Object request, IRequestContext requestContext)
at ServiceStack.WebHost.Endpoints.EndpointHost.ExecuteService(Object request, EndpointAttributes endpointAttributes, IHttpRequest httpReq, IHttpResponse httpRes)
at ServiceStack.WebHost.Endpoints.Support.EndpointHandlerBase.ExecuteService(Object request, EndpointAttributes endpointAttributes, IHttpRequest httpReq, IHttpResponse httpRes)
at ServiceStack.WebHost.Endpoints.RestHandler.GetResponse(IHttpRequest httpReq, IHttpResponse httpRes, Object request)
at ServiceStack.WebHost.Endpoints.RestHandler.ProcessRequest(IHttpRequest httpReq, IHttpResponse httpRes, String operationName)
对test2的调用成功,但我收到ErrorResponse
类型作为返回值而不是预期的Op<list<Y>,list<E>>
。
我还缺少什么吗?
答案 0 :(得分:1)
由于ServiceStack Services允许您返回任何响应类型,如果未发生异常,最终无法确切知道服务将返回什么,因为这将依赖于运行时执行的服务实现逻辑抛出异常后,例如:
public object Any(Request request)
{
throw new Exception(); //No way of knowing what Service would've returned
if (SomeCustomLogic(request))
return new Response1();
return new Response2();
}
虽然您遵循ServiceStack建议使用返回类型标记您的请求DTO,例如:
public class MyRequest : IReturn<MyResponse> { ... }
或ServiceStack的约定,即以请求DTO命名的响应DTO,后缀为Response
,例如:
public class GetCustomers { ... }
public class GetCustomersResponse { ... }
然后您可以使用WebRequestUtils.GetErrorResponseDtoType(requestType)
从请求DTO类型中检索响应类型,例如:
public override object HandleException(IRequest request, T requestDto, Exception ex)
{
var responseType = WebRequestUtils.GetErrorResponseDtoType(requestDto.GetType());
}
如果ServiceStack无法推断响应类型(即不使用上面推荐的约定),则返回通用ErrorResponse
类型。
另请注意,您可以使用更有用的DtoUtils.CreateErrorResponse()
来返回填充错误Response DTO,该错误具有响应DTO的ResponseStatus
属性,例如:
public override object HandleException(IRequest request, T requestDto, Exception ex)
{
var errorResponse = DtoUtils.CreateErrorResponse(requestDto, ex);
}