2013-10-01 3 views
4

Мы использовали следующую запись, чтобы включить сжатие в нашем Service Stack API.Service Stack разрешить сжатие во всем мире

Enable gzip/deflate compression.

Мы следующий код в моем AppHost файле:

public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext actionContext) 
{ 
    return new ApiServiceRunner<TRequest>(this, actionContext); 
} 

И В моем ApiServiceRunner у меня есть следующие:

public override object OnAfterExecute(IRequestContext requestContext, object response) 
{ 
    // if it's not null and not already compressed 
    if ((response != null) && !(response is CompressedResult)) 

    // ToOptimizedResult already picks the most optimal compression (hence the name) 
    response = requestContext.ToOptimizedResult(response); 

    return base.OnAfterExecute(requestContext, response); 
} 

Проблема в том, что этот код теперь работает на КАЖДОЙ ответ и мы имеют одну конечную точку, которая просто вызывает json-файл из файловой системы сервера. Когда код запускается в этом json-файле, он полностью убивает пул приложений на сервере, и я вижу исключение переполнения стека при отладке теста интеграции, который вызывает этот json-файл.

Таким образом, мы должны были добавить следующий код в наш файл AppHost:

public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext actionContext) 
{ 
    bool useCustomRunner = actionContext.RequestType.Name != "HomepageLayoutConfigRequest"; 

    return useCustomRunner 
     ? new ApiServiceRunner<TRequest>(this, actionContext) 
     : base.CreateServiceRunner<TRequest>(actionContext); 
} 

Как вы можете видеть, что мы не используем наш пользовательский ApiServiceRunner когда имя типа запроса HomepageLayoutConfigRequest. Это уродливо, и нам нужен лучший способ сделать это.

Любые идеи?

благодаря Russ

пс. вот моя последняя AppHost CreateServiceRunner переопределение:

public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext actionContext) 
    { 
     var requestType = actionContext.RequestType; 
     string message = "The [EnableCompression] attribute exists: {0}"; 

     Debug.WriteLine(string.Format("The requestType was {0}", requestType)); 

     var useCustomRunner = requestType.HasAttribute<EnableCompression>(); 
     Debug.WriteLine(string.Format(message, requestType.HasAttribute<EnableCompression>())); 

     #region for serviceType if we ever need it. Currently it doesnt work as the guys at SS say it should 
     // https://stackoverflow.com/questions/19127522/service-stack-enable-compression-globally 
     // Commented out at there is nothing in the EndpointHost.Metadata so getting a null exception - we only need to use the attribute on the request DTO anyway. 

     // @Mythz - the following code is the code that doesnt work as per my comments 
     //var serviceType = EndpointHost.Metadata.GetServiceTypeByRequest(requestType); 

     // @Mythz- this (serviceType) is always null. It is available in next iteration of debugging (1 iteration behind) 
     //if (serviceType != null && !useCustomRunner) 
     //{ 
     // Debug.WriteLine(string.Format("The serviceType was {0}", serviceType)); 
     // useCustomRunner = serviceType.HasAttribute<EnableCompression>(); 
     // Debug.WriteLine(string.Format(message, serviceType.HasAttribute<EnableCompression>())); 
     //} 
     #endregion 

     return useCustomRunner 
      ? new ApiServiceRunner<TRequest>(this, actionContext) 
      : base.CreateServiceRunner<TRequest>(actionContext); 
    } 

ответ

2

Я думаю, что вы на правильном пути, Тхо я предпочел бы использовать пользовательский атрибут вместо этого, например, только включить сжатие для классов обслуживания или запроса DTO ', которые отмеченные [EnableCompression], вы можете сделать:

var serviceType = actionContext.ServiceType; 
var requestType = actionContext.RequestType; 

var useCustomRunner = serviceType.HasAttribute<EnableCompressionAttribute>() 
        || requestType.HasAttribute<EnableCompressionAttribute>() 

return useCustomRunner 
    ? new ApiServiceRunner<TRequest>(this, actionContext) 
    : base.CreateServiceRunner<TRequest>(actionContext); 

Я лично, как декларативное намерение [EnableCompression] но вы также можете использовать что-то вроде [UseCustomRunner], если ваш ApiServiceRunner заканчивает тем, что делает больше, чем просто сжатие.

+0

Эй, Mythz, все это выглядит великолепно. Хотя im получает нулевой ref на: var serviceType = EndpointHost.Metadata.GetServiceTypeByRequest (requestType); As EndpointHost.MetaData ничего не имеет в любом из своих коллекций. Например, коллекция ServiceTypes пуста. Любые идеи? – RuSs

+0

Нечетное, ваше имя запроса и службы отображается на странице метаданных '/ operations/metadata'? – mythz

+0

Несомненно! ... странно! – RuSs

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