4

I have the following installed:

  <package id="Nancy" version="1.4.2" targetFramework="net4" />
  <package id="Nancy.Owin" version="1.4.1" targetFramework="net4" />
  <package id="Nancy.Serialization.JsonNet" version="1.4.1" targetFramework="net4" />
  <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net4" />
  <package id="Owin" version="1.0" targetFramework="net4" />

And also:

public sealed class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var options = new NancyOptions();
        app.UseNancy(options);
    }
}

public sealed class CustomJsonNetSerializer : JsonSerializer
{
    public CustomJsonNetSerializer()
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver();
        DateFormatHandling = DateFormatHandling.IsoDateFormat;
        Formatting = Formatting.Indented;
    }
}

Then in my Bootstrapper:

protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
    base.ConfigureApplicationContainer(container);

    container.Register<JsonSerializer, CustomJsonNetSerializer>();
}

And finally in the route:

public sealed class ApiBase : NancyModule
{
    public ApiBase() : base("api/")
    {
        Get["user/"] = o => Response.AsJson(new { Context.CurrentUser, Time = DateTime.UtcNow});
    }
}

However when running this app, the CustomJsonNetSerializer is never instantiated, it looks like Nancy is using a different implementation possibly the ISerializer.

Please note I want to know why this solution is failing as I am following the official doc rather than doing other implementation i.e implementing an ISerializer.

Any idea?

[Update] I could not figure out what was wrong so I ended up with:

public sealed class CustomJsonNetSerializer : JsonSerializer, ISerializer
{
    public CustomJsonNetSerializer()
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver();
        DateFormatHandling = DateFormatHandling.IsoDateFormat;
        Formatting = Formatting.None;
    }

    public bool CanSerialize(string contentType)
    {
        return contentType.Equals("application/json", StringComparison.OrdinalIgnoreCase);
    }

    public void Serialize<TModel>(string contentType, TModel model, Stream outputStream)
    {
        using (var streamWriter = new StreamWriter(outputStream))
        using(var jsonWriter = new JsonTextWriter(streamWriter))
        {
            Serialize(jsonWriter, model);
        }
    }

    public IEnumerable<string> Extensions { get { yield return "json"; } }
}

And:

protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
    base.ConfigureApplicationContainer(container);

    container.Register<ISerializer, CustomJsonNetSerializer>();
}
MaYaN
  • 6,683
  • 12
  • 57
  • 109
  • http://stackoverflow.com/questions/23352833/how-to-get-a-response-from-the-nancy-negotiator refer this, you can use Negotiaer return type or return with negotiate () – Gomes Feb 26 '16 at 16:00
  • Addendum: Also see related SO question https://stackoverflow.com/questions/24873171 – Yogi Nov 17 '17 at 16:02
  • 1
    The updated code above worked for me. – Byron Wall Oct 16 '18 at 16:43

2 Answers2

2

Why do you think that your custom serializer is not used?

I can see that breakpoint set to the CustomJsonNetSerializer is hit.

The response contains correctly formatted JSON file:

{
  "currentUser": null,
  "time": "2015-11-29T15:01:55.4669533Z"
}

If I change the DateFormatHandling to

DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;

the change will be reflected as expected:

{
  "currentUser": null,
  "time": "\/Date(1448809002853)\/"
}

Could you make sure that your application is configured correctly:

You have Startup class in the root namespace of your application (is it OWIN?). Annotate Startup class with OwinStartup annotation. Something like:

[assembly:OwinStartup(typeof(WebApplication3.Startup))]

public class Startup
{
            public void Configuration(IAppBuilder app)
            {
                app.UseNancy();
            }
}

You have only one Bootstrapper

public class Bootstrapper : DefaultNancyBootstrapper
    {
        protected override void ConfigureApplicationContainer(TinyIoCContainer container)
        {
            base.ConfigureApplicationContainer(container);

            container.Register<JsonSerializer, CustomJsonNetSerializer>();
        }
    }

Verify all the package's versions:

<packages>
  <package id="Microsoft.Owin" version="2.1.0" targetFramework="net4" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="2.1.0" targetFramework="net4" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net4" />
  <package id="Nancy" version="1.4.2" targetFramework="net4" />
  <package id="Nancy.Owin" version="1.4.1" targetFramework="net4" />
  <package id="Nancy.Serialization.JsonNet" version="1.4.1" targetFramework="net4" />
  <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net4" />
  <package id="Owin" version="1.0" targetFramework="net4" />
</packages>
Anton Sizikov
  • 9,105
  • 1
  • 28
  • 39
0

I'm running into the same problem, basically it seems that the CustomSerializer is registered BUT the response.AsJson it is not using it. I add the registered serializer on the contructor in the module and if I manually Serialize the object and send a AsText response it will work. Can it be that the problem is that method AsJson is not using the custom serializer?

So, in the bootstrap I'm do as you

    protected override void ConfigureApplicationContainer(Nancy.TinyIoc.TinyIoCContainer container)
    {
        base.ConfigureApplicationContainer(container);
        container.Register<System.Web.Script.Serialization.JavaScriptSerializer>(CustomJsonSerializer);
    }

But then in the module

public class SimpleModule : Nancy.NancyModule
{
        Get["/State/"] = parameters =>
        {
            string Json = TheSerializer.Serialize(myobject);
            return Response.AsText(Json);
            // return Response.AsJson(myobject);
        };        
}

Switching that comments on the response will end up in 2 different JSON responses. A wrong one when using AsJson method.

OscarSanhueza
  • 317
  • 2
  • 13