Service Stack全局启用压缩

时间:2013-10-01 23:11:22

标签: iis compression servicestack

我们使用以下帖子在我们的服务堆栈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);
    }

1 个答案:

答案 0 :(得分: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]的内容。