public void CanRead_ReturnsTrueForAnySupportedContentType(string requestContentType, bool expectedCanRead) { // Arrange var loggerMock = GetLogger(); var formatter = new JsonInputFormatter(loggerMock, _serializerSettings, ArrayPool<char>.Shared, _objectPoolProvider); var contentBytes = Encoding.UTF8.GetBytes("content"); var httpContext = GetHttpContext(contentBytes, contentType: requestContentType); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(string)); var formatterContext = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: new ModelStateDictionary(), metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = formatter.CanRead(formatterContext); // Assert Assert.Equal(expectedCanRead, result); }
public async Task JsonPatchInputFormatter_ReadsMultipleOperations_Successfully() { // Arrange var logger = GetLogger(); var formatter = new JsonPatchInputFormatter(logger); var content = "[{\"op\": \"add\", \"path\" : \"Customer/Name\", \"value\":\"John\"}," + "{\"op\": \"remove\", \"path\" : \"Customer/Name\"}]"; var contentBytes = Encoding.UTF8.GetBytes(content); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(JsonPatchDocument<Customer>)); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = await formatter.ReadAsync(context); // Assert Assert.False(result.HasError); var patchDoc = Assert.IsType<JsonPatchDocument<Customer>>(result.Model); Assert.Equal("add", patchDoc.Operations[0].op); Assert.Equal("Customer/Name", patchDoc.Operations[0].path); Assert.Equal("John", patchDoc.Operations[0].value); Assert.Equal("remove", patchDoc.Operations[1].op); Assert.Equal("Customer/Name", patchDoc.Operations[1].path); }
public void AddValidation_Date() { IModelMetadataProvider provider = new EmptyModelMetadataProvider(); ModelMetadata metadata = provider.GetMetadataForType(typeof(DateTime)); Dictionary<String, String> attributes = new Dictionary<String, String>(); ClientModelValidationContext context = new ClientModelValidationContext(new ActionContext(), metadata, provider, attributes); new DateValidator().AddValidation(context); Assert.Equal(2, attributes.Count); Assert.Equal("true", attributes["data-val"]); Assert.Equal(String.Format(Validations.Date, "DateTime"), attributes["data-val-date"]); }
private static DefaultModelBindingContext GetBindingContext(Type modelType) { var metadataProvider = new EmptyModelMetadataProvider(); DefaultModelBindingContext bindingContext = new DefaultModelBindingContext { ActionContext = new ActionContext() { HttpContext = new DefaultHttpContext(), }, ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelName = "someName", ValidationState = new ValidationStateDictionary(), }; bindingContext.HttpContext.Request.Method = "GET"; return bindingContext; }
public async Task JsonPatchInputFormatter_ReturnsModelStateErrors_InvalidModelType() { // Arrange var exceptionMessage = "Cannot deserialize the current JSON array (e.g. [1,2,3]) into type " + $"'{typeof(Customer).FullName}' because the type requires a JSON object "; var logger = GetLogger(); var formatter = new JsonPatchInputFormatter(logger); var content = "[{\"op\": \"add\", \"path\" : \"Customer/Name\", \"value\":\"John\"}]"; var contentBytes = Encoding.UTF8.GetBytes(content); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes, contentType: "application/json-patch+json"); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(Customer)); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = await formatter.ReadAsync(context); // Assert Assert.True(result.HasError); Assert.Contains(exceptionMessage, modelState[""].Errors[0].Exception.Message); }
public void CanRead_ReturnsFalse_NonJsonPatchContentType(Type modelType) { // Arrange var logger = GetLogger(); var formatter = new JsonPatchInputFormatter(logger); var content = "[{\"op\": \"add\", \"path\" : \"Customer/Name\", \"value\":\"John\"}]"; var contentBytes = Encoding.UTF8.GetBytes(content); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes, contentType: "application/json-patch+json"); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(modelType); var formatterContext = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = formatter.CanRead(formatterContext); // Assert Assert.False(result); }
public async Task JsonFormatterReadsSimpleTypes(string content, Type type, object expected) { // Arrange var logger = GetLogger(); var formatter = new JsonInputFormatter(logger); var contentBytes = Encoding.UTF8.GetBytes(content); var httpContext = GetHttpContext(contentBytes); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(type); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: new ModelStateDictionary(), metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = await formatter.ReadAsync(context); // Assert Assert.False(result.HasError); Assert.Equal(expected, result.Model); }
public async Task CustomSerializerSettingsObject_TakesEffect() { // Arrange // missing password property here var contentBytes = Encoding.UTF8.GetBytes("{ \"UserName\" : \"John\"}"); var logger = GetLogger(); var jsonFormatter = new JsonInputFormatter(logger); // by default we ignore missing members, so here explicitly changing it jsonFormatter.SerializerSettings = new JsonSerializerSettings() { MissingMemberHandling = MissingMemberHandling.Error }; var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes, "application/json;charset=utf-8"); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(UserLogin)); var inputFormatterContext = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = await jsonFormatter.ReadAsync(inputFormatterContext); // Assert Assert.True(result.HasError); Assert.False(modelState.IsValid); var modelErrorMessage = modelState.Values.First().Errors[0].Exception.Message; Assert.Contains("Required property 'Password' not found in JSON", modelErrorMessage); }
public async Task ReadAsync_UsesTryAddModelValidationErrorsToModelState() { // Arrange var content = "{name: 'Person Name', Age: 'not-an-age'}"; var logger = GetLogger(); var formatter = new JsonInputFormatter(logger); var contentBytes = Encoding.UTF8.GetBytes(content); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(User)); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); modelState.MaxAllowedErrors = 3; modelState.AddModelError("key1", "error1"); modelState.AddModelError("key2", "error2"); // Act var result = await formatter.ReadAsync(context); // Assert Assert.True(result.HasError); Assert.False(modelState.ContainsKey("age")); var error = Assert.Single(modelState[""].Errors); Assert.IsType<TooManyModelErrorsException>(error.Exception); }
public async Task ReadAsync_InvalidArray_AddsOverflowErrorsToModelState() { // Arrange var content = "[0, 23, 300]"; var logger = GetLogger(); var formatter = new JsonInputFormatter(logger); var contentBytes = Encoding.UTF8.GetBytes(content); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(byte[])); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = await formatter.ReadAsync(context); // Assert Assert.True(result.HasError); Assert.Equal("The supplied value is invalid for Byte.", modelState["[2]"].Errors[0].ErrorMessage); Assert.Null(modelState["[2]"].Errors[0].Exception); }
public async Task ReadAsync_AddsModelValidationErrorsToModelState() { // Arrange var content = "{name: 'Person Name', Age: 'not-an-age'}"; var logger = GetLogger(); var formatter = new JsonInputFormatter(logger); var contentBytes = Encoding.UTF8.GetBytes(content); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(User)); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = await formatter.ReadAsync(context); // Assert Assert.True(result.HasError); Assert.Equal( "Could not convert string to decimal: not-an-age. Path 'Age', line 1, position 39.", modelState["Age"].Errors[0].Exception.Message); }
public async Task JsonFormatterReadsComplexTypes() { // Arrange var content = "{name: 'Person Name', Age: '30'}"; var logger = GetLogger(); var formatter = new JsonInputFormatter(logger); var contentBytes = Encoding.UTF8.GetBytes(content); var httpContext = GetHttpContext(contentBytes); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(User)); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: new ModelStateDictionary(), metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = await formatter.ReadAsync(context); // Assert Assert.False(result.HasError); var userModel = Assert.IsType<User>(result.Model); Assert.Equal("Person Name", userModel.Name); Assert.Equal(30, userModel.Age); }
private InputFormatterContext GetInputFormatterContext(byte[] contentBytes, Type modelType) { var httpContext = GetHttpContext(contentBytes); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(modelType); return new InputFormatterContext( httpContext, modelName: string.Empty, modelState: new ModelStateDictionary(), metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); }
public async Task ReadAsync_AcceptsUTF16Characters() { // Arrange var expectedInt = 10; var expectedString = "TestString"; var input = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>" + "<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" + "<sampleString>" + expectedString + "</sampleString></TestLevelOne>"; var formatter = new XmlDataContractSerializerInputFormatter(); var contentBytes = Encoding.Unicode.GetBytes(input); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes, contentType: "application/xml; charset=utf-16"); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(TestLevelOne)); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = await formatter.ReadAsync(context); // Assert Assert.NotNull(result); Assert.False(result.HasError); var model = Assert.IsType<TestLevelOne>(result.Model); Assert.Equal(expectedInt, model.SampleInt); Assert.Equal(expectedString, model.sampleString); }
public async Task ReadAsync_UsesContentTypeCharSet_ToReadStream() { // Arrange var expectedException = TestPlatformHelper.IsMono ? typeof(SerializationException) : typeof(XmlException); var expectedMessage = TestPlatformHelper.IsMono ? "Expected element 'TestLevelTwo' in namespace '', but found Element node 'DummyClass' in namespace ''" : "The expected encoding 'utf-16LE' does not match the actual encoding 'utf-8'."; var inputBytes = Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<DummyClass><SampleInt>1000</SampleInt></DummyClass>"); var formatter = new XmlDataContractSerializerInputFormatter(); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(inputBytes, contentType: "application/xml; charset=utf-16"); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(TestLevelOne)); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var ex = await Assert.ThrowsAsync(expectedException, () => formatter.ReadAsync(context)); Assert.Equal(expectedMessage, ex.Message); }
public void CanRead_ReturnsTrueOnlyForJsonPatchContentType(string requestContentType, bool expectedCanRead) { // Arrange var logger = GetLogger(); var formatter = new JsonPatchInputFormatter(logger); var content = "[{\"op\": \"add\", \"path\" : \"Customer/Name\", \"value\":\"John\"}]"; var contentBytes = Encoding.UTF8.GetBytes(content); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes, contentType: requestContentType); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(JsonPatchDocument<Customer>)); var formatterContext = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = formatter.CanRead(formatterContext); // Assert Assert.Equal(expectedCanRead, result); }
public async Task ReadAsync_InvalidComplexArray_AddsOverflowErrorsToModelState() { // Arrange var content = "[{name: 'Name One', Age: 30}, {name: 'Name Two', Small: 300}]"; var logger = GetLogger(); var formatter = new JsonInputFormatter(logger); var contentBytes = Encoding.UTF8.GetBytes(content); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(typeof(User[])); var context = new InputFormatterContext( httpContext, modelName: "names", modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = await formatter.ReadAsync(context); // Assert Assert.True(result.HasError); Assert.Equal( "Error converting value 300 to type 'System.Byte'. Path '[1].Small', line 1, position 59.", modelState["names[1].Small"].Errors[0].Exception.Message); }
public async Task ReadAsync_ReadsValidArray_AsList(Type requestedType) { // Arrange var content = "[0, 23, 300]"; var logger = GetLogger(); var formatter = new JsonInputFormatter(logger, _serializerSettings, ArrayPool<char>.Shared, _objectPoolProvider); var contentBytes = Encoding.UTF8.GetBytes(content); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForType(requestedType); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, metadata: metadata, readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader); // Act var result = await formatter.ReadAsync(context); // Assert Assert.False(result.HasError); var integers = Assert.IsType<List<int>>(result.Model); Assert.Equal(new int[] { 0, 23, 300 }, integers); }