Closed xmedeko closed 7 years ago
You have all the same versions? The only difference is if you switch from 4.x to 4.6.1? Sounds weird...
Yes, all the same versions of .NET 4.6.1. No, there is no switch from any other .NET version.
You mean you haven't tested with a different version of .NET? It sounded like this was something that broke when switching to 4.6.1...
I also use LightInjectNancyBootstrapper
, may it be connected?
Yes, that may very well be connected. It's weird that it happens on only some machines, though :confused:
When I use the code from NancyInternalConfiguration
:
AppDomainAssemblyTypeScanner.TypesOf<ISerializer>(ScanMode.ExcludeNancy).Union(new List<Type>(new[] { typeof(Nancy.Responses.DefaultJsonSerializer), typeof(Nancy.Responses.DefaultXmlSerializer) })).ToList())
The I got the list:
JsonNetSerializer,DefaultJsonSerializer,DefaultXmlSerializer
So which code shuffles this list so as the formatter has
DefaultXmlSerializer,JsonNetSerializer,DefaultJsonSerializer,
?
Yes, the list you want is the first one, so that's correct. This is then passed to the bootstrapper, which registers the types in the container. My guess is that it's the container that shuffles things around.
FYI; for the Autofac bootstrapper, we use a method called PreserveExistingDefaults
(see this) to make sure the registrations stay in the "correct" order. Maybe this is where the LightInjectNancyBootstrapper
fails?
Hmm, IMHO it's not good to rely on the container order. If it uses HashSet
then the order is unpredictable - then you should register IEnumerable<IService>
with the container to be sure to get the same order or something like that.
I'll try to check if LightInject has something similar to Autofac later.
Hmm, IMHO it's not good to rely on the container order.
Well, it's one way to ensure the custom serializers are picked over the default ones. If you have a better way that would work across all bootstrappers, please let us know :wink:
Yep, there are several possible ways: register whole CollectionTypeRegistration
not the IService independently, or mark default with some IDefault
interface, or mark default with some DefaultAttribute
.
register whole
CollectionTypeRegistration
not the IService independently
What does this mean?
or mark default with some
IDefault
interface, or mark default with someDefaultAttribute
This is definitely possible, but how do you propose we use that interface or attribute?
About IDefault
and DefaultAttribute
: you can make the same logic as with DefaultStatusCodeHandler
.
The problems occurs on the 64bit machines, on 32bit machines it works. The workaround is:
protected override NancyInternalConfiguration InternalConfiguration
{
get
{
return NancyInternalConfiguration.WithOverrides(config =>
{
config.Serializers = new[] { typeof(DefaultXmlSerializer), typeof(JsonNetSerializer) };
});
}
}
This problem and the workaround should be documented, since it's hard to find.
All auto discoveries in Nancy are by nature not deterministic in order. It comes down to the order that the .NET type system picks things up. If you depend on the other, be explicit in the registration as shown by @xmedeko in this comment https://github.com/NancyFx/Nancy.Serialization.JsonNet/issues/36#issuecomment-206822301
@thecodejunkie what's the reason for closing this bug? The bug is in the NancyFX code, the FormatterExtensions.AsJson
is not working well together with Nancy.Serialization.JsonNet. Is there any change in the NancyFx code, which fixed that?
I have .NET 4.6.1, Nancy 1.4.3, Nancy.Serialization.JsonNet 1.4.1 and compile my project by VS 2015 C# 6.0. I use
FormatterExtensions.AsJson
to format the response. On some machines (I would call them MachinesA) theformatter.Serializers
iswhile on the other machines (MachinesB) the order is:
So the response is formatted by
DefaultJsonSerializer
and notJsonNetSerializer
. I cannot find, what's the difference between MachinesA and MachinesB. They all have .NET 4.6.1 installed, they have various OS (Win 10, Win 7, ...). My application is always the same - just copy of the folder.