C# 访问responseDTO在ServiceStack中键入自定义ServiceRunner的HandleException

C# 访问responseDTO在ServiceStack中键入自定义ServiceRunner的HandleException,c#,exception-handling,servicestack-bsd,C#,Exception Handling,Servicestack Bsd,我已经编写了定制ServiceRunner并重写了HandleException方法。如我所见,如果服务中存在未处理的异常,HandleException方法返回的对象将成为服务响应。我希望返回与服务成功返回的响应类型相同的响应。是否有任何方法可以访问遇到异常的服务的响应类型HandleException内部 编辑: 根据收到的回答,我使用定义如下的DTO/服务类型实现了服务(在F#中): type CS()= interface IReturn<Op<list<Y&g

我已经编写了定制ServiceRunner并重写了HandleException方法。如我所见,如果服务中存在未处理的异常,HandleException方法返回的对象将成为服务响应。我希望返回与服务成功返回的响应类型相同的响应。是否有任何方法可以访问遇到异常的服务的响应类型HandleException内部

编辑: 根据收到的回答,我使用定义如下的DTO/服务类型实现了服务(在F#中):

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
对于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)
ServiceStack.WebRequestUtils.GetErrorResponseDtoType(类型requestType)上的

在d:\Projects\ServiceStack\M.WebService\MyCustomServiceRunner.cs:第167行中的M.ServiceStackWebAPP.MyCustomServiceRunner`1.HandleException(IRequestContext requestContext,TRequest request,Exception ex)处
在ServiceStack.ServiceHost.ServiceRunner`1.Execute(IRequestContext请求上下文、对象实例、TRequest请求)
位于ServiceStack.ServiceHost.ServiceRunner`1.Process(IRequestContext requestContext、对象实例、对象请求)
在ServiceStack.ServiceHost.NServiceExec`1.Execute(IRequestContext requestContext、对象实例、对象请求、字符串requestName)
在ServiceStack.ServiceHost.NServiceRequestExec`2.Execute处(IRequestContext requestContext,对象实例,对象请求)
在ServiceStack.ServiceHost.ServiceController.c\u DisplayClass15.c\u DisplayClass17.b\u 14(IRequestContext reqCtx,Object req)
位于ServiceStack.ServiceHost.ServiceController.ManagedServiceExec(ServiceExecFn serviceExec,对象服务,IRequestContext requestContext,对象dto)
在ServiceStack.ServiceHost.ServiceController.c__显示器Class15.b__13(IRequestContext requestContext,对象dto)
在ServiceStack.ServiceHost.ServiceController.Execute(对象请求,IRequestContext请求上下文)
在ServiceStack.WebHost.Endpoints.EndpointHost.ExecuteService(对象请求、EndpointAttributes、EndpointAttributes、IHttpRequest HttpRequest、IHTTPreponse httpRes)
位于ServiceStack.WebHost.Endpoints.Support.EndpointHandlerBase.ExecuteService(对象请求、端点属性、IHttpRequest httpReq、IHTTPreponse httpRes)
位于ServiceStack.WebHost.Endpoints.RestHandler.GetResponse(IHttpRequest httpReq、IHttpResponse httpRes、对象请求)
位于ServiceStack.WebHost.Endpoints.RestHandler.ProcessRequest(IHttpRequest httpReq、IHTTPreponse httpRes、String operationName)
调用test2成功,但我收到
ErrorResponse
类型作为返回值,而不是预期的
Op


我还缺少什么吗?

因为ServiceStack服务允许您返回任何响应类型如果没有发生异常,最终不可能确切知道服务会返回什么,因为这取决于引发异常后执行的运行时服务实现逻辑,例如:

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> { ... }
public override object HandleException(IRequest request, T requestDto, Exception ex)
{
    var responseType = WebRequestUtils.GetErrorResponseDtoType(requestDto.GetType());
}
然后您可以使用
WebRequestUtils.GetErrorResponseDtoType(requestType)
从请求数据类型中检索响应类型,例如:

public class MyRequest : IReturn<MyResponse> { ... }
public override object HandleException(IRequest request, T requestDto, Exception ex)
{
    var responseType = WebRequestUtils.GetErrorResponseDtoType(requestDto.GetType());
}
如果ServiceStack无法推断响应类型(即不使用上述推荐约定),则将返回通用
ErrorResponse
类型

还请注意,您可以使用更有用的
DtoUtils.CreateErrorResponse()
返回填充的错误响应DTO,该响应DTO的
ResponseStatus
属性将填充异常,例如:

public override object HandleException(IRequest request, T requestDto, Exception ex)
{
    var errorResponse = DtoUtils.CreateErrorResponse(requestDto, ex);
}

谢谢你的快速回复。我仍然无法收到回复的to类型。根据你的回答,我已经提供了更多的信息。如果需要更多信息,请告诉我。@ronilk您收到的错误是因为您正在将旧版本的ServiceStack与新软件包一起使用。所有ServiceStack软件包必须具有相同的版本,您可以通过查看NuGet/packages文件夹来检查该版本。如果您的问题在ServiceStack的v3上,请将您的问题标记为ServiceStack bsd而不是ServiceStack。我在WebRequestUtils.cs源代码中查看了GetErrorResponseDtoType方法。对我来说,该方法返回ErrorResponse而不是响应类型,因为hasResponseStatus变量变为false。所以我想问一下,除了检查错误细节之外,ResponseStatus在任何场景中是否都很重要?如果我没有在任何地方使用ResponseStatus,那么我可以安全地忽略这部分并直接调用GetTypeWithGenericTypeDefinitionOf方法吗?直接在HandleException内部调用GetTypeWithGenericTypeDefinition的方法就可以了。