【问题标题】:Configuring JsonNetSerializer and JsonNetBodyDeserializer using Nancy TinyIoC使用 Nancy TinyIoC 配置 JsonNetSerializer 和 JsonNetBodyDeserializer
【发布时间】:2014-09-12 10:26:20
【问题描述】:

我是南希的菜鸟。我一直将它用作生成 REST API 的框架。我对 Json.NET 很熟悉,所以我一直在玩 Nancy.Serialization.JsonNet 包。

我的目标:自定义JsonNetSerializerJsonNetBodyDeserializer 的行为(即更改设置)。

具体来说,我想合并以下设置...

var settings = new JsonSerializerSettings { Formatting = Formatting.Indented };
settings.Converters.Add( new StringEnumConverter { AllowIntegerValues = false, CamelCaseText = true } );

我想使用内置的 TinyIoC 容器来执行此自定义,以避免继承链并限制Nancy.Serialization.JsonNet 包中的任何更改引起的潜在问题。

注意:作为临时解决方法,我利用继承来创建 CustomJsonNetSerializerCustomJsonNetBodyDeserializer

我已经尝试了几种方法来合并此配置,至少对于JsonNetSerializer。我还没有尝试使用 TinyIoC 配置 JsonNetBodyDeserializer。我想它会以类似的方式完成。我尝试过的所有工作都在我的CustomNancyBootstrapper(继承自DefaultNancyBootstrapper)中。

迄今为止最成功的方法:覆盖ConfigureApplicationContainer

protected override void ConfigureApplicationContainer( TinyIoCContainer container )
{
    base.ConfigureApplicationContainer( container );

    // probably don't need both registrations, and I've tried only keeping one or the other
    var settings = new JsonSerializerSettings { Formatting = Formatting.Indented };
    settings.Converters.Add( new StringEnumConverter { AllowIntegerValues = false, CamelCaseText = true } );
    container.Register( new JsonNetSerializer( JsonSerializer.CreateDefault( settings ) ) );
    container.Register<ISerializer>( new JsonNetSerializer( JsonSerializer.CreateDefault( settings ) ) );
}

我已经跟踪了代码,并查看了 JsonNet 包中的JsonNetSerializer(JsonSerializer serializer) 构造函数。

潜在问题:我注意到构造函数被调用了两次。我没想到会出现这种行为。

第一次一切都刚刚好 - 我的自定义已正确添加和注册。但是,第二次发生并且类型被重新注册,没有设置自定义。重新注册似乎取代了失去我的设置自定义的原始注册。

第二次调用构造函数时的调用堆栈显示它在GetEngineGetEngineInternal期间被调用,这似乎试图构建一个NancyEngine(我使用的是自托管包,所以这发生在程序中.cs -- using(var host = new NancyHost(uri)))。

似乎我要么需要告诉南希不要做某事,要么我需要加入链条的后面部分。

任何帮助将不胜感激。

【问题讨论】:

    标签: c# json.net nancy tinyioc


    【解决方案1】:

    在 Nancy 中解决这个问题的典型方法是实现自己的 JSON 序列化器,如下所示:

    public sealed class CustomJsonSerializer : JsonSerializer
    {
        public CustomJsonSerializer()
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver();
            Converters.Add(new StringEnumConverter
            {
                AllowIntegerValues = false, 
                CamelCaseText = true
            });
            Formatting = Formatting.Indented;
        }
    }
    

    您可以在此处覆盖所有设置。

    那你就可以注册了,我用IRegistrations来注册

    public class JsonRegistration : IRegistrations
    {
        public IEnumerable<TypeRegistration> TypeRegistrations
        {
            get
            {
                yield return new TypeRegistration(typeof(JsonSerializer), typeof(CustomJsonSerializer));
            }
        }
    
        public IEnumerable<CollectionTypeRegistration> CollectionTypeRegistrations { get; protected set; }
        public IEnumerable<InstanceRegistration> InstanceRegistrations { get; protected set; }
    }
    

    问: 这种方法与创建 CustomJsonNetSerializer 继承自 JsonNetSerializer 然后在 ConfigureApplicationContainer 中注册(container.Register( typeof(JsonNetSerializer), typeof(CustomJsonNetSerializer) )有何不同? em>

    答: JsonSerializer 是 Nancy 的 json.net 的实现,这是我们在 github 上的自述文件中定义的推荐方法:

    https://github.com/NancyFx/Nancy.Serialization.JsonNet#customization

    您提到的类是将对象序列化为JSON,还有另一个处理反序列化,两者都在内部使用JsonSerializer:

    https://github.com/NancyFx/Nancy.Serialization.JsonNet/blob/master/src/Nancy.Serialization.JsonNet/JsonNetSerializer.cs#L10

    使用此方法可以使使用 JsonSerializer 的任何地方的实现设置保持一致。

    问:我能否从您概述的方法中正确推断出我不再需要在我的 CustomNancyBootstrapper 的 ConfigureApplicationContainer 覆盖中显式注册 CustomJsonSerializer? p>

    答:我为注册所做的方法只是注册依赖项的一种更干净的抽象,而不是制作一个巨大的 Bootstrapper,您可以创建一些较小的特定类。

    是的,使用我的方法意味着您不需要在引导程序中注册。

    【讨论】:

    • 有趣!根据我的跟踪,CollectionTypeRegistrations 是我丢失自定义设置的地方。在我尝试这种方法之前有两个问题。这种方法与创建继承自 JsonNetSerializer 的 CustomJsonNetSerializer 然后在 ConfigureApplicationContainer (container.Register( typeof(JsonNetSerializer), typeof(CustomJsonNetSerializer) ) 中注册它有何不同?第二个问题,我可以从您概述的方法中正确推断出我会不再需要在我的 CustomNancyBootstrapper 的 ConfigureApplicationContainer 覆盖中显式注册 CustomJsonSerializer?
    • 在答案中回答了你的问题:)
    • 真棒洞察力,大帮助...谢谢菲尔!!
    • 似乎不再起作用了。自定义 json 序列化程序上的构造函数在注册后永远不会被调用。南希真是个黑匣子……
    • @SergeyAkopov 听起来您在配置所有内容后调用基类,因此注册被覆盖。所以基本上。 PEBKAC。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 2016-09-05
    • 2012-09-18
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多