Custom serialization to JSON throws JsonWriterException

Feb 19, 2010 at 2:20 PM
Edited Feb 19, 2010 at 3:34 PM

Hello,

I am new to the Json.NET and need help on the following topic.

I have create 2 Converters, that inherit from JsonConverter, in order to provide a custom serialization for certain object types. However when trying to serialize the following error occurs:

Newtonsoft.Json.JsonWriterException : Token PropertyName in state Property would result in an invalid JavaScript object.

Here is a test case using NUnit so that you can test it easily

 

using System;
using NUnit.Framework;
using Newtonsoft.Json;

namespace Tests.Logic.JSON {
	[TestFixture]
	class ClientMapToJSONConverterTest {
		[Test]
		public void FullClientMapSerialization() {
			ClientMap source = new ClientMap() {
				position = new Pos() { X = 100, Y = 200 },
				center = new PosDouble() { X = 251.6, Y = 361.3 }
			};

			string json = JsonConvert.SerializeObject(source, new PosConverter(), new PosDoubleConverter());
			Assert.That(json, Is.EqualTo("{\"position\":new Pos(100,200),\"center\":new PosD(251.6,361.3)}")); 
		}

		
	}

	public class ClientMap {
		public Pos position { get; set; }
		public PosDouble center { get; set; }
	}

	public class Pos {
		public int X { get; set; }
		public int Y { get; set; }
	}

	public class PosDouble {
		public double X { get; set; }
		public double Y { get; set; }
	}

	#region Converters
	public class PosConverter : JsonConverter {

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
			Pos p = (Pos)value;

			if (p != null)
				writer.WriteRaw(String.Format("new Pos({0},{1})", p.X, p.Y));
			else
				writer.WriteNull();
		}

		public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer) {
			throw new NotImplementedException();
		}

		public override bool CanConvert(Type objectType) {
			return objectType.IsAssignableFrom(typeof(Pos));
		}
	}
	public class PosDoubleConverter : JsonConverter {

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
			PosDouble p = (PosDouble)value;

			if (p != null)
				writer.WriteRaw(String.Format("new PosD({0},{1})", p.X, p.Y));
			else
				writer.WriteNull();
		}

		public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer) {
			throw new NotImplementedException();
		}

		public override bool CanConvert(Type objectType) {
			return objectType.IsAssignableFrom(typeof(PosDouble));
		}
	}
	#endregion
}

 

Coordinator
Feb 20, 2010 at 6:51 AM

WriteRaw doesn't update the state of the writer. It is still expecting a value for the current property when you write the next property name, causing the error.

Use WriteRawValue.