Example #1
0
        internal async Task WriteErrorResponseAsync(HttpContext httpContext, ODataException oe)
        {
            var error = new Error
            {
                Code          = string.IsNullOrEmpty(oe.ErrorCode) ? Enum.GetName(typeof(ODataExceptionCode), oe.ODataExceptionCode) : oe.ErrorCode,
                ExceptionType = oe.InnerException?.GetType().Name ?? oe.GetType().Name,
                Message       = new ErrorMessage
                {
                    Lang  = System.Globalization.CultureInfo.CurrentUICulture.Name.ToLower(),
                    Value = SNSR.GetString(oe.Message).Replace(Environment.NewLine, "\\n").Replace('"', ' ').Replace('\'', ' ').Replace(" \\ ", " ")
                },
                InnerError =
#if DEBUG
                    new StackInfo
                {
                    Trace = Utility.CollectExceptionMessages(oe)
                }
#else
                    null
#endif
            };

            httpContext.Response.ContentType = "application/json";
            httpContext.Response.StatusCode  = oe.HttpStatusCode;
            await WriteErrorAsync(httpContext, error).ConfigureAwait(false);
        }
        private static void ValidateMathFunctions(ODataQueryOptions queryOptions, ODataValidationSettings validationSettings)
        {
            if (validationSettings.AllowedFunctions == AllowedFunctions.AllFunctions ||
                validationSettings.AllowedFunctions == AllowedFunctions.AllMathFunctions)
            {
                return;
            }

            string rawFilterValue = queryOptions.RawValues.Filter;

            if ((validationSettings.AllowedFunctions & AllowedFunctions.Ceiling) != AllowedFunctions.Ceiling &&
                rawFilterValue.Contains("ceiling("))
            {
                throw ODataException.NotImplemented("Unsupported function ceiling", "$filter");
            }

            if ((validationSettings.AllowedFunctions & AllowedFunctions.Floor) != AllowedFunctions.Floor &&
                rawFilterValue.Contains("floor("))
            {
                throw ODataException.NotImplemented("Unsupported function floor", "$filter");
            }

            if ((validationSettings.AllowedFunctions & AllowedFunctions.Round) != AllowedFunctions.Round &&
                rawFilterValue.Contains("round("))
            {
                throw ODataException.NotImplemented("Unsupported function round", "$filter");
            }
        }
        public void WriteMessageAsync_SynchronousResponseContainsContentId_IfHasContentIdInRequestChangeSet()
        {
            // Arrange
            HeaderDictionary headers = new HeaderDictionary
            {
                { "Content-Type", $"multipart/mixed;charset=utf-8;boundary={Guid.NewGuid()}" },
            };

            MemoryStream          ms            = new MemoryStream();
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(ms, headers);

            string       contentId    = Guid.NewGuid().ToString();
            HttpResponse httpResponse = CreateResponse("any", new HeaderDictionary(), "text/example;charset=utf-8");

            httpResponse.HttpContext.Request.SetODataContentId(contentId);

            // Act
            ODataBatchWriter batchWriter = new ODataMessageWriter(odataResponse).CreateODataBatchWriter();

            batchWriter.WriteStartBatch();
            batchWriter.WriteStartChangeset();

            // Assert
            Action         test      = () => ODataBatchResponseItem.WriteMessageAsync(batchWriter, httpResponse.HttpContext).Wait();
            ODataException exception = ExceptionAssert.Throws <ODataException>(test);

            Assert.Equal("An asynchronous operation was called on a synchronous batch writer. Calls on a batch writer instance must be either all synchronous or all asynchronous.",
                         exception.Message);
        }
        public void WriteMessage_SynchronouslyWritesResponseMessage_Throws()
        {
            HeaderDictionary headers = new HeaderDictionary
            {
                { "Content-Type", $"multipart/mixed;charset=utf-8;boundary={Guid.NewGuid()}" },
            };

            MemoryStream          ms            = new MemoryStream();
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(ms, headers);

            HeaderDictionary responseHeaders = new HeaderDictionary
            {
                { "customHeader", "bar" }
            };
            HttpResponse response = CreateResponse("example content", responseHeaders, "text/example");

            // Act
            ODataBatchWriter batchWriter = new ODataMessageWriter(odataResponse).CreateODataBatchWriter();

            batchWriter.WriteStartBatch();

            // Assert
            Action         test      = () => ODataBatchResponseItem.WriteMessageAsync(batchWriter, response.HttpContext).Wait();
            ODataException exception = ExceptionAssert.Throws <ODataException>(test);

            Assert.Equal("An asynchronous operation was called on a synchronous batch writer. Calls on a batch writer instance must be either all synchronous or all asynchronous.",
                         exception.Message);
        }
        /// <summary>
        /// Initialises a new instance of the <see cref="OrderByProperty"/> class.
        /// </summary>
        /// <param name="rawValue">The raw value.</param>
        /// <param name="model">The model.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="rawValue"/> or <paramref name="model"/> are null.</exception>
        /// <exception cref="ODataException">Thrown if there is an error parsing the <paramref name="rawValue"/>.</exception>
        internal OrderByProperty(string rawValue, EdmComplexType model)
        {
            RawValue = rawValue ?? throw new ArgumentNullException(nameof(rawValue));

            if (model is null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            if (rawValue.IndexOf(' ') == -1)
            {
                PropertyPath = PropertyPath.For(rawValue, model);
            }
            else
            {
                PropertyPath = PropertyPath.For(rawValue.SubstringBefore(' '), model);

                if (rawValue.EndsWith(" asc", StringComparison.Ordinal))
                {
                    Direction = OrderByDirection.Ascending;
                }
                else if (rawValue.EndsWith(" desc", StringComparison.Ordinal))
                {
                    Direction = OrderByDirection.Descending;
                }
                else
                {
                    throw ODataException.BadRequest(ExceptionMessage.InvalidOrderByDirection(rawValue.SubstringAfter(' '), PropertyPath.Property.Name), "$orderby");
                }
            }
        }
        public void Constructor_Throws_ODataException_For_EmptySkipQueryOption()
        {
            ODataException odataException = Assert.Throws <ODataException>(() => new ODataRawQueryOptions("?$skip="));

            Assert.Equal(ExceptionMessage.QueryOptionValueCannotBeEmpty("$skip"), odataException.Message);
            Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
            Assert.Equal("$skip", odataException.Target);
        }
        public void Constructor_Throws_ODataException_For_UnknownQueryOption()
        {
            ODataException odataException = Assert.Throws <ODataException>(() => new ODataRawQueryOptions("?$wibble=*"));

            Assert.Equal(ExceptionMessage.UnsupportedQueryOption("$wibble"), odataException.Message);
            Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
            Assert.Equal("$wibble", odataException.Target);
        }
        public void EntitySetForPath_Throws_ODataException_IfEntitySetNotRegistered()
        {
            ODataException odataException = Assert.Throws <ODataException>(() => EntityDataModel.Current.EntitySetForPath("/OData/Colour"));

            Assert.Equal(ExceptionMessage.EntityDataModelDoesNotContainEntitySet("Colour"), odataException.Message);
            Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
            Assert.Equal("Colour", odataException.Target);
        }
        public void Constructor_Throws_ODataException_For_FormatAtom()
        {
            ODataException odataException = Assert.Throws <ODataException>(() => new FormatQueryOption("$format=atom"));

            Assert.Equal(ExceptionMessage.QueryOptionValueNotSupported("$format", "atom", "'json, application/json'"), odataException.Message);
            Assert.Equal(HttpStatusCode.NotAcceptable, odataException.StatusCode);
            Assert.Equal("$format", odataException.Target);
        }
        [InlineData("2012-09-03T24:00-03:00")] // Lexer should parse but should fail in ConstantNodeParser
        public void Parse_DateTimeOffset_Abnf_Failures(string value)
        {
            ODataException odataException = Assert.Throws <ODataException>(() => ConstantNodeParser.ParseConstantNode(new Token(TokenType.DateTimeOffset, value, 0)));

            Assert.Equal(ExceptionMessage.UnableToParseDateTimeOffset, odataException.Message);
            Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
            Assert.Equal("$filter", odataException.Target);
        }
        public void Ctor_Message_Works()
        {
            var ex = new ODataException("message", "expression", 42);

            Assert.Equal("message", ex.Message);
            Assert.Equal("expression", ex.Expression);
            Assert.Equal(42, ex.ErrorPosition);
        }
Example #12
0
        public void MultipartBatchTestDuplicateContentIdsFailsV401()
        {
            ODataException ode = Assert.Throws <ODataException>(
                () => ReadBatch(RequestPayloadVerifyDuplicateContentId, ODataVersion.V401));

            Assert.Contains("The content ID '1' was found more than once in the same change set or same batch request. Content IDs have to be unique across all operations of a change set for OData V4.0 and have to be unique across all operations in the whole batch request for OData V4.01.",
                            ode.Message);
        }
        public void Constructor_Throws_ODataException_For_FormatXml_AndMetadataLevel()
        {
            ODataException odataException = Assert.Throws <ODataException>(() => new FormatQueryOption("$format=xml;odata.metadata=none"));

            Assert.Equal(ExceptionMessage.QueryOptionValueNotSupported("$format", "xml", "'json, application/json'"), odataException.Message);
            Assert.Equal(HttpStatusCode.NotAcceptable, odataException.StatusCode);
            Assert.Equal("$format", odataException.Target);
        }
        public void ToBinaryOperatorKind_Throws_ODataException_For_UnsupportedOperatorKind()
        {
            ODataException odataException = Assert.Throws <ODataException>(() => "wibble".ToBinaryOperatorKind());

            Assert.Equal(ExceptionMessage.InvalidOperator("wibble"), odataException.Message);
            Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
            Assert.Equal("$filter", odataException.Target);
        }
        public void ReadMetadataDocument_WorksForJsonCSDL()
        {
            Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(@"{
  ""$Version"": ""4.0"",
  ""$EntityContainer"": ""NS.Container"",
  ""NS"": {
    ""Customer"": {
      ""$Kind"": ""EntityType"",
      ""$Key"": [
        ""Id""
      ],
      ""Id"": {
        ""$Type"": ""Edm.Int32""
      },
      ""Name"": {}
    },
    ""Container"": {
      ""$Kind"": ""EntityContainer"",
      ""Customers"": {
        ""$Collection"": true,
        ""$Type"": ""NS.Customer""
      }
    }
  }
}"));

            IODataResponseMessage responseMessage = new InMemoryMessage()
            {
                StatusCode = 200, Stream = stream
            };

            responseMessage.SetHeader("Content-Type", "application/json");
            ODataMessageReader reader = new ODataMessageReader(responseMessage, new ODataMessageReaderSettings(), new EdmModel());

#if NETCOREAPP3_1 || NETCOREAPP2_1
            IEdmModel model = reader.ReadMetadataDocument();

            IEdmEntityType customerType = model.FindDeclaredType("NS.Customer") as IEdmEntityType;
            Assert.NotNull(customerType);

            IEdmProperty idProperty = customerType.FindProperty("Id");
            Assert.NotNull(idProperty);
            Assert.Equal("Edm.Int32", idProperty.Type.FullName());

            IEdmProperty nameProperty = customerType.FindProperty("Name");
            Assert.NotNull(nameProperty);
            Assert.Equal("Edm.String", nameProperty.Type.FullName());

            IEdmEntitySet customers = Assert.Single(model.EntityContainer.EntitySets());
            Assert.Equal("Customers", customers.Name);
            Assert.Same(customerType, customers.EntityType());
#else
            Action test = () => reader.ReadMetadataDocument();

            ODataException exception = Assert.Throws <ODataException>(test);
            Assert.Equal("The JSON metadata is not supported at this platform. It's only supported at platform implementing .NETStardard 2.0.", exception.Message);
#endif
        }
Example #16
0
            public void ParseInvalidPropertyEqualsSyntax()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => FilterExpressionParser.Parse("Name eq %", EntityDataModel.Current.EntitySets["Products"].EdmType));;

                Assert.Equal(ExceptionMessage.GenericUnableToParseFilter, odataException.Message);
                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("$filter", odataException.Target);
            }
Example #17
0
            public void ParseFunctionMissingSecondParameterExpression()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => FilterExpressionParser.Parse("cast(Colour,) eq 20", EntityDataModel.Current.EntitySets["Products"].EdmType));;

                Assert.Equal(ExceptionMessage.UnableToParseFilter("the function cast has a missing parameter or extra comma at position 12"), odataException.Message);
                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("$filter", odataException.Target);
            }
Example #18
0
            public void ParseFunctionMissingParenthesisEqExpression()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => FilterExpressionParser.Parse("ceiling(Freight eq 32", EntityDataModel.Current.EntitySets["Orders"].EdmType));;

                Assert.Equal(ExceptionMessage.UnableToParseFilter("an extra opening or missing closing parenthesis may be present"), odataException.Message);
                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("$filter", odataException.Target);
            }
Example #19
0
            public void ParseFunctionMissingParameterExpression()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => FilterExpressionParser.Parse("ceiling() eq 32", EntityDataModel.Current.EntitySets["Orders"].EdmType));;

                Assert.Equal(ExceptionMessage.UnableToParseFilter("the function ceiling has no parameters specified at position 8"), odataException.Message);
                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("$filter", odataException.Target);
            }
Example #20
0
            public void ParseFunctionInvalidSyntax()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => FilterExpressionParser.Parse("cast(Colour, not", EntityDataModel.Current.EntitySets["Products"].EdmType));;

                Assert.Equal(ExceptionMessage.UnableToParseFilter("unexpected not at position 14"), odataException.Message);
                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("$filter", odataException.Target);
            }
Example #21
0
            public void ParseFunctionExtraEndParenthesisEqExpression()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => FilterExpressionParser.Parse("ceiling(Freight) eq 32)", EntityDataModel.Current.EntitySets["Orders"].EdmType));;

                Assert.Equal(ExceptionMessage.UnableToParseFilter("the closing parenthesis not expected at position 23"), odataException.Message);
                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("$filter", odataException.Target);
            }
Example #22
0
            public void ParseFunctionEqMissingExpression()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => FilterExpressionParser.Parse("ceiling(Freight) eq", EntityDataModel.Current.EntitySets["Orders"].EdmType));

                Assert.Equal(ExceptionMessage.UnableToParseFilter("the binary operator Equal has no right node"), odataException.Message);
                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("$filter", odataException.Target);
            }
Example #23
0
            public void An_ODataException_IsThrown_WithStatusBadRequest()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => SkipQueryOptionValidator.Validate(_queryOptions, _validationSettings));

                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("The value for OData query $skip must be a non-negative numeric value", odataException.Message);
                Assert.Equal("$skip", odataException.Target);
            }
Example #24
0
            public void An_ODataException_IsThrown_WithStatusNotImplemented()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => SelectQueryOptionValidator.Validate(_queryOptions, _validationSettings));

                Assert.Equal(HttpStatusCode.NotImplemented, odataException.StatusCode);
                Assert.Equal("The query option $select is not implemented by this service", odataException.Message);
                Assert.Equal("$select", odataException.Target);
            }
            public void An_ODataException_IsThrown_WithStatusBadRequest()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => CountQueryOptionValidator.Validate(_queryOptions, _validationSettings));

                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("The supplied value for OData query $count is invalid, valid options are 'true' and 'false'", odataException.Message);
                Assert.Equal("$count", odataException.Target);
            }
Example #26
0
            public void ParseSingleOpeningParenthesis()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => FilterExpressionParser.Parse("(", EntityDataModel.Current.EntitySets["Orders"].EdmType));;

                Assert.Equal(ExceptionMessage.UnableToParseFilter("an incomplete filter has been specified"), odataException.Message);
                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("$filter", odataException.Target);
            }
Example #27
0
            public void An_ODataException_IsThrown_WithStatusBadRequest()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => TopQueryOptionValidator.Validate(_queryOptions, _validationSettings));

                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("The integer value for $top is invalid, it must be an integer greater than zero and below the max value of 0 allowed by this service", odataException.Message);
                Assert.Equal("$top", odataException.Target);
            }
Example #28
0
            public void ParsePropertyEqValueOrMissingExpression()
            {
                ODataException odataException = Assert.Throws <ODataException>(
                    () => FilterExpressionParser.Parse("Discontinued eq true or", EntityDataModel.Current.EntitySets["Products"].EdmType));;

                Assert.Equal(ExceptionMessage.UnableToParseFilter("an incomplete filter has been specified"), odataException.Message);
                Assert.Equal(HttpStatusCode.BadRequest, odataException.StatusCode);
                Assert.Equal("$filter", odataException.Target);
            }
Example #29
0
        public void NegativeLevelValueInExpandShouldThrowInLevels()
        {
            // Arrange & Act
            Action test = () => this.ParseExpandOptions("($levels=-5)");

            // Assert
            ODataException exception = Assert.Throws <ODataException>(test);

            Assert.Equal(Strings.UriSelectParser_InvalidLevelsOption("-5"), exception.Message);
        }
Example #30
0
        public void CtorPathTemplateSegmentTemplate_ThrowsODataException_EmptyTemplate()
        {
            // Arrange
            PathTemplateSegment segment = new PathTemplateSegment("{}");

            // Act & Assert
            ODataException exception = ExceptionAssert.Throws <ODataException>(() => new PathTemplateSegmentTemplate(segment));

            Assert.Equal("The route template in path template '{}' is empty.", exception.Message);
        }