使用Nancy TinyIoC配置JsonNetSerializer和JsonNetBodyDeserializer

我是南希的菜鸟。 我一直在使用它作为生成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容器来执行此自定义,以避免inheritance链并限制Nancy.Serialization.JsonNet包中任何更改引起的潜在问题。

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

我已经尝试了几种方法来至少为JsonNetSerializer整合这种配置。 我还没有尝试使用TinyIoC配置JsonNetBodyDeserializer。 我想它会以同样的方式完成。 我尝试过的所有工作都在我的CustomNancyBootstrapper (它inheritance自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( new JsonNetSerializer( JsonSerializer.CreateDefault( settings ) ) ); } 

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

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

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

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

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

任何帮助,将不胜感激。

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

 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 TypeRegistrations { get { yield return new TypeRegistration(typeof(JsonSerializer), typeof(CustomJsonSerializer)); } } public IEnumerable CollectionTypeRegistrations { get; protected set; } public IEnumerable InstanceRegistrations { get; protected set; } } 

问: 这种方法与创建从JsonNetSerializerinheritance的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,你可以创建一些较小的特定类。

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