我是Nancy的菜鸟。我一直将其用作生成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))中注册它有什么不同?

答:如果Nancy是json.net,则JsonSerializer是实现,这是我们在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。

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

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

10-10 07:59