c# - 使用 Nancy TinyIoC 配置 JsonNetSerializer 和 JsonNetBodyDeserializer

标签 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 } );

我想使用内置的 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(我使用的是自托管包,所以这发生在 program.cs 中——using(var host = new NancyHost(uri)))。

看来我要么需要告诉 Nancy 不要做某事,要么我需要连接到链中的后面部分。

如有任何帮助,我们将不胜感激。

最佳答案

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

问: 这种方法与创建继承自 JsonNetSerializer 的 CustomJsonNetSerializer 然后将其注册到 ConfigureApplicationContainer (container.Register( typeof(JsonNetSerializer), typeof(CustomJsonNetSerializer) ) 有何不同?

答: JsonSerializer是json.net对Nancy的实现,这是我们在github的readme中定义的推荐方法:

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,您可以创建一些更小的特定类。

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

关于c# - 使用 Nancy TinyIoC 配置 JsonNetSerializer 和 JsonNetBodyDeserializer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24873171/

相关文章:

c# - 选择表的列名和类型

json - 在 JsonSchema 中,格式值应设置为 "full-date"或 "date"?

c# - 使用Newtonsoft如何避免 ":"后的tailing space空间

json - 如何在 ASP.NET 中将 JSON 反序列化为简单的 Dictionary<string,string>?

session-cookies - 负载平衡 Web 服务器上的 nancyfx session

c# - 无法反序列化惰性对象

c# - 哪个控件可以用来表示一个对象?

c# - 使用 Moq 验证具有不同参数的单独调用

c# - Nancy 模块自动发现在 ILMerge 后不起作用

c# - 不完整的视频流式传输到移动浏览器 - HTTP header