2

カスタム ServiceRunner を作成し、HandleException メソッドをオーバーライドしました。ご覧のとおり、サービス内で未処理の例外が発生した場合、HandleException メソッドによって返されるオブジェクトがサービスの応答になります。成功した場合にサービスが返すのと同じ responseDTO タイプを返したいと考えています。例外が発生したサービスの responseDTO タイプである 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

したがって、HandleException で受け取ると予想される型は次のとおりですOp<list<Y>,list<E>> (Y と E は、bin フォルダーで利用可能な dll で定義されている既知の型です)

提案に従って、WebRequestUtils が両方の名前空間で利用可能だったので、次の 2 つのオプションを試しました。

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、 expected ではなく戻り値として typeを受け取りましたOp<list<Y>,list<E>>

私はまだ何かを見逃していますか?

4

1 に答える 1

1

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();
}

ただし、リクエスト DTO を戻りタイプでマークするという ServiceStack の推奨に従っている場合は、次のようになります。

public class MyRequest : IReturn<MyResponse> { ... }

Responseまたは、リクエスト DTO の後にサフィックスを付けてレスポンス DTO の名前を付けるという ServiceStack の規則。

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タイプを返します。

また、例外が入力された応答 DTO のプロパティをDtoUtils.CreateErrorResponse()持つ、入力されたエラー応答 DTO を返すために、より便利なを使用できることにも注意してください。ResponseStatus

public override object HandleException(IRequest request, T requestDto, Exception ex)
{
    var errorResponse = DtoUtils.CreateErrorResponse(requestDto, ex);
}
于 2016-10-05T15:12:06.600 に答える