问题
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>();
}
回答1:
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>
回答2:
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.
来源:https://stackoverflow.com/questions/33983600/why-can-i-not-register-a-custom-json-net-implementation-in-nancy