使用Nancy TinyIoC配置JsonNetSerializer和JsonNetBodyDeserializer

本文关键字:JsonNetBodyDeserializer JsonNetSerializer 配置 Nancy TinyIoC 使用 | 更新日期: 2023-09-27 18:14:02

我对Nancy是个新手。我一直使用它作为框架来生成REST API。我熟悉Json。所以我一直在使用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(我使用的是self-host包,所以这发生在program.cs—using(var host = new NancyHost(uri))中)。

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

使用Nancy TinyIoC配置JsonNetSerializer和JsonNetBodyDeserializer

通常在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; }
}

Q:这种方法与从JsonNetSerializer继承创建CustomJsonNetSerializer然后在ConfigureApplicationContainer中注册它有什么不同?注册(typeof(JsonNetSerializer), typeof(CustomJsonNetSerializer))?

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

https://github.com/NancyFx/Nancy.Serialization.JsonNet定制

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

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

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

Q:我是否可以从您概述的方法中正确推断出我不再需要在我的CustomNancyBootstrapper的ConfigureApplicationContainer覆盖中显式地注册CustomJsonSerializer ?

A:我所做的注册方法只是注册依赖关系的一个更清晰的抽象,而不是创建一个巨大的Bootstrapper,您可以创建一些更小的特定类。

是,使用我的方法意味着你不需要在bootstrapper中注册

相关文章:
  • 没有找到相关文章