Пример #1
0
        /// <summary>
        /// Deserializes the payload using the JsonParser, then converts the resulting clr objects into payload element form
        /// Throws an TaupoInvalidOperationException if the json does not evaluate successfully.
        /// </summary>
        /// <param name="serialized">A raw json payload</param>
        /// <param name="payloadContext">Additional payload information to aid deserialization</param>
        /// <returns>A PayloadElement representation of the payload</returns>
        public ODataPayloadElement DeserializeFromBinary(byte[] serialized, ODataPayloadContext payloadContext)
        {
            ExceptionUtilities.CheckArgumentNotNull(serialized, "serialized");
            ExceptionUtilities.CheckArgumentNotNull(payloadContext, "payloadContext");

            string encodingName = payloadContext.EncodingName;

            ODataPayloadElement errorPayload = null;
            if (this.payloadErrorDeserializer.TryDeserializeErrorPayload(serialized, encodingName, out errorPayload))
            {
                return errorPayload;
            }

            // Evaluate the given JSON text
            Encoding encoding = HttpUtilities.GetEncodingOrDefault(encodingName);
            string payload = encoding.GetString(serialized, 0, serialized.Length);

            JsonValue jsonData = null;
            using (StringReader reader = new StringReader(payload))
            {
                JsonTokenizer tokenizer = new JsonTokenizer(reader);
                JsonParser parser = new JsonParser(tokenizer);
                jsonData = parser.ParseValue();
            }

            // convert the deserialized JsonValue objects into payload elements
            return this.payloadConverter.ConvertToPayloadElement(jsonData);
        }
        /// <summary>
        /// Deserializes given HTTP payload as a json error payload or returns false
        /// </summary>
        /// <param name="serialized">The payload that was sent over HTTP</param>
        /// <param name="encodingName">Optional name of an encoding to use if it is relevant to the current format. May be null if no character-set information was known.</param>
        /// <param name="errorPayload">Error payload that is found</param>
        /// <returns>True if it finds and error, false if not</returns>
        public bool TryDeserializeErrorPayload(byte[] serialized, string encodingName, out ODataPayloadElement errorPayload)
        {
            ExceptionUtilities.CheckArgumentNotNull(serialized, "serialized");
            errorPayload = null;

            Encoding encoding = HttpUtilities.GetEncodingOrDefault(encodingName);
            string payload = encoding.GetString(serialized, 0, serialized.Length);
            
            // sample json error
            // {
            //   “error”: {
            //     “code”: <string>
            //     “message”: {
            //       “lang”: <string>,
            //       “value“: <string>
            //     },
            //     “innererror”: {
            //       “message”: <string>,
            //       “type”: <string>,
            //       “stacktrace”: <string>,
            //       “internalexception”: {
            //         … another inner error structure …
            //       }
            //     }
            //   }
            // }
            string errorName = "\"" + ODataConstants.ErrorElementName + "\":";
            int errorElementPos = payload.IndexOf(errorName, StringComparison.Ordinal);

            // Look in the payload and see if an error exists
            if (errorElementPos > -1)
            {
                ODataErrorPayload topLevelError = new ODataErrorPayload();
                errorPayload = topLevelError;
                ODataInternalExceptionPayload innerError = null;
                bool inTopLevelMessage = false;
                bool inError = false;

                using (StringReader reader = new StringReader(payload.Substring(errorElementPos)))
                {
                    JsonTokenizer tokenizer = new JsonTokenizer(reader);
                    
                    while (tokenizer.HasMoreTokens())
                    {
                        if (tokenizer.TokenType == JsonTokenType.String)
                        {
                            string tokenValue = null;
                            if (tokenizer != null)
                            {
                                tokenValue = tokenizer.Value.ToString();
                            }

                            // don't start processing other properties until we're definitely inside the error itself
                            if (!inError)
                            {
                                inError = tokenValue == ODataConstants.ErrorElementName;
                            }
                            else
                            {
                                if (tokenValue == ODataConstants.InnerErrorElementName)
                                {
                                    this.Assert.IsNull(innerError, "Should not find 'innererror' property on inner errors");
                                    topLevelError.InnerError = innerError = new ODataInternalExceptionPayload();
                                }
                                else if (tokenValue == ODataConstants.InternalExceptionElementName)
                                {
                                    this.Assert.IsNotNull(innerError, "Should not find 'internalexception' property on top-level errors");
                                    ExceptionUtilities.Assert(innerError.InternalException == null, "Inner error should have been null");
                                    innerError.InternalException = new ODataInternalExceptionPayload();
                                    innerError = innerError.InternalException;
                                }
                                else if (tokenValue == ODataConstants.MessageElementName)
                                {
                                    if (innerError == null)
                                    {
                                        inTopLevelMessage = true;
                                    }
                                    else
                                    {
                                        innerError.Message = this.GetIdentifierValue(tokenizer);
                                    }
                                }
                                else if (tokenValue == ODataConstants.ValueElementName)
                                {
                                    this.Assert.IsTrue(inTopLevelMessage, "Should not find 'value' property outside top-level message");
                                    this.Assert.IsNull(innerError, "Should not find 'value' property on inner errors");
                                    topLevelError.Message = this.GetIdentifierValue(tokenizer);
                                }
                                else if (tokenValue == ODataConstants.CodeElementName)
                                {
                                    this.Assert.IsNull(innerError, "Should not find 'code' property on inner errors");
                                    topLevelError.Code = this.GetIdentifierValue(tokenizer);
                                }
                                else if (tokenValue == ODataConstants.TypeNameElementName)
                                {
                                    this.Assert.IsNotNull(innerError, "Should not find 'type' on top-level errors");
                                    innerError.TypeName = this.GetIdentifierValue(tokenizer);
                                }
                                else if (tokenValue == ODataConstants.StackTraceElementName)
                                {
                                    this.Assert.IsNotNull(innerError, "Should not find 'stacktrace' on top-level errors");
                                    innerError.StackTrace = this.GetIdentifierValue(tokenizer);
                                }
                            }
                        }
                        else if (tokenizer.TokenType == JsonTokenType.RightCurly)
                        {
                            inTopLevelMessage = false;
                        }

                        tokenizer.GetNextToken();
                    }
                }

                return true;
            }

            return false;
        }
        private string GetIdentifierValue(JsonTokenizer tokenizer)
        {
            tokenizer.GetNextToken();
            ExceptionUtilities.Assert(tokenizer.TokenType == JsonTokenType.Colon, "Error parsing JSON Error: Expected colon token next");

            tokenizer.GetNextToken();
            ExceptionUtilities.Assert(tokenizer.TokenType == JsonTokenType.String, "Error parsing JSON Error: Expected string token next");

            ExceptionUtilities.CheckObjectNotNull(tokenizer.Value, "Expected tokenizer to have a value and not be null");
            return tokenizer.Value.ToString();
        }
 /// <summary>
 /// Parses the specified text reader content into a <see cref="JsonValue"/>
 /// </summary>
 /// <param name="reader">The reader to read.</param>
 /// <returns>The <see cref="JsonValue"/> read from the reader.</returns>
 public static JsonValue ParseValue(TextReader reader)
 {
     var tokenizer = new JsonTokenizer(reader);
     var parser = new JsonTextPreservingParser(tokenizer);
     return parser.ParseValueOrProperty();
 }
 /// <summary>
 /// Initializes a new instance of the JsonParser class
 /// </summary>
 /// <param name="tokenizer">An instance of <see cref="JsonTokenizer"/></param>
 public JsonTextPreservingParser(JsonTokenizer tokenizer)
 {
     ExceptionUtilities.CheckArgumentNotNull(tokenizer, "tokenizer");
     this.tokenizer = tokenizer;
 }
Пример #6
0
            public override ODataPayloadElement Visit(PrimitiveValue payloadElement)
            {
                var rawText = payloadElement.Annotations.OfType<RawTextPayloadElementRepresentationAnnotation>().Select(r => r.Text).SingleOrDefault();
                var dataType = payloadElement.Annotations.OfType<DataTypeAnnotation>().Select(d => d.DataType).OfType<PrimitiveDataType>().SingleOrDefault();
                if (rawText != null && dataType != null)
                {
                    using (var reader = new StringReader(rawText))
                    {
                        var tokenizer = new JsonTokenizer(reader);
                        var parsed = tokenizer.Value;

                        if (tokenizer.TokenType == JsonTokenType.String)
                        {
                            var clrType = dataType.GetFacetValue<PrimitiveClrTypeFacet, Type>(null);
                            if (this.converter.TryConvertFromString((string)parsed, clrType, out parsed))
                            {
                                return payloadElement.ReplaceWith(new PrimitiveValue(payloadElement.FullTypeName, parsed));
                            }
                        }
                    }
                }

                return base.Visit(payloadElement);
            }
Пример #7
0
 /// <summary>
 /// Initializes a new instance of the JsonParser class
 /// </summary>
 /// <param name="tokenizer">An instance of <see cref="JsonTokenizer"/></param>
 public JsonParser(JsonTokenizer tokenizer)
 {
     ExceptionUtilities.CheckArgumentNotNull(tokenizer, "tokenizer");
     this.tokenizer = tokenizer;
 }