public async Task ReadAsync_ThrowsOnDeserializationErrors() { // Arrange var content = "{name: 'Person Name', Age: 'not-an-age'}"; var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var httpContext = GetHttpContext(contentBytes); var modelState = new ModelStateDictionary(); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(User)); var context = new InputFormatterContext(httpContext, metadata, modelState); // Act and Assert await Assert.ThrowsAsync <JsonReaderException>(() => formatter.ReadAsync(context)); }
public async Task JsonFormatterReadsSimpleTypes(string content, Type type, object expected) { // Arrange var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var httpContext = GetHttpContext(contentBytes); var modelState = new ModelStateDictionary(); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, type); var context = new InputFormatterContext(httpContext, metadata, modelState); // Act await formatter.ReadAsync(context); // Assert Assert.Equal(expected, context.Model); }
public async Task JsonFormatterReadsComplexTypes() { // Arrange var content = "{name: 'Person Name', Age: '30'}"; var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var httpContext = GetHttpContext(contentBytes); var modelState = new ModelStateDictionary(); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(User)); var context = new InputFormatterContext(httpContext, metadata, modelState); // Act await formatter.ReadAsync(context); // Assert var model = Assert.IsType<User>(context.Model); Assert.Equal("Person Name", model.Name); Assert.Equal(30, model.Age); }
public async Task JsonFormatterReadsComplexTypes() { // Arrange var content = "{name: 'Person Name', Age: '30'}"; var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var httpContext = GetHttpContext(contentBytes); var modelState = new ModelStateDictionary(); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(User)); var context = new InputFormatterContext(httpContext, metadata, modelState); // Act await formatter.ReadAsync(context); // Assert var model = Assert.IsType <User>(context.Model); Assert.Equal("Person Name", model.Name); Assert.Equal(30, model.Age); }
public async Task ReadAsync_AddsModelValidationErrorsToModelState_WhenCaptureErrorsIsSet() { // Arrange var content = "{name: 'Person Name', Age: 'not-an-age'}"; var formatter = new JsonInputFormatter { CaptureDeserilizationErrors = true }; var contentBytes = Encoding.UTF8.GetBytes(content); var httpContext = GetHttpContext(contentBytes); var modelState = new ModelStateDictionary(); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(User)); var context = new InputFormatterContext(httpContext, metadata, modelState); // Act await formatter.ReadAsync(context); // Assert 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 CustomSerializerSettingsObject_TakesEffect() { // Arrange // missing password property here var contentBytes = Encoding.UTF8.GetBytes("{ \"UserName\" : \"John\"}"); var jsonFormatter = new JsonInputFormatter(); // 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 inputFormatterContext = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, modelType: typeof(UserLogin)); // 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_AddsModelValidationErrorsToModelState() { // Arrange var content = "{name: 'Person Name', Age: 'not-an-age'}"; var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, modelType: typeof(User)); // 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 formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var actionContext = GetActionContext(contentBytes); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(User)); var context = new InputFormatterContext(actionContext, metadata.ModelType); // Act var model = await formatter.ReadAsync(context); // Assert var userModel = Assert.IsType<User>(model); Assert.Equal("Person Name", userModel.Name); Assert.Equal(30, userModel.Age); }
public async Task Validation_DoesNotHappen_OnNullableValueTypeProperties() { // Arrange var contentBytes = Encoding.UTF8.GetBytes("{}"); var jsonFormatter = new JsonInputFormatter(); var actionContext = GetActionContext(contentBytes, "application/json;charset=utf-8"); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(Venue)); var inputFormatterContext = new InputFormatterContext(actionContext, metadata.ModelType); // Act var obj = await jsonFormatter.ReadAsync(inputFormatterContext); // Assert Assert.True(actionContext.ModelState.IsValid); var venue = obj as Venue; Assert.NotNull(venue); Assert.Null(venue.Location); Assert.Null(venue.NearByLocations); Assert.Null(venue.Name); }
public async Task Validates_RequiredAttributeOnStructTypes() { // Arrange var contentBytes = Encoding.UTF8.GetBytes("{\"Longitude\":{}}"); var jsonFormatter = new JsonInputFormatter(); var actionContext = GetActionContext(contentBytes, "application/json;charset=utf-8"); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(GpsCoordinate)); var inputFormatterContext = new InputFormatterContext(actionContext, metadata.ModelType); // Act var obj = await jsonFormatter.ReadAsync(inputFormatterContext); // Assert Assert.False(actionContext.ModelState.IsValid); Assert.Equal(2, actionContext.ModelState.Count); var errorMessages = GetModelStateErrorMessages(actionContext.ModelState); Assert.Equal(3, errorMessages.Count()); Assert.Contains( errorMessages, (errorMessage) => errorMessage.Contains("Required property 'Latitude' not found in JSON")); Assert.Contains( errorMessages, (errorMessage) => errorMessage.Contains("Required property 'X' not found in JSON")); Assert.Contains( errorMessages, (errorMessage) => errorMessage.Contains("Required property 'Y' not found in JSON")); }
public async Task ThrowsException_OnSupplyingNull_ForRequiredValueType() { // Arrange var contentBytes = Encoding.UTF8.GetBytes("{\"Id\":\"null\",\"Name\":\"Programming C#\"}"); var jsonFormatter = new JsonInputFormatter(); var actionContext = GetActionContext(contentBytes, "application/json;charset=utf-8"); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(Book)); var inputFormatterContext = new InputFormatterContext(actionContext, metadata.ModelType); // Act var obj = await jsonFormatter.ReadAsync(inputFormatterContext); // Assert var book = obj as Book; Assert.NotNull(book); Assert.Equal(0, book.Id); Assert.Equal("Programming C#", book.Name); Assert.False(actionContext.ModelState.IsValid); Assert.Equal(1, actionContext.ModelState.Values.First().Errors.Count); var modelErrorMessage = actionContext.ModelState.Values.First().Errors[0].Exception.Message; Assert.Contains("Could not convert string to integer: null. Path 'Id'", modelErrorMessage); }
public async Task ReadAsync_ThrowsOnDeserializationErrors() { // Arrange var content = "{name: 'Person Name', Age: 'not-an-age'}"; var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var httpContext = GetHttpContext(contentBytes); var modelState = new ModelStateDictionary(); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(User)); var context = new InputFormatterContext(httpContext, metadata, modelState); // Act and Assert await Assert.ThrowsAsync<JsonReaderException>(() => formatter.ReadAsync(context)); }
public async Task ReadAsync_UsesTryAddModelValidationErrorsToModelState() { // Arrange var content = "{name: 'Person Name', Age: 'not-an-age'}"; var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var actionContext = GetActionContext(contentBytes); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(User)); var context = new InputFormatterContext(actionContext, metadata.ModelType); actionContext.ModelState.MaxAllowedErrors = 3; actionContext.ModelState.AddModelError("key1", "error1"); actionContext.ModelState.AddModelError("key2", "error2"); // Act var model = await formatter.ReadAsync(context); // Assert Assert.False(actionContext.ModelState.ContainsKey("age")); var error = Assert.Single(actionContext.ModelState[""].Errors); Assert.IsType<TooManyModelErrorsException>(error.Exception); }
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); }
public async Task CustomSerializerSettingsObject_TakesEffect() { // Arrange // missing password property here var contentBytes = Encoding.UTF8.GetBytes("{ \"UserName\" : \"John\"}"); var jsonFormatter = new JsonInputFormatter(); // by default we ignore missing members, so here explicitly changing it jsonFormatter.SerializerSettings = new JsonSerializerSettings() { MissingMemberHandling = MissingMemberHandling.Error }; var actionContext = GetActionContext(contentBytes, "application/json;charset=utf-8"); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(UserLogin)); var inputFormatterContext = new InputFormatterContext(actionContext, metadata.ModelType); // Act var obj = await jsonFormatter.ReadAsync(inputFormatterContext); // Assert Assert.False(actionContext.ModelState.IsValid); var modelErrorMessage = actionContext.ModelState.Values.First().Errors[0].Exception.Message; Assert.Contains("Required property 'Password' not found in JSON", modelErrorMessage); }
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 Validates_RequiredAttribute_OnRegularAndInheritedProperties(Type type) { // Arrange var contentBytes = Encoding.UTF8.GetBytes("{ \"Name\" : \"Programming C#\"}"); var jsonFormatter = new JsonInputFormatter(); var actionContext = GetActionContext(contentBytes, "application/json;charset=utf-8"); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(type); var inputFormatterContext = new InputFormatterContext(actionContext, metadata.ModelType); // Act var obj = await jsonFormatter.ReadAsync(inputFormatterContext); // Assert Assert.False(actionContext.ModelState.IsValid); Assert.Equal(1, actionContext.ModelState.Count); var modelErrorMessage = actionContext.ModelState.Values.First().Errors[0].Exception.Message; Assert.Contains("Required property 'Id' not found in JSON", modelErrorMessage); }
public async Task ChangesTo_DefaultSerializerSettings_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.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 Validation_DoesNotHappen_ForNonRequired_ValueTypeProperties() { // Arrange var contentBytes = Encoding.UTF8.GetBytes("{\"Name\":\"Seattle\"}"); var jsonFormatter = new JsonInputFormatter(); var actionContext = GetActionContext(contentBytes, "application/json;charset=utf-8"); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(Location)); var inputFormatterContext = new InputFormatterContext(actionContext, metadata.ModelType); // Act var obj = await jsonFormatter.ReadAsync(inputFormatterContext); // Assert Assert.True(actionContext.ModelState.IsValid); var location = obj as Location; Assert.NotNull(location); Assert.Equal(0, location.Id); Assert.Equal("Seattle", location.Name); }
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 JsonFormatterReadsSimpleTypes(string content, Type type, object expected) { // Arrange var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var actionContext = GetActionContext(contentBytes); var context = new InputFormatterContext(actionContext, type); // Act var model = await formatter.ReadAsync(context); // Assert Assert.Equal(expected, model); }
public async Task ReadAsync_InvalidArray_AddsOverflowErrorsToModelState() { // Arrange var content = "[0, 23, 300]"; var formatter = new JsonInputFormatter(); 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); // 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 JsonFormatterReadsComplexTypes() { // Arrange var content = "{name: 'Person Name', Age: '30'}"; var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var httpContext = GetHttpContext(contentBytes); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: new ModelStateDictionary(), modelType: typeof(User)); // 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); }
public async Task ReadAsync_InvalidComplexArray_AddsOverflowErrorsToModelState() { // Arrange var content = "[{name: 'Name One', Age: 30}, {name: 'Name Two', Small: 300}]"; var formatter = new JsonInputFormatter(); 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); // 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_UsesTryAddModelValidationErrorsToModelState() { // Arrange var content = "{name: 'Person Name', Age: 'not-an-age'}"; var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var modelState = new ModelStateDictionary(); var httpContext = GetHttpContext(contentBytes); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: modelState, modelType: typeof(User)); 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_AddsModelValidationErrorsToModelState() { // Arrange var content = "{name: 'Person Name', Age: 'not-an-age'}"; var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var actionContext = GetActionContext(contentBytes); var metadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(User)); var context = new InputFormatterContext(actionContext, metadata.ModelType); // Act var model = await formatter.ReadAsync(context); // Assert Assert.Equal("Could not convert string to decimal: not-an-age. Path 'Age', line 1, position 39.", actionContext.ModelState["Age"].Errors[0].Exception.Message); }
public async Task JsonFormatterReadsSimpleTypes(string content, Type type, object expected) { // Arrange var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); var httpContext = GetHttpContext(contentBytes); var context = new InputFormatterContext( httpContext, modelName: string.Empty, modelState: new ModelStateDictionary(), modelType: type); // Act var result = await formatter.ReadAsync(context); // Assert Assert.False(result.HasError); Assert.Equal(expected, result.Model); }