2013-10-01 61 views
4

我們使用以下文章在我們的服務堆棧API上啓用壓縮。服務堆棧啓用全局壓縮

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

正如你可以看到當請求類型名稱是HomepageLayoutConfigRequest我們不使用我們的自定義ApiServiceRunner。這是醜陋的,我們想要一個更好的方式來做到這一點。

任何想法?

感謝 拉斯

PS。這裏是我的最新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]聲明的意圖,但如果你的ApiServiceRunner最終所做的不僅僅是壓縮越多,你也可以使用類似[UseCustomRunner]

+0

嘿Mythz,這一切看起來不錯。雖然即時獲取空引用: var serviceType = EndpointHost.Metadata.GetServiceTypeByRequest(requestType); 由於EndpointHost.MetaData在其任何集合中都沒有任何內容。例如ServiceTypes集合是空的。 任何想法? – RuSs

+0

奇怪,請求和服務名稱是否出現在'/ operations/metadata'元數據頁面中? – mythz

+0

當然!!怪異! – RuSs