SignalR,WebApi,Autofac,camelCasedJson

时间:2015-08-24 22:01:55

标签: json asp.net-web-api signalr autofac

我有一个web api应用程序,包括一些SignalR功能,它具有由Autofac管理的依赖项。

SignalR,开箱即用,不支持camelCased Json属性。

有一个不错的修复here,但我需要将它与Autofac集成。

所以.....

这是SignalR中心

 public class PledgeHub : Hub
{
    public void SendPledge(LivePledgeUpdate pledge)
    {
        Clients.All.sendPledge(pledge);
    }
}

这是startup.cs类,其中包含文章

中的Camelcased Resolver
[assembly: OwinStartup(typeof(Startup))]
namespace Filanthropy.Web
{
    public partial class Startup
    {

        private readonly HttpConfiguration config;

        public Startup()
        {
            config = new HttpConfiguration();
        }

        public void Configuration(IAppBuilder app)
        {

            // Set the dependency resolver to be Autofac.
            var container = BuildContainer(config);

            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

            ConfigureAuth(app);

            ConfigureWebApi(config);

            app.MapSignalR();          

            app.UseWebApi(config);

            app.UseAutofacMiddleware(container);
            app.UseAutofacWebApi(config);            
    }



        private void ConfigureWebApi(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
               name: "DefaultApi",
               routeTemplate: "api/{controller}/{id}",
               defaults: new { id = RouteParameter.Optional }
               );

            var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
            jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();


        }

        private static IContainer BuildContainer(HttpConfiguration config)
        {
           var builder = new ContainerBuilder();

            // Register your Web API controllers.
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

            // OPTIONAL: Register the Autofac filter provider.
            builder.RegisterWebApiFilterProvider(config);

            builder.RegisterType<PledgeHub>().ExternallyOwned();           

            GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => JsonSerializerFactory.Value);

            return builder.Build();
    }


        private static readonly Lazy<JsonSerializer> JsonSerializerFactory = new Lazy<JsonSerializer>(GetJsonSerializer);

        private static JsonSerializer GetJsonSerializer()
        {
            return new JsonSerializer
            {
                ContractResolver = new FilteredCamelCasePropertyNamesContractResolver
                {

                    TypesToInclude =
                                {
                                    typeof(SignalRHubs.PledgeHub),
                                }
                }
            };
        }


    }
}

我通过WebApi获得了所有服务的camelCased属性,但不是通过Signalr。

1 个答案:

答案 0 :(得分:1)

我猜你的问题是这样的:

GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => JsonSerializerFactory.Value);

如果您使用Autofac作为容器/依赖项解析程序,则需要使用Autofac注册序列化程序,而不是使用即将被替换的全局依赖项解析程序。

builder.Register(ctx => JsonSerializerFactory.Value).As<JsonSerializer>();

另外,我看到你正在使用OWIN。使用OWIN时,不引用GlobalHost - 您需要单独设置集线器配置。 The docs have an example showing how to do it

public class Startup
{
  public void Configuration(IAppBuilder app)
  {
    var builder = new ContainerBuilder();

    // STANDARD SIGNALR SETUP:

    // Get your HubConfiguration. In OWIN, you'll create one
    // rather than using GlobalHost.
    var config = new HubConfiguration();

    // Register your SignalR hubs.
    builder.RegisterHubs(Assembly.GetExecutingAssembly());

    // Set the dependency resolver to be Autofac.
    var container = builder.Build();
    config.Resolver = new AutofacDependencyResolver(container);

    // OWIN SIGNALR SETUP:

    // Register the Autofac middleware FIRST, then the standard SignalR middleware.
    app.UseAutofacMiddleware(container);
    app.MapSignalR("/signalr", config);
  }
}