From fb2a5998bc2e85bde77ab157c5d30eb4791d809f Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sat, 25 Feb 2012 16:44:07 +1300 Subject: [PATCH] -Added Path to JsonReaderException, JsonSchemaException and ValidationEventArgs -Fixed Path on JsonValidatingReader -Fixed path queries over constructors --- .../JsonValidatingReaderTests.cs | 36 ++++++++++++++----- Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs | 35 ++++++++++++++++-- .../Properties/AssemblyInfo.cs | 2 +- .../Schema/ExtensionsTests.cs | 5 +-- .../Schema/JsonSchemaTests.cs | 1 + .../Serialization/JsonSerializerTest.cs | 26 +++++++------- Src/Newtonsoft.Json/JsonReader.cs | 22 ++++++------ Src/Newtonsoft.Json/JsonReaderException.cs | 9 ++++- Src/Newtonsoft.Json/JsonValidatingReader.cs | 10 +++++- Src/Newtonsoft.Json/Linq/JPath.cs | 13 +++++++ .../Properties/AssemblyInfo.cs | 2 +- .../Schema/JsonSchemaException.cs | 9 ++++- .../Schema/ValidationEventArgs.cs | 15 ++++++-- .../Serialization/ErrorContext.cs | 4 +-- 14 files changed, 142 insertions(+), 47 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs b/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs index c2729960..b8950d72 100644 --- a/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs +++ b/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs @@ -50,16 +50,17 @@ namespace Newtonsoft.Json.Tests JsonSchema schema = JsonSchema.Parse(schemaJson); reader.Schema = schema; Assert.AreEqual(schema, reader.Schema); - Assert.AreEqual(0, reader.Depth); + Assert.AreEqual("", reader.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.AreEqual("", reader.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); Assert.AreEqual("name", reader.Value.ToString()); - + Assert.AreEqual("name", reader.Path); Assert.AreEqual(1, reader.Depth); Assert.IsTrue(reader.Read()); @@ -67,30 +68,39 @@ namespace Newtonsoft.Json.Tests Assert.AreEqual("James", reader.Value.ToString()); Assert.AreEqual(typeof (string), reader.ValueType); Assert.AreEqual('"', reader.QuoteChar); + Assert.AreEqual("name", reader.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); Assert.AreEqual("hobbies", reader.Value.ToString()); Assert.AreEqual('\'', reader.QuoteChar); + Assert.AreEqual("hobbies", reader.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.AreEqual("hobbies", reader.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.String, reader.TokenType); Assert.AreEqual("pie", reader.Value.ToString()); Assert.AreEqual('"', reader.QuoteChar); + Assert.AreEqual("hobbies[0]", reader.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.String, reader.TokenType); Assert.AreEqual("cake", reader.Value.ToString()); + Assert.AreEqual("hobbies[1]", reader.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.AreEqual("hobbies", reader.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.AreEqual("", reader.Path); + Assert.IsFalse(reader.Read()); + Assert.IsNull(validationEventArgs); } @@ -248,6 +258,7 @@ namespace Newtonsoft.Json.Tests Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.String, reader.TokenType); Assert.AreEqual(@"Value ""THREE"" is not defined in enum. Line 1, position 20.", validationEventArgs.Message); + Assert.AreEqual("[2]", validationEventArgs.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.EndArray, reader.TokenType); @@ -274,6 +285,7 @@ namespace Newtonsoft.Json.Tests Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.String, reader.TokenType); Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' does not match regex pattern 'foo'. Line 1, position 46.", validationEventArgs.Message); + Assert.AreEqual("", validationEventArgs.Path); Assert.IsNotNull(validationEventArgs); } @@ -297,6 +309,7 @@ namespace Newtonsoft.Json.Tests Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.Integer, reader.TokenType); Assert.AreEqual("Integer 10 exceeds maximum value of 5. Line 1, position 2.", validationEventArgs.Message); + Assert.AreEqual("", validationEventArgs.Path); Assert.IsNotNull(validationEventArgs); } @@ -372,6 +385,7 @@ namespace Newtonsoft.Json.Tests Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.Integer, reader.TokenType); Assert.AreEqual(@"Value 3 is not defined in enum. Line 1, position 6.", validationEventArgs.Message); + Assert.AreEqual("[2]", validationEventArgs.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.EndArray, reader.TokenType); @@ -458,6 +472,7 @@ namespace Newtonsoft.Json.Tests Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.Float, reader.TokenType); Assert.AreEqual(@"Value 3.0 is not defined in enum. Line 1, position 12.", validationEventArgs.Message); + Assert.AreEqual("[2]", validationEventArgs.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.EndArray, reader.TokenType); @@ -497,6 +512,7 @@ namespace Newtonsoft.Json.Tests Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.Float, reader.TokenType); Assert.AreEqual(@"Float 4.001 is not evenly divisible by 0.1. Line 1, position 14.", validationEventArgs.Message); + Assert.AreEqual("[2]", validationEventArgs.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.EndArray, reader.TokenType); @@ -560,6 +576,7 @@ namespace Newtonsoft.Json.Tests Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.Null, reader.TokenType); Assert.AreEqual(@"Value null is not defined in enum. Line 1, position 5.", validationEventArgs.Message); + Assert.AreEqual("[0]", validationEventArgs.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.EndArray, reader.TokenType); @@ -597,6 +614,7 @@ namespace Newtonsoft.Json.Tests Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.Boolean, reader.TokenType); Assert.AreEqual(@"Value false is not defined in enum. Line 1, position 11.", validationEventArgs.Message); + Assert.AreEqual("[1]", validationEventArgs.Path); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.EndArray, reader.TokenType); @@ -768,6 +786,7 @@ namespace Newtonsoft.Json.Tests Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.EndObject, reader.TokenType); Assert.AreEqual("Required properties are missing from object: hobbies, age. Line 1, position 16.", validationEventArgs.Message); + Assert.AreEqual("", validationEventArgs.Path); Assert.IsNotNull(validationEventArgs); } @@ -1182,7 +1201,7 @@ namespace Newtonsoft.Json.Tests reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; - errors.Add(validationEventArgs.Message); + errors.Add(validationEventArgs.Path + " - " + validationEventArgs.Message); }; reader.Schema = secondSchema; @@ -1206,7 +1225,7 @@ namespace Newtonsoft.Json.Tests Assert.AreEqual(JsonToken.String, reader.TokenType); Assert.AreEqual("secasecasecasecaseca", reader.Value.ToString()); Assert.AreEqual(1, errors.Count); - Assert.AreEqual("String 'secasecasecasecaseca' exceeds maximum length of 10. Line 3, position 42.", errors[0]); + Assert.AreEqual("secondproperty - String 'secasecasecasecaseca' exceeds maximum length of 10. Line 3, position 42.", errors[0]); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); @@ -1226,9 +1245,9 @@ namespace Newtonsoft.Json.Tests Assert.AreEqual(JsonToken.String, reader.TokenType); Assert.AreEqual("aaa", reader.Value.ToString()); Assert.AreEqual(4, errors.Count); - Assert.AreEqual("String 'aaa' is less than minimum length of 7. Line 5, position 40.", errors[1]); - Assert.AreEqual("String 'aaa' does not match regex pattern 'hi'. Line 5, position 40.", errors[2]); - Assert.AreEqual("String 'aaa' does not match regex pattern 'hi2u'. Line 5, position 40.", errors[3]); + Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' is less than minimum length of 7. Line 5, position 40.", errors[1]); + Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' does not match regex pattern 'hi'. Line 5, position 40.", errors[2]); + Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' does not match regex pattern 'hi2u'. Line 5, position 40.", errors[3]); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); @@ -1239,7 +1258,7 @@ namespace Newtonsoft.Json.Tests Assert.AreEqual(JsonToken.String, reader.TokenType); Assert.AreEqual("three", reader.Value.ToString()); Assert.AreEqual(5, errors.Count); - Assert.AreEqual("String 'three' is less than minimum length of 6. Line 6, position 25.", errors[4]); + Assert.AreEqual("thirdproperty.additional - String 'three' is less than minimum length of 6. Line 6, position 25.", errors[4]); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.EndObject, reader.TokenType); @@ -1487,6 +1506,7 @@ namespace Newtonsoft.Json.Tests reader.ReadAsInt32(); Assert.AreEqual(JsonToken.EndArray, reader.TokenType); Assert.AreEqual("Array item count 2 exceeds maximum count of 1. Line 1, position 5.", validationEventArgs.Message); + Assert.AreEqual("", validationEventArgs.Path); } [Test] diff --git a/Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs index 1d699a59..08031bed 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs @@ -181,8 +181,8 @@ namespace Newtonsoft.Json.Tests.Linq } [Test] - [ExpectedException(typeof(Exception), ExpectedMessage = @"Index 1 not valid on JConstructor.")] - public void EvaluateIndexerOnConstructorWithError() + [ExpectedException(typeof(IndexOutOfRangeException), ExpectedMessage = @"Index 1 outside the bounds of JConstructor.")] + public void EvaluateConstructorOutOfBoundsIndxerWithError() { JConstructor c = new JConstructor("Blah"); @@ -210,7 +210,7 @@ namespace Newtonsoft.Json.Tests.Linq [Test] [ExpectedException(typeof(IndexOutOfRangeException), ExpectedMessage = "Index 1000 outside the bounds of JArray.")] - public void EvaluateOutOfBoundsIndxerWithError() + public void EvaluateArrayOutOfBoundsIndxerWithError() { JArray a = new JArray(1, 2, 3, 4, 5); @@ -252,6 +252,35 @@ namespace Newtonsoft.Json.Tests.Linq Assert.AreEqual("Jeff", a2); } + [Test] + public void PathWithConstructor() + { + JArray a = JArray.Parse(@"[ + { + ""Property1"": [ + 1, + [ + [ + [] + ] + ] + ] + }, + { + ""Property2"": new Constructor1( + null, + [ + 1 + ] + ) + } +]"); + + JValue v = (JValue)a.SelectToken("[1].Property2[1][0]"); + Assert.AreEqual(1, v.Value); + } + + [Test] public void Example() { diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index f34065ed..4a503e7a 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -72,5 +72,5 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.0.8.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.0.8.14623")] +[assembly: AssemblyFileVersion("4.0.8.14625")] #endif diff --git a/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs b/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs index 99f3a5b3..36e042ab 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs @@ -113,9 +113,10 @@ namespace Newtonsoft.Json.Tests.Schema JObject o = JObject.Parse("{'lol':1}"); List errors = new List(); - o.Validate(schema, (sender, args) => errors.Add(args.Message)); + o.Validate(schema, (sender, args) => errors.Add(args.Path + " - " + args.Message)); - Assert.AreEqual("Invalid type. Expected String but got Integer. Line 1, position 8.", errors[0]); + Assert.AreEqual("lol - Invalid type. Expected String but got Integer. Line 1, position 8.", errors[0]); + Assert.AreEqual("1", o.SelectToken("lol").ToString()); Assert.AreEqual(1, errors.Count); } diff --git a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaTests.cs b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaTests.cs index 0e31a1eb..959560b1 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaTests.cs @@ -113,6 +113,7 @@ namespace Newtonsoft.Json.Tests.Schema } }", writtenJson); } + [Test] public void WriteTo_AdditionalProperties() { diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index 015fac8a..39b31037 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -5180,7 +5180,7 @@ keyword such as type of business."" } [Test] - [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Unexpected end when setting PreProperty's value. Line 2, position 18.")] + [ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "Unexpected end when setting PreProperty's value. Line 2, position 18.")] public void DeserializeUnexpectedEndInt() { string json = @"{ @@ -5263,10 +5263,10 @@ keyword such as type of business."" Assert.AreEqual(null, e.NullableEnum); json = JsonConvert.SerializeObject(new WithEnums - { - Id = 7, - NullableEnum = MyEnum.Value2 - }); + { + Id = 7, + NullableEnum = MyEnum.Value2 + }); Assert.AreEqual(@"{""Id"":7,""NullableEnum"":1}", json); @@ -5278,13 +5278,13 @@ keyword such as type of business."" [Test] public void NullableStructWithConverter() { - string json = JsonConvert.SerializeObject(new Widget1 { Id = new WidgetId1 { Value = 1234 } }); + string json = JsonConvert.SerializeObject(new Widget1 {Id = new WidgetId1 {Value = 1234}}); Assert.AreEqual(@"{""Id"":""1234""}", json); Widget1 w = JsonConvert.DeserializeObject(@"{""Id"":""1234""}"); - Assert.AreEqual(new WidgetId1 { Value = 1234 }, w.Id); + Assert.AreEqual(new WidgetId1 {Value = 1234}, w.Id); } [Test] @@ -5330,21 +5330,21 @@ keyword such as type of business."" } [Test] - [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "No JSON content found and type 'System.Double' is not nullable.")] + [ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "No JSON content found and type 'System.Double' is not nullable.")] public void DeserializeDoubleFromEmptyString() { JsonConvert.DeserializeObject(""); } [Test] - [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "No JSON content found and type 'System.StringComparison' is not nullable.")] + [ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "No JSON content found and type 'System.StringComparison' is not nullable.")] public void DeserializeEnumFromEmptyString() { JsonConvert.DeserializeObject(""); } [Test] - [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "No JSON content found and type 'System.Int32' is not nullable.")] + [ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "No JSON content found and type 'System.Int32' is not nullable.")] public void DeserializeInt32FromEmptyString() { JsonConvert.DeserializeObject(""); @@ -5358,7 +5358,7 @@ keyword such as type of business."" } [Test] - [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null. + [ExpectedException(typeof (ArgumentNullException), ExpectedMessage = @"Value cannot be null. Parameter name: value")] public void DeserializeDoubleFromNullString() { @@ -5366,12 +5366,12 @@ Parameter name: value")] } [Test] - [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null. + [ExpectedException(typeof (ArgumentNullException), ExpectedMessage = @"Value cannot be null. Parameter name: value")] public void DeserializeFromNullString() { JsonConvert.DeserializeObject(null); - } + } } public class Widget1 diff --git a/Src/Newtonsoft.Json/JsonReader.cs b/Src/Newtonsoft.Json/JsonReader.cs index edcc9895..691ac82d 100644 --- a/Src/Newtonsoft.Json/JsonReader.cs +++ b/Src/Newtonsoft.Json/JsonReader.cs @@ -241,19 +241,10 @@ namespace Newtonsoft.Json } } - /// - /// Gets or sets the culture used when reading JSON. Defaults to . - /// - public CultureInfo Culture - { - get { return _culture ?? CultureInfo.InvariantCulture; } - set { _culture = value; } - } - /// /// Gets the path of the current JSON token. /// - public string Path + public virtual string Path { get { @@ -264,6 +255,15 @@ namespace Newtonsoft.Json } } + /// + /// Gets or sets the culture used when reading JSON. Defaults to . + /// + public CultureInfo Culture + { + get { return _culture ?? CultureInfo.InvariantCulture; } + set { _culture = value; } + } + /// /// Initializes a new instance of the class with the specified . /// @@ -596,7 +596,7 @@ namespace Newtonsoft.Json linePosition = 0; } - return new JsonReaderException(message, ex, lineNumber, linePosition); + return new JsonReaderException(message, ex, Path, lineNumber, linePosition); } internal static string FormatExceptionMessage(IJsonLineInfo lineInfo, string message) diff --git a/Src/Newtonsoft.Json/JsonReaderException.cs b/Src/Newtonsoft.Json/JsonReaderException.cs index 4ea4a8df..e10f39a4 100644 --- a/Src/Newtonsoft.Json/JsonReaderException.cs +++ b/Src/Newtonsoft.Json/JsonReaderException.cs @@ -49,6 +49,12 @@ namespace Newtonsoft.Json /// The line position indicating where the error occurred. public int LinePosition { get; private set; } + /// + /// Gets the path to the JSON where the error occurred. + /// + /// The path to the JSON where the error occurred. + public string Path { get; private set; } + /// /// Initializes a new instance of the class. /// @@ -91,9 +97,10 @@ namespace Newtonsoft.Json } #endif - internal JsonReaderException(string message, Exception innerException, int lineNumber, int linePosition) + internal JsonReaderException(string message, Exception innerException, string path, int lineNumber, int linePosition) : base(message, innerException) { + Path = path; LineNumber = lineNumber; LinePosition = linePosition; } diff --git a/Src/Newtonsoft.Json/JsonValidatingReader.cs b/Src/Newtonsoft.Json/JsonValidatingReader.cs index 8c60fd80..15c5ff42 100644 --- a/Src/Newtonsoft.Json/JsonValidatingReader.cs +++ b/Src/Newtonsoft.Json/JsonValidatingReader.cs @@ -111,6 +111,14 @@ namespace Newtonsoft.Json get { return _reader.Depth; } } + /// + /// Gets the path of the current JSON token. + /// + public override string Path + { + get { return _reader.Path; } + } + /// /// Gets the quotation mark character used to enclose the value of a string. /// @@ -246,7 +254,7 @@ namespace Newtonsoft.Json ? message + " Line {0}, position {1}.".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition) : message; - OnValidationEvent(new JsonSchemaException(exceptionMessage, null, lineInfo.LineNumber, lineInfo.LinePosition)); + OnValidationEvent(new JsonSchemaException(exceptionMessage, null, Path, lineInfo.LineNumber, lineInfo.LinePosition)); } private void OnValidationEvent(JsonSchemaException exception) diff --git a/Src/Newtonsoft.Json/Linq/JPath.cs b/Src/Newtonsoft.Json/Linq/JPath.cs index c0279b90..d110bbc3 100644 --- a/Src/Newtonsoft.Json/Linq/JPath.cs +++ b/Src/Newtonsoft.Json/Linq/JPath.cs @@ -141,6 +141,7 @@ namespace Newtonsoft.Json.Linq int index = (int) part; JArray a = current as JArray; + JConstructor c = current as JConstructor; if (a != null) { @@ -154,6 +155,18 @@ namespace Newtonsoft.Json.Linq current = a[index]; } + else if (c != null) + { + if (c.Count <= index) + { + if (errorWhenNoMatch) + throw new IndexOutOfRangeException("Index {0} outside the bounds of JConstructor.".FormatWith(CultureInfo.InvariantCulture, index)); + + return null; + } + + current = c[index]; + } else { if (errorWhenNoMatch) diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index b1bc331c..0e73afb0 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -85,7 +85,7 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.0.8.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.0.8.14623")] +[assembly: AssemblyFileVersion("4.0.8.14625")] #endif [assembly: CLSCompliant(true)] diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs index 86d29243..5699d38e 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs @@ -49,6 +49,12 @@ namespace Newtonsoft.Json.Schema /// The line position indicating where the error occurred. public int LinePosition { get; private set; } + /// + /// Gets the path to the JSON where the error occurred. + /// + /// The path to the JSON where the error occurred. + public string Path { get; private set; } + /// /// Initializes a new instance of the class. /// @@ -91,9 +97,10 @@ namespace Newtonsoft.Json.Schema } #endif - internal JsonSchemaException(string message, Exception innerException, int lineNumber, int linePosition) + internal JsonSchemaException(string message, Exception innerException, string path, int lineNumber, int linePosition) : base(message, innerException) { + Path = path; LineNumber = lineNumber; LinePosition = linePosition; } diff --git a/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs b/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs index 3b2b107a..77169bc0 100644 --- a/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs +++ b/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs @@ -42,16 +42,25 @@ namespace Newtonsoft.Json.Schema } /// - /// Gets the associated with the validation event. + /// Gets the associated with the validation error. /// - /// The JsonSchemaException associated with the validation event. + /// The JsonSchemaException associated with the validation error. public JsonSchemaException Exception { get { return _ex; } } /// - /// Gets the text description corresponding to the validation event. + /// Gets the path of the JSON location where the validation error occurred. + /// + /// The path of the JSON location where the validation error occurred. + public string Path + { + get { return _ex.Path; } + } + + /// + /// Gets the text description corresponding to the validation error. /// /// The text description. public string Message diff --git a/Src/Newtonsoft.Json/Serialization/ErrorContext.cs b/Src/Newtonsoft.Json/Serialization/ErrorContext.cs index 28f7ad5c..75cc87b2 100644 --- a/Src/Newtonsoft.Json/Serialization/ErrorContext.cs +++ b/Src/Newtonsoft.Json/Serialization/ErrorContext.cs @@ -59,9 +59,9 @@ namespace Newtonsoft.Json.Serialization /// The member that caused the error. public object Member { get; private set; } /// - /// Gets the path of the JSON location when the error occurred. + /// Gets the path of the JSON location where the error occurred. /// - /// The path of the JSON location when the error occurred. + /// The path of the JSON location where the error occurred. public string Path { get; private set; } /// /// Gets or sets a value indicating whether this is handled.