使用Nancy TinyIoC配置JsonNetSerializer和JsonNetBodyDeserializer

Rob*_*Rob 8 c# json.net nancy tinyioc

我是南希的菜鸟.我一直在使用它作为生成REST API的框架.我熟悉Json.NET所以我一直在玩这个Nancy.Serialization.JsonNet包.

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

具体来说,我想加入以下设置......

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

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

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

我已经尝试了几种方法来合并这种配置至少为JsonNetSerializer.我还没有尝试配置JsonNetBodyDeserializer使用TinyIoC.我想它会以同样的方式完成.我尝试过的所有工作都在我的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 ) ) );
}
Run Code Online (Sandbox Code Playgroud)

我已经跟踪了代码并JsonNetSerializer(JsonSerializer serializer)在JsonNet包中观察了构造函数.

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

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

第二次调用构造函数时调用堆栈显示它在调用期间GetEngine,GetEngineInternal并且似乎尝试构建一个NancyEngine(我正在使用自主程序包,所以这发生在program.cs中 - using(var host = new NancyHost(uri))).

好像我需要告诉Nancy不要做某事或者我需要挂钩到链中的后续部分.

任何帮助,将不胜感激.

Phi*_*ill 15

通常,在Nancy中解决这个问题的方法是实现自己的JSON Serializer,如下所示:

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

在这里,您可以覆盖所有设置.

然后你可以注册它,我这样做是通过使用 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; }
}
Run Code Online (Sandbox Code Playgroud)

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

答: JsonSerializer是jancy.net for Nancy的实现,这是我们在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吗?

答: 我为注册完成的方法只是一个更清晰的注册依赖项抽象,而不是制作一个巨大的Bootstrapper,你可以创建一些较小的特定类.

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