2016-10-05 2 views
2

Я написал собственный ServiceRunner и переопределил метод HandleException. Как я вижу, в случае необработанного исключения внутри службы объект, возвращаемый методом HandleException, становится ответом службы. Я хочу вернуть тот же тип responseDTO, что служба возвращается в случае успеха. Есть ли способ, с помощью которого я могу получить доступ к HandleException, к типу responseDTO службы, который столкнулся с этим исключением?Доступ к типу responseDTO в HandleException пользовательского ServiceRunner в ServiceStack

EDIT: В соответствии с полученным ответом я реализовывал услуги (которые в 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 и Е известны типы, которые определены в DLL, доступных в папке Bin)

по предложению я попытался следующие два варианта, так как 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>>.

У меня все еще что-то отсутствует?

ответ

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 по маркировке вашего запроса DTOs с обратным типа, например:

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() вернуть населенную ошибку отклик DTO, который будет иметь ResponseStatus свойства DTO ответа заселенную с Exception, например:

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

Спасибо за быстрый ответ. Я все еще не могу получить тип responseDTO.Я дал дополнительную информацию, основанную на вашем ответе. Пожалуйста, дайте мне знать, если требуется дополнительная информация. – ronilk

+0

@ronilk ошибки, которые вы получаете, это то, что вы используете старый v3 ServiceStack с новыми пакетами. Все пакеты ServiceStack должны иметь ту же версию, которую вы можете проверить, просмотрев папку NuGet/packages. Если вы сомневаетесь в версии 3 ServiceStack, просим пометить ваши вопросы ** servicestack-bsd ** not ** servicestack **. – mythz

+0

Спасибо за указание. Я изменил тег. – ronilk

Смежные вопросы