我们使用以下帖子在我们的Service Stack 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);
}
最佳答案 我认为你是在正确的轨道上,我宁愿使用自定义属性,例如,仅为服务类启用压缩或使用[EnableCompression]标记的请求DTO,你可以这样做:
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]的东西.