// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using XmlFormattersWebSite; using Xunit; namespace Microsoft.AspNetCore.Mvc.FunctionalTests { public class XmlDataContractSerializerInputFormatterTest : IClassFixture> { private readonly string errorMessageFormat = string.Format( "{{1}}:{0} does not recognize '{1}', so instead use '{2}' with '{3}' set to '{4}' for value " + "type property '{{0}}' on type '{{1}}'.", typeof(DataContractSerializer).FullName, typeof(RequiredAttribute).FullName, typeof(DataMemberAttribute).FullName, nameof(DataMemberAttribute.IsRequired), bool.TrueString); public XmlDataContractSerializerInputFormatterTest(MvcTestFixture fixture) { Client = fixture.Client; } public HttpClient Client { get; } [Fact] public async Task ThrowsOnInvalidInput_AndAddsToModelState() { // Arrange var input = "Not a valid xml document"; var content = new StringContent(input, Encoding.UTF8, "application/xml-dcs"); // Act var response = await Client.PostAsync("http://localhost/Home/Index", content); // Assert Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); var data = await response.Content.ReadAsStringAsync(); Assert.Contains( string.Format( ":There was an error deserializing the object of type {0}.", typeof(DummyClass).FullName), data); } [Fact] public async Task RequiredDataIsProvided_AndModelIsBound_NoValidationErrors() { // Arrange var input = "
WA" + "98052
10
"; var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Validation/CreateStore"); request.Content = new StringContent(input, Encoding.UTF8, "application/xml-dcs"); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml-dcs")); // Act var response = await Client.SendAsync(request); // Assert var dcsSerializer = new DataContractSerializer(typeof(ModelBindingInfo)); var responseStream = await response.Content.ReadAsStreamAsync(); var modelBindingInfo = dcsSerializer.ReadObject(responseStream) as ModelBindingInfo; Assert.NotNull(modelBindingInfo); Assert.NotNull(modelBindingInfo.Store); Assert.Equal(10, modelBindingInfo.Store.Id); Assert.NotNull(modelBindingInfo.Store.Address); Assert.Equal(98052, modelBindingInfo.Store.Address.Zipcode); Assert.Equal("WA", modelBindingInfo.Store.Address.State); Assert.Empty(modelBindingInfo.ModelStateErrorMessages); } // Verifies that the model state has errors related to body model validation. [Fact] public async Task DataMissingForRefereneceTypeProperties_AndModelIsBound_AndHasMixedValidationErrors() { // Arrange var input = "" + "
10"; var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Validation/CreateStore"); request.Content = new StringContent(input, Encoding.UTF8, "application/xml-dcs"); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml-dcs")); var expectedErrorMessages = new List(); expectedErrorMessages.Add("Address:The Address field is required."); // Act var response = await Client.SendAsync(request); // Assert var dcsSerializer = new DataContractSerializer(typeof(ModelBindingInfo)); var responseStream = await response.Content.ReadAsStreamAsync(); var modelBindingInfo = dcsSerializer.ReadObject(responseStream) as ModelBindingInfo; Assert.NotNull(modelBindingInfo); Assert.NotNull(modelBindingInfo.Store); Assert.Equal(10, modelBindingInfo.Store.Id); Assert.NotNull(modelBindingInfo.ModelStateErrorMessages); Assert.Equal(expectedErrorMessages.Count(), modelBindingInfo.ModelStateErrorMessages.Count); foreach (var expectedErrorMessage in expectedErrorMessages) { Assert.Contains( modelBindingInfo.ModelStateErrorMessages, (actualErrorMessage) => actualErrorMessage.Equals(expectedErrorMessage)); } } } }