Endless loop somewhere

Topics: Web Api
Sep 21, 2011 at 8:41 PM

If I add a custom json formatter everything works fine locally, but when I try to deploy to a server anything that would go through that never returns. If I use the built in json formatter all is well. 

Anyone seen anything like this? 

Sep 21, 2011 at 11:52 PM

Do you have a code snippet showing what you are trying to do?

Henrik

From: jlindholm [email removed]
Sent: Wednesday, September 21, 2011 12:41 PM
To: Henrik Frystyk Nielsen
Subject: Endless loop somewhere [wcf:273368]

From: jlindholm

If I add a custom json formatter everything works fine locally, but when I try to deploy to a server anything that would go through that never returns. If I use the built in json formatter all is well.

Anyone seen anything like this?

Sep 22, 2011 at 1:25 PM
Edited Sep 22, 2011 at 1:26 PM

Sure here is the code to inject the formatter. In the formatter none of the logging methods are ever called, so it appears to never get there. Again it works 100% fine in a local environment, but in a server 2008 it fails. Both have the application pools configured the same, doing an xcopy deploy.

 

var hostConfig = new HttpConfiguration
{
	EnableHelpPage = true,
	EnableTestClient = true,
	IncludeExceptionDetail = true,
	MessageHandlerFactory = () => new System.Net.Http.DelegatingHandler[]
									{
										new FormattingHandler()
									},
	ErrorHandlers = (handlers, endpoint, descriptions) => handlers.Add(new ErrorHandler()),
	ResponseHandlers = (handlers, endpoint, operation) => handlers.Add(new ResponseHandler())
};

// comment out this line and everything works....
hostConfig.Formatters.Insert(0, new JsonNetProcessor());

RouteTable.Routes.Add(new ServiceRoute("Communications/v1", new HttpServiceHostFactory { Configuration = hostConfig }, typeof(RestAPI.Communications)));


Here is the code for the formatter itself.

   public class JsonNetProcessor : MediaTypeFormatter
    {
        public JsonNetProcessor()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/json"));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/bson")); 
        }
        private static JsonSerializerSettings _default;
        public static JsonSerializerSettings DefaultJsonSerializerSettings
        {
            get
            {
                if ( _default == null )
                {
                    _default = new JsonSerializerSettings
                    {
                        ConstructorHandling = ConstructorHandling.Default,
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                        NullValueHandling = NullValueHandling.Ignore,
                        MissingMemberHandling = MissingMemberHandling.Ignore,
                        DefaultValueHandling = DefaultValueHandling.Include,
                        ContractResolver = new CamelCasePropertyNamesContractResolver()
                    };
                    _default.Converters.Add(new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AdjustToUniversal });
                }
                return _default;
            }
        }

        private JsonSerializerSettings _settings;

        public virtual JsonSerializerSettings GetJsonSerializerSettings()
        {
            if (_settings == null)
            {
                _settings = DefaultJsonSerializerSettings;
            }
            return _settings;
        }

        protected override object OnReadFromStream(Type type, Stream stream, HttpContentHeaders contentHeaders)
        {
            var serializer = new JsonSerializer();
            JsonReader reader;

            if (contentHeaders.ContentType.MediaType == "application/bson")
            {
                reader = new BsonReader(stream);
            }
            else
            {
                reader = new JsonTextReader(new StreamReader(stream));
            }

            var result = serializer.Deserialize(reader, type);

            return result;
        }

        protected override void OnWriteToStream(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, System.Net.TransportContext context)
        {
            Utility.Logging.Log("OnWriteToStream");
            var serializer = JsonSerializer.Create(GetJsonSerializerSettings());
            JsonWriter writer;

            if (contentHeaders.ContentType.MediaType == "application/bson")
            {
                writer = new BsonWriter(stream);
            }
            else
            {
                writer = new JsonTextWriter(new StreamWriter(stream));
            }

            serializer.Serialize(writer, value);

            writer.Flush();
            Utility.Logging.Log("OnWriteToStream::End");
        }
    }


Sep 22, 2011 at 5:37 PM

Update:

Figured this out, it stemmed from someone on the team using a different NewtonSoft.Json.dll than the one I was developing with. Not exactly sure where the endless loop started, but at least I figured it out.