为什么ToOptimizedResult抛出“请求的功能未实现”。在Mono?

时间:2014-01-22 19:21:44

标签: mono servicestack dto

我正在使用Visual Studio构建ServiceStack 4.0.8服务。在Windows上,一切都运行良好,但是当我尝试使用NGINX 1.4.1和fastcgi-server4在Mono 2.10.8.1 / Ubuntu 13.10上运行时。

我得到一个例外:

  

未实施所请求的功能。   在System.Web.HttpContextWrapper.GetService(System.Type serviceType)[0x00000] in:0   在ServiceStack.Host.RequestPreferences.GetWorker(System.Web.HttpContextBase context)[0x00000] in:0   at ServiceStack.Host.RequestPreferences.get_HttpWorkerRequest()[0x00000]   in:0 at ServiceStack.Host.RequestPreferences.get_AcceptEncoding()[0x00000]   in:0 at ServiceStack.Host.RequestPreferences.get_AcceptsDeflate()[0x00000]   in:0 at ServiceStack.RequestExtensions.GetCompressionType(IRequest request)[0x00000]   in:0 at ServiceStack.RequestExtensions.ToOptimizedResult [List 1] (IRequest request, System.Collections.Generic.List 1 dto)[0x00000]   in:0在Phase1HistoryServer.SymbolsService.Get(Phase1HistoryServer.Symbols request)[0x00000] in:0

如果我直接返回DTO对象,我不会收到错误。但是,如果我使用base.Request.ToOptimizedResult,则会发生异常。

List<DataItem> data = new List<DataItem>(); 
data.Add(new dataItem { Data = "fake data" });
return base.Request.ToOptimizedResult<List<DataItem>>(data);

1 个答案:

答案 0 :(得分:3)

更新

A commit to ServiceStack已经完成,版本4.0.16+不再受此例外的影响。


ToOptimizedResult()有效,这不是ServiceStack的缺点,而是Mono和fastcgi-server-4的缺点。有一个合适的解决方法。

单声道不完整,未实现System.Web.HttpContextWrapper.GetService

抛出此异常是因为Mono项目尚未实现此方法。由于Mono是一个OpenSource项目,他们必须自己重新创建.NET规范,而这种方法并没有完成。

See here获取相关的Mono源代码:

public class HttpContextWrapper : HttpContextBase
{
    ...

    [MonoTODO]
    public override object GetService (Type serviceType)
    {
        throw new NotImplementedException ();
    }
}

单声道解决方案,使用自托管应用程序:

我在Mono 上运行ServiceStack(虽然是v3.2.6)并且在使用ToOptimizedResult时没有任何问题,但我不使用fastcgi-server4,这将依赖于System.Web.HttpContextWrapper

相反,我使用自托管ServiceStack应用程序,该应用程序基于底层System.Net.HttpListener池,它似乎不受同一问题的影响。因此效果很好。

演示应用程序:

下面是使用您的测试代码的工作自托管ServiceStack应用程序的代码:

using System;
using ServiceStack;
using System.Collections.Generic;

namespace Testv4
{
    class MainClass
    {
        public static void Main()
        {
            // Very basic console host
            var appHost = new AppHost(500);
            appHost.Init();
            appHost.Start("http://*:8082/");
            Console.ReadKey();
        }
    }

    public class AppHost : AppHostHttpListenerPoolBase
    {
        public AppHost(int poolSize) : base("Test Service", poolSize, typeof(TestApp).Assembly) {}

        public override void Configure(Funq.Container container)
        {
        }
    }

    public static class TestApp
    {
        public class DataItem
        {
            public string Data { get; set; }
        }

        [Route("/Test", "GET")]
        public class TestRequest {}

        public class TestController : Service
        {
            public object Get(TestRequest request)
            {
                var list = new List<DataItem> {
                    new DataItem { Data = "Fake Data" }
                };

                return base.Request.ToOptimizedResult(list);
            }
        }
    }
}

您可以转到localhost:8082/Test来测试应用程序。压缩结果时不应抛出异常。

自托管应用程序可用性:

我的建议是将NGINX的请求转发到ServiceStack应用程序的透明代理功能,或者简单地删除NGINX并请求直接转到应用程序。

AppHostHttpListenerPoolBase效果很好,我在生产环境中使用它没有任何问题。