简体   繁体   English

使用Nancy TinyIoC配置JsonNetSerializer和JsonNetBodyDeserializer

[英]Configuring JsonNetSerializer and JsonNetBodyDeserializer using Nancy TinyIoC

I am a noob to Nancy. 我是南希的菜鸟。 I have been using it as a framework to produce a REST API. 我一直在使用它作为生成REST API的框架。 I am familiar with Json.NET so I've been playing with the Nancy.Serialization.JsonNet package. 我熟悉Json.NET所以我一直在玩Nancy.Serialization.JsonNet包。

My goal: to customize the behavior (ie change the settings) of the JsonNetSerializer and JsonNetBodyDeserializer . 我的目标:自定义JsonNetSerializerJsonNetBodyDeserializer的行为(即更改设置)。

Specifically I'd like to incorporate the following settings... 具体来说,我想加入以下设置......

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

I wanted to perform this customization using the builtin TinyIoC container to avoid the inheritance chain and limit potential issues arising from any changes in the Nancy.Serialization.JsonNet package. 我想使用内置的TinyIoC容器执行此自定义,以避免继承链并限制Nancy.Serialization.JsonNet包中任何更改引起的潜在问题。

NOTE: As a temporary workaround, I have leveraged inheritance to create CustomJsonNetSerializer and CustomJsonNetBodyDeserializer . 注意:作为临时解决方法,我利用继承来创建CustomJsonNetSerializerCustomJsonNetBodyDeserializer

I have tried several approaches to incorporate this configuration at least for the JsonNetSerializer . 我尝试了几种方法来至少为JsonNetSerializer整合这种配置。 I've not tried configuring the JsonNetBodyDeserializer using the TinyIoC yet. 我还没有尝试配置JsonNetBodyDeserializer使用TinyIoC呢。 I imagine it will be done similarly. 我想它会以同样的方式完成。 All the work I've tried is in my CustomNancyBootstrapper (which inherits from DefaultNancyBootstrapper ). 我尝试过的所有工作都在我的CustomNancyBootstrapper (它继承自DefaultNancyBootstrapper )中。

Most successful approach so far: override ConfigureApplicationContainer 到目前为止最成功的方法:覆盖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 ) ) );
}

I have traced the code and watched the JsonNetSerializer(JsonSerializer serializer) constructor in the JsonNet package. 我已经跟踪了代码并在JsonNet包中观察了JsonNetSerializer(JsonSerializer serializer)构造函数。

Potential problem: I noticed the constructor is called twice. 潜在问题:我注意到构造函数被调用了两次。 I did not expect this behavior. 我没想到这种行为。

The first time everything is just right - my customization is added and registered properly. 第一次一切都很正确 - 我的自定义被添加并正确注册。 But, then the second time happens and the types are re-registered, without the settings customization. 但是,第二次发生并且类型被重新注册,没有设置自定义。 The re-registration appears to replace the original registration losing my settings customization. 重新注册似乎取代原始注册失去我的设置自定义。

The call stack the second time the constructor is called shows that it is called during GetEngine and GetEngineInternal which seems to try to build a NancyEngine (I am using the self-host package so this happens in program.cs -- using(var host = new NancyHost(uri)) ). 第二次调用构造函数时调用堆栈显示它在GetEngineGetEngineInternal期间被调用,它似乎试图构建一个NancyEngine (我正在使用自主程序包,所以这发生在program.cs中 - using(var host = new NancyHost(uri)) )。

Seems like I either need to tell Nancy not to do something or I need to hook in to a later part in the chain. 好像我需要告诉Nancy不要做某事或者我需要挂钩到链中的后续部分。

Any help would be appreciated. 任何帮助,将不胜感激。

Typically the way to solve this in Nancy is to implement your own JSON Serializer like so: 通常,在Nancy中解决这个问题的方法是实现自己的JSON Serializer,如下所示:

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

Here you can override all the settings. 在这里,您可以覆盖所有设置。

Then you can register it, I do this by using IRegistrations 然后你可以注册它,我通过使用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; }
}

Q: How does this approach differ from creating CustomJsonNetSerializer inheriting from JsonNetSerializer and then registering it in ConfigureApplicationContainer (container.Register( typeof(JsonNetSerializer), typeof(CustomJsonNetSerializer) )? 问: 这种方法与创建从JsonNetSerializer继承的CustomJsonNetSerializer,然后在ConfigureApplicationContainer(container.Register(typeof(JsonNetSerializer),typeof(CustomJsonNetSerializer))中注册它有何不同?

A: The JsonSerializer is the implementation if json.net for Nancy, this is the recommended method we define on the readme on github: 答: JsonSerializer是jancy.net for Nancy的实现,这是我们在github上自述文件中定义的推荐方法:

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

The class you mention is the serialization of an object to JSON, there is another which handles deserialization, both of which utilize JsonSerializer internally: 你提到的类是JSON对象的序列化,还有另一个处理反序列化的类,它们都在内部使用JsonSerializer:

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

Using this method makes the implementation settings consistent anywhere that the JsonSerializer is used. 使用此方法可使实现设置在使用JsonSerializer的任何位置保持一致。

Q: can I correctly infer from the approach you've outlined that I would no longer need to explicitly register CustomJsonSerializer in the ConfigureApplicationContainer override in my CustomNancyBootstrapper? 问: 我可以从您概述的方法中正确推断出我不再需要在CustomNancyBootstrapper中的ConfigureApplicationContainer覆盖中显式注册CustomJsonSerializer吗?

A: The method I've done for registering is just a cleaner abstraction for registering dependencies, rather than making one giant Bootstrapper, you can create a few smaller specific classes. 答:我为注册完成的方法只是一个更清晰的注册依赖项抽象,而不是制作一个巨大的Bootstrapper,你可以创建一些较小的特定类。

Yes using my method means you do not need to register in the bootstrapper. 是的,使用我的方法意味着您不需要在引导程序中注册。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM