diff --git a/src/Microsoft.AspNet.Mvc.Abstractions/InputFormatterContext.cs b/src/Microsoft.AspNet.Mvc.Abstractions/InputFormatterContext.cs index 1921c9003f..92e7c0b180 100644 --- a/src/Microsoft.AspNet.Mvc.Abstractions/InputFormatterContext.cs +++ b/src/Microsoft.AspNet.Mvc.Abstractions/InputFormatterContext.cs @@ -2,33 +2,51 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc { /// - /// Represents information used by an input formatter for - /// deserializing the request body into an object. + /// A context object used by an input formatter for deserializing the request body into an object. /// public class InputFormatterContext { /// /// Creates a new instance of . /// - public InputFormatterContext([NotNull] ActionContext actionContext, - [NotNull] Type modelType) + /// + /// The for the current operation. + /// + /// + /// The for recording errors. + /// + /// + /// The of the model to deserialize. + /// + public InputFormatterContext( + [NotNull] HttpContext httpContext, + [NotNull] ModelStateDictionary modelState, + [NotNull] Type modelType) { - ActionContext = actionContext; + HttpContext = httpContext; + ModelState = modelState; ModelType = modelType; } /// - /// Action context associated with the current call. + /// Gets the associated with the current operation. /// - public ActionContext ActionContext { get; private set; } + public HttpContext HttpContext { get; private set; } /// - /// Represents the expected type of the model represented by the request body. + /// Gets the associated with the current operation. + /// + public ModelStateDictionary ModelState { get; } + + /// + /// Gets the expected of the model represented by the request body. /// public Type ModelType { get; private set; } } diff --git a/src/Microsoft.AspNet.Mvc.Abstractions/OutputFormatterContext.cs b/src/Microsoft.AspNet.Mvc.Abstractions/OutputFormatterContext.cs index 71f8154d5a..2c7ab76fe2 100644 --- a/src/Microsoft.AspNet.Mvc.Abstractions/OutputFormatterContext.cs +++ b/src/Microsoft.AspNet.Mvc.Abstractions/OutputFormatterContext.cs @@ -3,6 +3,7 @@ using System; using System.Text; +using Microsoft.AspNet.Http; using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc @@ -24,9 +25,9 @@ public class OutputFormatterContext public Type DeclaredType { get; set; } /// - /// Action context associated with the current call. + /// Gets or sets the context associated with the current operation. /// - public ActionContext ActionContext { get; set; } + public HttpContext HttpContext { get; set; } /// /// The encoding which is chosen by the selected formatter. diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs index faa96e6cc9..c600ddb23e 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs @@ -101,7 +101,7 @@ public override async Task ExecuteResultAsync([NotNull] ActionContext context) var formatterContext = new OutputFormatterContext() { - ActionContext = context, + HttpContext = context.HttpContext, DeclaredType = objectResult.DeclaredType, Object = Value, }; @@ -125,7 +125,6 @@ private IOutputFormatter SelectFormatter(ObjectResult objectResult, OutputFormat { // If no formatter was provided, then run Conneg with the formatters configured in options. var formatters = formatterContext - .ActionContext .HttpContext .RequestServices .GetRequiredService>() @@ -140,7 +139,6 @@ private IOutputFormatter SelectFormatter(ObjectResult objectResult, OutputFormat // If the available user-configured formatters can't write this type, then fall back to the // 'global' one. formatter = formatterContext - .ActionContext .HttpContext .RequestServices .GetRequiredService(); diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs index aa5a79dbda..29ffef2afd 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ObjectResult.cs @@ -49,7 +49,7 @@ public override async Task ExecuteResultAsync(ActionContext context) var formatterContext = new OutputFormatterContext() { DeclaredType = DeclaredType, - ActionContext = context, + HttpContext = context.HttpContext, Object = Value, StatusCode = StatusCode }; @@ -83,8 +83,7 @@ public virtual IOutputFormatter SelectFormatter( OutputFormatterContext formatterContext, IEnumerable formatters) { - var logger = formatterContext.ActionContext.HttpContext.RequestServices - .GetRequiredService>(); + var logger = formatterContext.HttpContext.RequestServices.GetRequiredService>(); // Check if any content-type was explicitly set (for example, via ProducesAttribute // or Url path extension mapping). If yes, then ignore content-negotiation and use this content-type. @@ -108,7 +107,7 @@ public virtual IOutputFormatter SelectFormatter( // which can write the type. MediaTypeHeaderValue requestContentType = null; MediaTypeHeaderValue.TryParse( - formatterContext.ActionContext.HttpContext.Request.ContentType, + formatterContext.HttpContext.Request.ContentType, out requestContentType); if (!sortedAcceptHeaderMediaTypes.Any() && requestContentType == null) { @@ -240,17 +239,18 @@ public virtual IOutputFormatter SelectFormatterUsingAnyAcceptableContentType( private IEnumerable GetSortedAcceptHeaderMediaTypes( OutputFormatterContext formatterContext) { - var request = formatterContext.ActionContext.HttpContext.Request; + var request = formatterContext.HttpContext.Request; var incomingAcceptHeaderMediaTypes = request.GetTypedHeaders().Accept ?? new MediaTypeHeaderValue[] { }; // By default we want to ignore considering accept headers for content negotiation when // they have a media type like */* in them. Browsers typically have these media types. // In these cases we would want the first formatter in the list of output formatters to // write the response. This default behavior can be changed through options, so checking here. - var options = formatterContext.ActionContext.HttpContext - .RequestServices - .GetRequiredService>() - .Options; + var options = formatterContext + .HttpContext + .RequestServices + .GetRequiredService>() + .Options; var respectAcceptHeader = true; if (options.RespectBrowserAcceptHeader == false diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs index 19b19c060c..3838879109 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNoContentOutputFormatter.cs @@ -33,7 +33,7 @@ public bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue public Task WriteAsync(OutputFormatterContext context) { - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; response.ContentLength = 0; response.StatusCode = context.StatusCode ?? StatusCodes.Status204NoContent; return Task.FromResult(true); diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNotAcceptableOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNotAcceptableOutputFormatter.cs index 44cf917b13..a85b124aab 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNotAcceptableOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/HttpNotAcceptableOutputFormatter.cs @@ -21,7 +21,7 @@ public bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue /// public Task WriteAsync(OutputFormatterContext context) { - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; response.StatusCode = StatusCodes.Status406NotAcceptable; return Task.FromResult(true); } diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/InputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/InputFormatter.cs index 87382fa7ee..368cb595c4 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/InputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/InputFormatter.cs @@ -48,7 +48,7 @@ public virtual bool CanRead(InputFormatterContext context) return false; } - var contentType = context.ActionContext.HttpContext.Request.ContentType; + var contentType = context.HttpContext.Request.ContentType; MediaTypeHeaderValue requestContentType; if (!MediaTypeHeaderValue.TryParse(contentType, out requestContentType)) { @@ -72,7 +72,7 @@ protected virtual bool CanReadType(Type type) /// public virtual async Task ReadAsync(InputFormatterContext context) { - var request = context.ActionContext.HttpContext.Request; + var request = context.HttpContext.Request; if (request.ContentLength == 0) { return GetDefaultValueForType(context.ModelType); diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/JsonInputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/JsonInputFormatter.cs index 3498331fef..b9e7c771c0 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/JsonInputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/JsonInputFormatter.cs @@ -52,7 +52,7 @@ public JsonSerializerSettings SerializerSettings public override Task ReadRequestBodyAsync([NotNull] InputFormatterContext context) { var type = context.ModelType; - var request = context.ActionContext.HttpContext.Request; + var request = context.HttpContext.Request; MediaTypeHeaderValue requestContentType = null; MediaTypeHeaderValue.TryParse(request.ContentType, out requestContentType); @@ -70,7 +70,7 @@ public override Task ReadRequestBodyAsync([NotNull] InputFormatterContex errorHandler = (sender, e) => { var exception = e.ErrorContext.Error; - context.ActionContext.ModelState.TryAddModelError(e.ErrorContext.Path, e.ErrorContext.Error); + context.ModelState.TryAddModelError(e.ErrorContext.Path, e.ErrorContext.Error); // Error must always be marked as handled // Failure to do so can cause the exception to be rethrown at every recursive level and diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/JsonOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/JsonOutputFormatter.cs index e6f9a47bd9..102fd5849a 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/JsonOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/JsonOutputFormatter.cs @@ -72,7 +72,7 @@ private JsonSerializer CreateJsonSerializer() public override Task WriteResponseBodyAsync(OutputFormatterContext context) { - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; var selectedEncoding = context.SelectedEncoding; using (var writer = new HttpResponseStreamWriter(response.Body, selectedEncoding)) diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/OutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/OutputFormatter.cs index 38ac2207b8..55f693eea2 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/OutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/OutputFormatter.cs @@ -104,7 +104,7 @@ public virtual IReadOnlyList GetSupportedContentTypes( /// The to use when reading the request or writing the response. public virtual Encoding SelectCharacterEncoding([NotNull] OutputFormatterContext context) { - var request = context.ActionContext.HttpContext.Request; + var request = context.HttpContext.Request; var encoding = MatchAcceptCharacterEncoding(request.GetTypedHeaders().AcceptCharset); if (encoding == null) { @@ -195,7 +195,7 @@ public virtual void WriteResponseHeaders([NotNull] OutputFormatterContext contex selectedMediaType.Charset = selectedEncoding.WebName; context.SelectedContentType = context.SelectedContentType ?? selectedMediaType; - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; response.ContentType = selectedMediaType.ToString(); } diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/StreamOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/StreamOutputFormatter.cs index bd1cab55b2..cc95b11473 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/StreamOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/StreamOutputFormatter.cs @@ -33,7 +33,7 @@ public async Task WriteAsync([NotNull] OutputFormatterContext context) { using (var valueAsStream = ((Stream)context.Object)) { - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; if (context.SelectedContentType != null) { diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/StringOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/StringOutputFormatter.cs index 52319ade94..e4b6dc1088 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/StringOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/StringOutputFormatter.cs @@ -44,7 +44,7 @@ public override async Task WriteResponseBodyAsync(OutputFormatterContext context return; } - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; await response.WriteAsync(valueAsString, context.SelectedEncoding); } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/BodyModelBinder.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/BodyModelBinder.cs index a94bab5138..a8a4a36c61 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/BodyModelBinder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/BodyModelBinder.cs @@ -3,7 +3,6 @@ using System; using System.Linq; -using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Core; using Microsoft.Framework.DependencyInjection; @@ -26,14 +25,19 @@ public BodyModelBinder() } /// - protected async override Task BindModelCoreAsync([NotNull] ModelBindingContext bindingContext) + protected async override Task BindModelCoreAsync( + [NotNull] ModelBindingContext bindingContext) { var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices; - var actionContext = requestServices.GetRequiredService>().Value; - var formatters = requestServices.GetRequiredService>().Value.InputFormatters; + var httpContext = bindingContext.OperationBindingContext.HttpContext; + var formatters = requestServices + .GetRequiredService>().Value.InputFormatters; - var formatterContext = new InputFormatterContext(actionContext, bindingContext.ModelType); + var formatterContext = new InputFormatterContext( + httpContext, + bindingContext.ModelState, + bindingContext.ModelType); var formatter = formatters.FirstOrDefault(f => f.CanRead(formatterContext)); if (formatter == null) diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Formatters/HttpResponseMessageOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Formatters/HttpResponseMessageOutputFormatter.cs index 72ec20823a..ce6f977a51 100644 --- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Formatters/HttpResponseMessageOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/Formatters/HttpResponseMessageOutputFormatter.cs @@ -19,7 +19,7 @@ public bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue public async Task WriteAsync(OutputFormatterContext context) { - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; var responseMessage = context.Object as HttpResponseMessage; if (responseMessage == null) @@ -35,7 +35,7 @@ public async Task WriteAsync(OutputFormatterContext context) { response.StatusCode = (int)responseMessage.StatusCode; - var responseFeature = context.ActionContext.HttpContext.GetFeature(); + var responseFeature = context.HttpContext.GetFeature(); if (responseFeature != null) { responseFeature.ReasonPhrase = responseMessage.ReasonPhrase; diff --git a/src/Microsoft.AspNet.Mvc.Xml/XmlDataContractSerializerInputFormatter.cs b/src/Microsoft.AspNet.Mvc.Xml/XmlDataContractSerializerInputFormatter.cs index c21519837f..6e3aff7c51 100644 --- a/src/Microsoft.AspNet.Mvc.Xml/XmlDataContractSerializerInputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Xml/XmlDataContractSerializerInputFormatter.cs @@ -94,7 +94,7 @@ public DataContractSerializerSettings SerializerSettings /// Task which reads the input. public override Task ReadRequestBodyAsync(InputFormatterContext context) { - var request = context.ActionContext.HttpContext.Request; + var request = context.HttpContext.Request; MediaTypeHeaderValue requestContentType; MediaTypeHeaderValue.TryParse(request.ContentType , out requestContentType); @@ -106,7 +106,7 @@ public override Task ReadRequestBodyAsync(InputFormatterContext context) _dataAnnotationRequiredAttributeValidation.Validate( type, - context.ActionContext.ModelState); + context.ModelState); var serializer = GetCachedSerializer(type); diff --git a/src/Microsoft.AspNet.Mvc.Xml/XmlDataContractSerializerOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Xml/XmlDataContractSerializerOutputFormatter.cs index 9fb172b7b7..2303aa3ecb 100644 --- a/src/Microsoft.AspNet.Mvc.Xml/XmlDataContractSerializerOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Xml/XmlDataContractSerializerOutputFormatter.cs @@ -167,7 +167,7 @@ public override Task WriteResponseBodyAsync([NotNull] OutputFormatterContext con var tempWriterSettings = WriterSettings.Clone(); tempWriterSettings.Encoding = context.SelectedEncoding; - var innerStream = context.ActionContext.HttpContext.Response.Body; + var innerStream = context.HttpContext.Response.Body; using (var outputStream = new NonDisposableStream(innerStream)) using (var xmlWriter = CreateXmlWriter(outputStream, tempWriterSettings)) diff --git a/src/Microsoft.AspNet.Mvc.Xml/XmlSerializerInputFormatter.cs b/src/Microsoft.AspNet.Mvc.Xml/XmlSerializerInputFormatter.cs index ce7798caaf..6d958f60f7 100644 --- a/src/Microsoft.AspNet.Mvc.Xml/XmlSerializerInputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Xml/XmlSerializerInputFormatter.cs @@ -70,7 +70,7 @@ public XmlDictionaryReaderQuotas XmlDictionaryReaderQuotas /// Task which reads the input. public override Task ReadRequestBodyAsync(InputFormatterContext context) { - var request = context.ActionContext.HttpContext.Request; + var request = context.HttpContext.Request; MediaTypeHeaderValue requestContentType; MediaTypeHeaderValue.TryParse(request.ContentType, out requestContentType); diff --git a/src/Microsoft.AspNet.Mvc.Xml/XmlSerializerOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Xml/XmlSerializerOutputFormatter.cs index 15cb1d2286..11fb2fdb65 100644 --- a/src/Microsoft.AspNet.Mvc.Xml/XmlSerializerOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Xml/XmlSerializerOutputFormatter.cs @@ -139,12 +139,12 @@ public virtual XmlWriter CreateXmlWriter([NotNull] Stream writeStream, /// public override Task WriteResponseBodyAsync([NotNull] OutputFormatterContext context) { - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; var tempWriterSettings = WriterSettings.Clone(); tempWriterSettings.Encoding = context.SelectedEncoding; - var innerStream = context.ActionContext.HttpContext.Response.Body; + var innerStream = context.HttpContext.Response.Body; using (var outputStream = new NonDisposableStream(innerStream)) using (var xmlWriter = CreateXmlWriter(outputStream, tempWriterSettings)) diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ObjectResultTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ObjectResultTests.cs index 7473b13f00..b7278044af 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ObjectResultTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ObjectResultTests.cs @@ -357,7 +357,7 @@ public void SelectFormatter_WithNoMatchingAcceptHeadersAndRequestContentType_Pic var context = new OutputFormatterContext() { - ActionContext = actionContext, + HttpContext = actionContext.HttpContext, Object = input, DeclaredType = typeof(string) }; @@ -530,7 +530,7 @@ public async Task ObjectResult_Execute_CallsJsonResult_SetsContent() new ActionDescriptor()); var formatterContext = new OutputFormatterContext() { - ActionContext = tempActionContext, + HttpContext = tempActionContext.HttpContext, Object = nonStringValue, DeclaredType = nonStringValue.GetType() }; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonInputFormatterTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonInputFormatterTest.cs index 61ddfe47c5..5cc22d017b 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonInputFormatterTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonInputFormatterTest.cs @@ -38,8 +38,8 @@ public void CanRead_ReturnsTrueForAnySupportedContentType(string requestContentT var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes("content"); - var actionContext = GetActionContext(contentBytes, contentType: requestContentType); - var formatterContext = new InputFormatterContext(actionContext, typeof(string)); + var httpContext = GetHttpContext(contentBytes, contentType: requestContentType); + var formatterContext = new InputFormatterContext(httpContext, new ModelStateDictionary(), typeof(string)); // Act var result = formatter.CanRead(formatterContext); @@ -80,8 +80,8 @@ public async Task JsonFormatterReadsSimpleTypes(string content, Type type, objec var formatter = new JsonInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes(content); - var actionContext = GetActionContext(contentBytes); - var context = new InputFormatterContext(actionContext, type); + var httpContext = GetHttpContext(contentBytes); + var context = new InputFormatterContext(httpContext, new ModelStateDictionary(), type); // Act var model = await formatter.ReadAsync(context); @@ -98,9 +98,8 @@ public async Task JsonFormatterReadsComplexTypes() 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); + var httpContext = GetHttpContext(contentBytes); + var context = new InputFormatterContext(httpContext, new ModelStateDictionary(), typeof(User)); // Act var model = await formatter.ReadAsync(context); @@ -119,16 +118,18 @@ public async Task ReadAsync_AddsModelValidationErrorsToModelState() 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); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes); + + var context = new InputFormatterContext(httpContext, modelState, typeof(User)); // 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); + Assert.Equal( + "Could not convert string to decimal: not-an-age. Path 'Age', line 1, position 39.", + modelState["Age"].Errors[0].Exception.Message); } [Fact] @@ -139,19 +140,21 @@ public async Task ReadAsync_UsesTryAddModelValidationErrorsToModelState() 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"); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes); + + var context = new InputFormatterContext(httpContext, modelState, typeof(User)); + + modelState.MaxAllowedErrors = 3; + modelState.AddModelError("key1", "error1"); + 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.False(modelState.ContainsKey("age")); + var error = Assert.Single(modelState[""].Errors); Assert.IsType(error.Exception); } @@ -189,17 +192,18 @@ public async Task ChangesTo_DefaultSerializerSettings_TakesEffect() // by default we ignore missing members, so here explicitly changing it jsonFormatter.SerializerSettings.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); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes, "application/json;charset=utf-8"); + + var inputFormatterContext = new InputFormatterContext(httpContext, modelState, typeof(UserLogin)); // Act var obj = await jsonFormatter.ReadAsync(inputFormatterContext); // Assert - Assert.False(actionContext.ModelState.IsValid); + Assert.False(modelState.IsValid); - var modelErrorMessage = actionContext.ModelState.Values.First().Errors[0].Exception.Message; + var modelErrorMessage = modelState.Values.First().Errors[0].Exception.Message; Assert.Contains("Required property 'Password' not found in JSON", modelErrorMessage); } @@ -217,51 +221,24 @@ public async Task CustomSerializerSettingsObject_TakesEffect() 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); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes, "application/json;charset=utf-8"); - // 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); - } - - [Fact] - 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); + var inputFormatterContext = new InputFormatterContext(httpContext, modelState, typeof(UserLogin)); // 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); - } + Assert.False(modelState.IsValid); - private static ActionContext GetActionContext(byte[] contentBytes, - string contentType = "application/xml") - { - return new ActionContext(GetHttpContext(contentBytes, contentType), - new AspNet.Routing.RouteData(), - new ActionDescriptor()); + var modelErrorMessage = modelState.Values.First().Errors[0].Exception.Message; + Assert.Contains("Required property 'Password' not found in JSON", modelErrorMessage); } - private static HttpContext GetHttpContext(byte[] contentBytes, - string contentType = "application/json") + private static HttpContext GetHttpContext( + byte[] contentBytes, + string contentType = "application/json") { var request = new Mock(); var headers = new Mock(); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonOutputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonOutputFormatterTests.cs index 6e587a48bc..4cf83dc3ed 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonOutputFormatterTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonOutputFormatterTests.cs @@ -62,11 +62,13 @@ public async Task ChangesTo_DefaultSerializerSettings_TakesEffect() await jsonFormatter.WriteResponseBodyAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - Assert.Equal(expectedOutput, - new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8) - .ReadToEnd()); + var body = outputFormatterContext.HttpContext.Response.Body; + + Assert.NotNull(body); + body.Position = 0; + + var content = new StreamReader(body, Encoding.UTF8).ReadToEnd(); + Assert.Equal(expectedOutput, content); } [Fact] @@ -93,11 +95,13 @@ public async Task CustomSerializerSettingsObject_TakesEffect() await jsonFormatter.WriteResponseBodyAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; + var body = outputFormatterContext.HttpContext.Response.Body; + + Assert.NotNull(body); + body.Position = 0; - var streamReader = new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8); - Assert.Equal(expectedOutput, streamReader.ReadToEnd()); + var content = new StreamReader(body, Encoding.UTF8).ReadToEnd(); + Assert.Equal(expectedOutput, content); } [Fact] @@ -155,12 +159,14 @@ public async Task WriteToStreamAsync_UsesCorrectCharacterEncoding( var encoding = CreateOrGetSupportedEncoding(formatter, encodingAsString, isDefaultEncoding); var expectedData = encoding.GetBytes(formattedContent); - var memStream = new MemoryStream(); + + var body = new MemoryStream(); + var actionContext = GetActionContext(MediaTypeHeaderValue.Parse(mediaType), body); var outputFormatterContext = new OutputFormatterContext { Object = content, DeclaredType = typeof(string), - ActionContext = GetActionContext(MediaTypeHeaderValue.Parse(mediaType), memStream), + HttpContext = actionContext.HttpContext, SelectedEncoding = encoding }; @@ -168,7 +174,7 @@ public async Task WriteToStreamAsync_UsesCorrectCharacterEncoding( await formatter.WriteResponseBodyAsync(outputFormatterContext); // Assert - var actualData = memStream.ToArray(); + var actualData = body.ToArray(); Assert.Equal(expectedData, actualData); } @@ -200,11 +206,12 @@ private static OutputFormatterContext GetOutputFormatterContext( { var mediaTypeHeaderValue = MediaTypeHeaderValue.Parse(contentType); + var actionContext = GetActionContext(mediaTypeHeaderValue, responseStream); return new OutputFormatterContext { Object = outputValue, DeclaredType = outputType, - ActionContext = GetActionContext(mediaTypeHeaderValue, responseStream), + HttpContext = actionContext.HttpContext, SelectedEncoding = Encoding.GetEncoding(mediaTypeHeaderValue.Charset) }; } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonPatchInputFormatterTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonPatchInputFormatterTest.cs index 68e5b591e8..ddd9293a1d 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonPatchInputFormatterTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/JsonPatchInputFormatterTest.cs @@ -23,8 +23,9 @@ public async Task JsonPatchInputFormatter_ReadsOneOperation_Successfully() var content = "[{\"op\":\"add\",\"path\":\"Customer/Name\",\"value\":\"John\"}]"; var contentBytes = Encoding.UTF8.GetBytes(content); - var actionContext = GetActionContext(contentBytes); - var context = new InputFormatterContext(actionContext, typeof(JsonPatchDocument)); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes); + var context = new InputFormatterContext(httpContext, modelState, typeof(JsonPatchDocument)); // Act var model = await formatter.ReadAsync(context); @@ -45,8 +46,9 @@ public async Task JsonPatchInputFormatter_ReadsMultipleOperations_Successfully() "{\"op\": \"remove\", \"path\" : \"Customer/Name\"}]"; var contentBytes = Encoding.UTF8.GetBytes(content); - var actionContext = GetActionContext(contentBytes); - var context = new InputFormatterContext(actionContext, typeof(JsonPatchDocument)); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes); + var context = new InputFormatterContext(httpContext, modelState, typeof(JsonPatchDocument)); // Act var model = await formatter.ReadAsync(context); @@ -72,8 +74,12 @@ public void CanRead_ReturnsTrueOnlyForJsonPatchContentType(string requestContent var content = "[{\"op\": \"add\", \"path\" : \"Customer/Name\", \"value\":\"John\"}]"; var contentBytes = Encoding.UTF8.GetBytes(content); - var actionContext = GetActionContext(contentBytes, contentType: requestContentType); - var formatterContext = new InputFormatterContext(actionContext, typeof(JsonPatchDocument)); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes, contentType: requestContentType); + var formatterContext = new InputFormatterContext( + httpContext, + modelState, + typeof(JsonPatchDocument)); // Act var result = formatter.CanRead(formatterContext); @@ -92,8 +98,9 @@ public void CanRead_ReturnsFalse_NonJsonPatchContentType(Type modelType) var content = "[{\"op\": \"add\", \"path\" : \"Customer/Name\", \"value\":\"John\"}]"; var contentBytes = Encoding.UTF8.GetBytes(content); - var actionContext = GetActionContext(contentBytes, contentType: "application/json-patch+json"); - var formatterContext = new InputFormatterContext(actionContext, modelType); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes, contentType: "application/json-patch+json"); + var formatterContext = new InputFormatterContext(httpContext, modelState, modelType); // Act var result = formatter.CanRead(formatterContext); @@ -113,25 +120,20 @@ public async Task JsonPatchInputFormatter_ReturnsModelStateErrors_InvalidModelTy var content = "[{\"op\": \"add\", \"path\" : \"Customer/Name\", \"value\":\"John\"}]"; var contentBytes = Encoding.UTF8.GetBytes(content); - var actionContext = GetActionContext(contentBytes, contentType: "application/json-patch+json"); - var context = new InputFormatterContext(actionContext, typeof(Customer)); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes, contentType: "application/json-patch+json"); + + var context = new InputFormatterContext(httpContext, modelState, typeof(Customer)); // Act var model = await formatter.ReadAsync(context); // Assert - Assert.Contains(exceptionMessage, actionContext.ModelState[""].Errors[0].Exception.Message); - } - - private static ActionContext GetActionContext(byte[] contentBytes, - string contentType = "application/json-patch+json") - { - return new ActionContext(GetHttpContext(contentBytes, contentType), - new AspNet.Routing.RouteData(), - new ActionDescriptor()); + Assert.Contains(exceptionMessage, modelState[""].Errors[0].Exception.Message); } - private static HttpContext GetHttpContext(byte[] contentBytes, + private static HttpContext GetHttpContext( + byte[] contentBytes, string contentType = "application/json-patch+json") { var request = new Mock(); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/NoContentFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/NoContentFormatterTests.cs index 5d64d0116d..7cacfa84f8 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/NoContentFormatterTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/NoContentFormatterTests.cs @@ -45,7 +45,7 @@ public void CanWriteResult_ByDefault_ReturnsTrue_IfTheValueIsNull(object value, { Object = value, DeclaredType = typeToUse, - ActionContext = null, + HttpContext = null, }; var contetType = useNonNullContentType ? MediaTypeHeaderValue.Parse("text/plain") : null; var formatter = new HttpNoContentOutputFormatter(); @@ -67,7 +67,7 @@ public void CanWriteResult_ReturnsTrue_IfReturnTypeIsVoidOrTask(Type declaredTyp { Object = "Something non null.", DeclaredType = declaredType, - ActionContext = null, + HttpContext = null, }; var contetType = MediaTypeHeaderValue.Parse("text/plain"); var formatter = new HttpNoContentOutputFormatter(); @@ -93,7 +93,7 @@ public void { Object = value, DeclaredType = typeof(string), - ActionContext = null, + HttpContext = null, }; var contetType = MediaTypeHeaderValue.Parse("text/plain"); @@ -117,7 +117,7 @@ public async Task WriteAsync_WritesTheStatusCode204() var formatterContext = new OutputFormatterContext() { Object = null, - ActionContext = new ActionContext(defaultHttpContext, new RouteData(), new ActionDescriptor()) + HttpContext = defaultHttpContext, }; var formatter = new HttpNoContentOutputFormatter(); @@ -137,7 +137,7 @@ public async Task WriteAsync_ContextStatusCodeSet_WritesSameStatusCode() var formatterContext = new OutputFormatterContext() { Object = null, - ActionContext = new ActionContext(defaultHttpContext, new RouteData(), new ActionDescriptor()), + HttpContext = defaultHttpContext, StatusCode = StatusCodes.Status201Created }; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/OutputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/OutputFormatterTests.cs index 6fe9bc8e49..21bcdce2ec 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/OutputFormatterTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/OutputFormatterTests.cs @@ -54,7 +54,7 @@ public void SelectResponseCharacterEncoding_SelectsEncoding(string acceptCharset httpRequest.Headers["Accept-Charset"] = acceptCharsetHeaders; httpRequest.ContentType = "application/acceptCharset;charset=" + requestEncoding; mockHttpContext.SetupGet(o => o.Request).Returns(httpRequest); - var actionContext = new ActionContext(mockHttpContext.Object, new RouteData(), new ActionDescriptor()); + var formatter = new TestOutputFormatter(); foreach (string supportedEncoding in supportedEncodings) { @@ -64,7 +64,7 @@ public void SelectResponseCharacterEncoding_SelectsEncoding(string acceptCharset var formatterContext = new OutputFormatterContext() { Object = "someValue", - ActionContext = actionContext, + HttpContext = mockHttpContext.Object, DeclaredType = typeof(string) }; @@ -85,8 +85,7 @@ public void WriteResponseContentHeaders_FormatterWithNoEncoding_Throws() var mockHttpContext = new Mock(); var httpRequest = new DefaultHttpContext().Request; mockHttpContext.SetupGet(o => o.Request).Returns(httpRequest); - var actionContext = new ActionContext(mockHttpContext.Object, new RouteData(), new ActionDescriptor()); - formatterContext.ActionContext = actionContext; + formatterContext.HttpContext = mockHttpContext.Object; // Act & Assert var ex = Assert.Throws( @@ -108,8 +107,7 @@ public void WriteResponseContentHeaders_NoSelectedContentType_SetsOutputFormatte var httpRequest = new DefaultHttpContext().Request; mockHttpContext.SetupGet(o => o.Request).Returns(httpRequest); mockHttpContext.SetupProperty(o => o.Response.ContentType); - var actionContext = new ActionContext(mockHttpContext.Object, new RouteData(), new ActionDescriptor()); - formatterContext.ActionContext = actionContext; + formatterContext.HttpContext = mockHttpContext.Object; // Act testFormatter.WriteResponseHeaders(formatterContext); @@ -130,10 +128,7 @@ public async Task WriteResponseHeaders_ClonesMediaType() var mediaType = new MediaTypeHeaderValue("image/png"); formatter.SupportedMediaTypes.Add(mediaType); var formatterContext = new OutputFormatterContext(); - formatterContext.ActionContext = new ActionContext( - new DefaultHttpContext(), - new RouteData(), - new ActionDescriptor()); + formatterContext.HttpContext = new DefaultHttpContext(); // Act await formatter.WriteAsync(formatterContext); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/StringOutputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/StringOutputFormatterTests.cs index f222011527..4668a81dff 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/StringOutputFormatterTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/StringOutputFormatterTests.cs @@ -64,7 +64,7 @@ public async Task WriteAsync_DoesNotWriteNullStrings() { Object = null, DeclaredType = typeof(string), - ActionContext = new ActionContext(mockHttpContext.Object, new RouteData(), new ActionDescriptor()), + HttpContext = mockHttpContext.Object, SelectedEncoding = encoding }; diff --git a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/HttpResponseMessageOutputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/HttpResponseMessageOutputFormatterTests.cs index 572d2ee5f0..7267c2d643 100644 --- a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/HttpResponseMessageOutputFormatterTests.cs +++ b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/HttpResponseMessageOutputFormatterTests.cs @@ -143,7 +143,7 @@ private OutputFormatterContext GetOutputFormatterContext(object outputValue, Typ { Object = outputValue, DeclaredType = outputType, - ActionContext = new ActionContext(httpContext, routeData: null, actionDescriptor: null) + HttpContext = httpContext, }; } } diff --git a/test/Microsoft.AspNet.Mvc.Xml.Test/XmlDataContractSerializerInputFormatterTest.cs b/test/Microsoft.AspNet.Mvc.Xml.Test/XmlDataContractSerializerInputFormatterTest.cs index 3408bfb626..0e236923e4 100644 --- a/test/Microsoft.AspNet.Mvc.Xml.Test/XmlDataContractSerializerInputFormatterTest.cs +++ b/test/Microsoft.AspNet.Mvc.Xml.Test/XmlDataContractSerializerInputFormatterTest.cs @@ -79,8 +79,9 @@ public void CanRead_ReturnsTrueForAnySupportedContentType(string requestContentT var formatter = new XmlDataContractSerializerInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes("content"); - var actionContext = GetActionContext(contentBytes, contentType: requestContentType); - var formatterContext = new InputFormatterContext(actionContext, typeof(string)); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes, contentType: requestContentType); + var formatterContext = new InputFormatterContext(httpContext, modelState, typeof(string)); // Act var result = formatter.CanRead(formatterContext); @@ -285,7 +286,7 @@ public async Task ReadAsync_VerifyStreamIsOpenAfterRead() // Assert Assert.NotNull(model); - Assert.True(context.ActionContext.HttpContext.Request.Body.CanRead); + Assert.True(context.HttpContext.Request.Body.CanRead); } [Fact] @@ -328,8 +329,11 @@ public async Task ReadAsync_UsesContentTypeCharSet_ToReadStream() "1000"); var formatter = new XmlDataContractSerializerInputFormatter(); - var actionContext = GetActionContext(inputBytes, contentType: "application/xml; charset=utf-16"); - var context = new InputFormatterContext(actionContext, typeof(TestLevelOne)); + + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(inputBytes, contentType: "application/xml; charset=utf-16"); + + var context = new InputFormatterContext(httpContext, modelState, typeof(TestLevelOne)); // Act var ex = await Assert.ThrowsAsync(expectedException, () => formatter.ReadAsync(context)); @@ -381,8 +385,10 @@ public async Task ReadAsync_AcceptsUTF16Characters() var formatter = new XmlDataContractSerializerInputFormatter(); var contentBytes = Encodings.UTF16EncodingLittleEndian.GetBytes(input); - var actionContext = GetActionContext(contentBytes, contentType: "application/xml; charset=utf-16"); - var context = new InputFormatterContext(actionContext, typeof(TestLevelOne)); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes, contentType: "application/xml; charset=utf-16"); + + var context = new InputFormatterContext(httpContext, modelState, typeof(TestLevelOne)); // Act var model = await formatter.ReadAsync(context); @@ -530,10 +536,10 @@ public async Task PostingListOfModels_HasRequiredAttributeValidationErrors() Assert.Equal(98052, model[0].Zipcode); Assert.Equal(true, model[0].IsResidential); - Assert.Equal(1, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(1, context.ModelState.Keys.Count); AssertModelStateErrorMessages( typeof(Address).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Address.Zipcode), typeof(Address).FullName), @@ -564,10 +570,10 @@ public async Task PostingModel_HasRequiredAttributeValidationErrors() Assert.Equal(98052, model.Zipcode); Assert.Equal(true, model.IsResidential); - Assert.Equal(1, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(1, context.ModelState.Keys.Count); AssertModelStateErrorMessages( typeof(Address).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Address.Zipcode), typeof(Address).FullName), @@ -603,10 +609,10 @@ public async Task PostingModelWithProperty_HasRequiredAttributeValidationErrors( Assert.Equal(98052, model.AddressProperty.Zipcode); Assert.Equal(true, model.AddressProperty.IsResidential); - Assert.Equal(1, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(1, context.ModelState.Keys.Count); AssertModelStateErrorMessages( typeof(Address).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Address.Zipcode), typeof(Address).FullName), @@ -640,11 +646,11 @@ public async Task PostingModel_WithCollectionProperty_HasRequiredAttributeValida Assert.Equal(98052, model.Addresses[0].Zipcode); Assert.Equal(true, model.Addresses[0].IsResidential); - Assert.Equal(1, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(1, context.ModelState.Keys.Count); AssertModelStateErrorMessages( - modelStateKey: typeof(Address).FullName, - actionContext: context.ActionContext, - expectedErrorMessages: new[] + typeof(Address).FullName, + context, + new[] { string.Format(requiredErrorMessageFormat, nameof(Address.Zipcode), typeof(Address).FullName), string.Format(requiredErrorMessageFormat, nameof(Address.IsResidential), typeof(Address).FullName) @@ -676,10 +682,10 @@ public async Task PostingModelInheritingType_HasRequiredAttributeValidationError Assert.Equal(98052, model.Zipcode); Assert.Equal(true, model.IsResidential); - Assert.Equal(1, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(1, context.ModelState.Keys.Count); AssertModelStateErrorMessages( typeof(Address).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Address.Zipcode), typeof(Address).FullName), @@ -710,7 +716,7 @@ public async Task PostingModelHavingNullableValueTypes_NoRequiredAttributeValida Assert.NotNull(model); Assert.Equal(expectedModel.Year, model.Year); Assert.Equal(expectedModel.ServicedYears, model.ServicedYears); - Assert.Empty(context.ActionContext.ModelState); + Assert.Empty(context.ModelState); } [Fact] @@ -745,7 +751,7 @@ public async Task PostingModel_WithPropertyHavingNullableValueTypes_NoRequiredAt Assert.NotNull(model.CarInfoProperty); Assert.Equal(expectedModel.CarInfoProperty.Year, model.CarInfoProperty.Year); Assert.Equal(expectedModel.CarInfoProperty.ServicedYears, model.CarInfoProperty.ServicedYears); - Assert.Empty(context.ActionContext.ModelState); + Assert.Empty(context.ModelState); } [Fact] @@ -781,10 +787,10 @@ public async Task PostingModel_WithPropertySelfReferencingItself() Assert.Equal(expectedModel.Manager.Name, model.Manager.Name); Assert.Null(model.Manager.Manager); - Assert.Equal(1, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(1, context.ModelState.Keys.Count); AssertModelStateErrorMessages( typeof(Employee).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Employee.Id), typeof(Employee).FullName) @@ -810,7 +816,7 @@ public async Task PostingModel_WithBothRequiredAndDataMemberRequired_NoValidatio Assert.NotNull(model); Assert.Equal(10, model.Id); Assert.Equal(true, model.SupportsVirtualization); - Assert.Empty(context.ActionContext.ModelState); + Assert.Empty(context.ModelState); } [Fact] @@ -833,7 +839,7 @@ public async Task PostingListofModels_WithBothRequiredAndDataMemberRequired_NoVa Assert.Equal(1, model.Count); Assert.Equal(10, model[0].Id); Assert.Equal(true, model[0].SupportsVirtualization); - Assert.Empty(context.ActionContext.ModelState); + Assert.Empty(context.ModelState); } [Fact] @@ -855,10 +861,10 @@ public async Task PostingModel_WithRequiredAndDataMemberNoRequired_HasValidation Assert.NotNull(model); Assert.Equal(10, model.Id); - Assert.Equal(2, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(2, context.ModelState.Keys.Count); AssertModelStateErrorMessages( typeof(Product).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Product.Id), typeof(Product).FullName) @@ -866,7 +872,7 @@ public async Task PostingModel_WithRequiredAndDataMemberNoRequired_HasValidation AssertModelStateErrorMessages( typeof(Address).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Address.Zipcode), typeof(Address).FullName), @@ -895,10 +901,10 @@ public async Task PostingListOfModels_WithRequiredAndDataMemberNoRequired_HasVal Assert.Equal(10, model[0].Id); Assert.Equal("Phone", model[0].Name); - Assert.Equal(2, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(2, context.ModelState.Keys.Count); AssertModelStateErrorMessages( typeof(Product).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Product.Id), typeof(Product).FullName) @@ -906,7 +912,7 @@ public async Task PostingListOfModels_WithRequiredAndDataMemberNoRequired_HasVal AssertModelStateErrorMessages( typeof(Address).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Address.Zipcode), typeof(Address).FullName), @@ -931,10 +937,10 @@ public async Task PostingModel_WithDeeperHierarchy_HasValidationErrors() // Assert Assert.Null(model); - Assert.Equal(3, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(3, context.ModelState.Keys.Count); AssertModelStateErrorMessages( typeof(Address).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Address.IsResidential), typeof(Address).FullName), @@ -943,7 +949,7 @@ public async Task PostingModel_WithDeeperHierarchy_HasValidationErrors() AssertModelStateErrorMessages( typeof(Employee).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Employee.Id), typeof(Employee).FullName) @@ -951,7 +957,7 @@ public async Task PostingModel_WithDeeperHierarchy_HasValidationErrors() AssertModelStateErrorMessages( typeof(Product).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Product.Id), typeof(Product).FullName) @@ -976,17 +982,17 @@ public async Task PostingModelOfStructs_WithDeeperHierarchy_HasValidationErrors( // Assert Assert.Null(model); - Assert.Equal(3, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(3, context.ModelState.Keys.Count); AssertModelStateErrorMessages( typeof(School).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(School.Id), typeof(School).FullName) }); AssertModelStateErrorMessages( typeof(Website).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Website.Id), typeof(Website).FullName) @@ -994,7 +1000,7 @@ public async Task PostingModelOfStructs_WithDeeperHierarchy_HasValidationErrors( AssertModelStateErrorMessages( typeof(Student).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Student.Id), typeof(Student).FullName) @@ -1019,10 +1025,10 @@ public async Task PostingModel_WithDictionaryProperty_HasValidationErrorsOnKeyAn // Assert Assert.Null(model); - Assert.Equal(2, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(2, context.ModelState.Keys.Count); AssertModelStateErrorMessages( typeof(Point).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Point.X), typeof(Point).FullName), @@ -1030,7 +1036,7 @@ public async Task PostingModel_WithDictionaryProperty_HasValidationErrorsOnKeyAn }); AssertModelStateErrorMessages( typeof(Address).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Address.IsResidential), typeof(Address).FullName), @@ -1056,10 +1062,10 @@ public async Task PostingModel_WithDifferentValueTypeProperties_HasValidationErr // Assert Assert.Null(model); - Assert.Equal(3, context.ActionContext.ModelState.Keys.Count); + Assert.Equal(3, context.ModelState.Keys.Count); AssertModelStateErrorMessages( typeof(Point).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format(requiredErrorMessageFormat, nameof(Point.X), typeof(Point).FullName), @@ -1067,7 +1073,7 @@ public async Task PostingModel_WithDifferentValueTypeProperties_HasValidationErr }); AssertModelStateErrorMessages( typeof(GpsCoordinate).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format( @@ -1081,7 +1087,7 @@ public async Task PostingModel_WithDifferentValueTypeProperties_HasValidationErr }); AssertModelStateErrorMessages( typeof(ValueTypePropertiesModel).FullName, - context.ActionContext, + context, expectedErrorMessages: new[] { string.Format( @@ -1105,11 +1111,11 @@ public async Task PostingModel_WithDifferentValueTypeProperties_HasValidationErr private void AssertModelStateErrorMessages( string modelStateKey, - ActionContext actionContext, + InputFormatterContext context, IEnumerable expectedErrorMessages) { ModelState modelState; - actionContext.ModelState.TryGetValue(modelStateKey, out modelState); + context.ModelState.TryGetValue(modelStateKey, out modelState); Assert.NotNull(modelState); Assert.NotEmpty(modelState.Errors); @@ -1140,20 +1146,13 @@ private void AssertModelStateErrorMessages( private InputFormatterContext GetInputFormatterContext(byte[] contentBytes, Type modelType) { - var actionContext = GetActionContext(contentBytes); - var metadata = new EmptyModelMetadataProvider().GetMetadataForType(modelType); - return new InputFormatterContext(actionContext, metadata.ModelType); + var httpContext = GetHttpContext(contentBytes); + return new InputFormatterContext(httpContext, new ModelStateDictionary(), modelType); } - private static ActionContext GetActionContext(byte[] contentBytes, - string contentType = "application/xml") - { - return new ActionContext(GetHttpContext(contentBytes, contentType), - new AspNet.Routing.RouteData(), - new ActionDescriptor()); - } - private static HttpContext GetHttpContext(byte[] contentBytes, - string contentType = "application/xml") + private static HttpContext GetHttpContext( + byte[] contentBytes, + string contentType = "application/xml") { var request = new Mock(); var headers = new Mock(); diff --git a/test/Microsoft.AspNet.Mvc.Xml.Test/XmlDataContractSerializerOutputFormatterTest.cs b/test/Microsoft.AspNet.Mvc.Xml.Test/XmlDataContractSerializerOutputFormatterTest.cs index 384d1766b9..087d66b04d 100644 --- a/test/Microsoft.AspNet.Mvc.Xml.Test/XmlDataContractSerializerOutputFormatterTest.cs +++ b/test/Microsoft.AspNet.Mvc.Xml.Test/XmlDataContractSerializerOutputFormatterTest.cs @@ -102,12 +102,11 @@ public async Task WriteAsync_CanWriteBasicTypes(object input, string expectedOut await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - XmlAssert.Equal(expectedOutput, - new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8) - .ReadToEnd()); - Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] @@ -158,17 +157,22 @@ public async Task SuppliedWriterSettings_TakeAffect() // Assert Assert.Same(writerSettings, formatter.WriterSettings); - var responseStream = formatterContext.ActionContext.HttpContext.Response.Body; - Assert.NotNull(responseStream); - responseStream.Position = 0; - var actualOutput = new StreamReader(responseStream, Encoding.UTF8).ReadToEnd(); - XmlAssert.Equal(expectedOutput, actualOutput); + + var body = formatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] public async Task WriteAsync_WritesSimpleTypes() { // Arrange + var expectedOutput = + "" + + "10"; + var sampleInput = new DummyClass { SampleInt = 10 }; var formatter = new XmlDataContractSerializerOutputFormatter(); var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType()); @@ -177,18 +181,23 @@ public async Task WriteAsync_WritesSimpleTypes() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - XmlAssert.Equal("" + - "10", - new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8) - .ReadToEnd()); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] public async Task WriteAsync_WritesComplexTypes() { // Arrange + var expectedOutput = + "" + + "TestString" + + "10TestLevelOne string" + + ""; + var sampleInput = new TestLevelTwo { SampleString = "TestString", @@ -205,24 +214,26 @@ public async Task WriteAsync_WritesComplexTypes() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - XmlAssert.Equal("" + - "TestString" + - "10TestLevelOne string" + - "", - new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8) - .ReadToEnd()); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] public async Task WriteAsync_WritesOnModifiedWriterSettings() { // Arrange + var expectedOutput = + "" + + "" + + "10"; + var sampleInput = new DummyClass { SampleInt = 10 }; var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType()); var formatter = new XmlDataContractSerializerOutputFormatter( - new System.Xml.XmlWriterSettings + new XmlWriterSettings { OmitXmlDeclaration = false, CloseOutput = false @@ -232,19 +243,22 @@ public async Task WriteAsync_WritesOnModifiedWriterSettings() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - XmlAssert.Equal("" + - "" + - "10", - new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, - Encoding.UTF8).ReadToEnd()); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] public async Task WriteAsync_WritesUTF16Output() { // Arrange + var expectedOutput = + "" + + "" + + "10"; + var sampleInput = new DummyClass { SampleInt = 10 }; var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType(), "application/xml; charset=utf-16"); @@ -255,19 +269,21 @@ public async Task WriteAsync_WritesUTF16Output() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - XmlAssert.Equal("" + - "" + - "10", - new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, - Encodings.UTF16EncodingLittleEndian).ReadToEnd()); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] public async Task WriteAsync_WritesIndentedOutput() { // Arrange + var expectedOutput = + "" + + "\r\n 10\r\n"; + var sampleInput = new DummyClass { SampleInt = 10 }; var formatter = new XmlDataContractSerializerOutputFormatter(); formatter.WriterSettings.Indent = true; @@ -277,13 +293,11 @@ public async Task WriteAsync_WritesIndentedOutput() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - var outputString = new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, - Encoding.UTF8).ReadToEnd(); - XmlAssert.Equal("" + - "\r\n 10\r\n", - outputString); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] @@ -298,8 +312,8 @@ public async Task WriteAsync_VerifyBodyIsNotClosedAfterOutputIsWritten() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead); + var body = outputFormatterContext.HttpContext.Response.Body; + Assert.True(body.CanRead); } [Fact] @@ -310,7 +324,7 @@ public async Task WriteAsync_DoesntFlushOutputStream() var formatter = new XmlDataContractSerializerOutputFormatter(); var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType()); - var response = outputFormatterContext.ActionContext.HttpContext.Response; + var response = outputFormatterContext.HttpContext.Response; response.Body = FlushReportingStream.GetThrowingStream(); // Act & Assert @@ -447,11 +461,11 @@ public async Task WriteAsync_WritesWhenConfiguredWithRootName() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - var actualOutput = new StreamReader( - outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8).ReadToEnd(); - XmlAssert.Equal(expectedOutput, actualOutput); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] @@ -491,11 +505,11 @@ public async Task WriteAsync_WritesWhenConfiguredWithKnownTypes() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - var actualOutput = new StreamReader( - outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8).ReadToEnd(); - XmlAssert.Equal(expectedOutput, actualOutput); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] @@ -535,11 +549,11 @@ public async Task WriteAsync_WritesWhenConfiguredWithPreserveReferences() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - var actualOutput = new StreamReader( - outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8).ReadToEnd(); - XmlAssert.Equal(expectedOutput, actualOutput); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } private OutputFormatterContext GetOutputFormatterContext(object outputValue, Type outputType, @@ -549,23 +563,26 @@ private OutputFormatterContext GetOutputFormatterContext(object outputValue, Typ { Object = outputValue, DeclaredType = outputType, - ActionContext = GetActionContext(contentType) + HttpContext = GetHttpContext(contentType) }; } - private static ActionContext GetActionContext(string contentType) + private static HttpContext GetHttpContext(string contentType) { var request = new Mock(); + var headers = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase)); headers["Accept-Charset"] = MediaTypeHeaderValue.Parse(contentType).Charset; request.Setup(r => r.ContentType).Returns(contentType); request.SetupGet(r => r.Headers).Returns(headers); + var response = new Mock(); response.SetupGet(f => f.Body).Returns(new MemoryStream()); + var httpContext = new Mock(); httpContext.SetupGet(c => c.Request).Returns(request.Object); httpContext.SetupGet(c => c.Response).Returns(response.Object); - return new ActionContext(httpContext.Object, routeData: null, actionDescriptor: null); + return httpContext.Object; } private class TestXmlDataContractSerializerOutputFormatter : XmlDataContractSerializerOutputFormatter diff --git a/test/Microsoft.AspNet.Mvc.Xml.Test/XmlSerializerInputFormatterTest.cs b/test/Microsoft.AspNet.Mvc.Xml.Test/XmlSerializerInputFormatterTest.cs index 24fa22ccec..418c82918c 100644 --- a/test/Microsoft.AspNet.Mvc.Xml.Test/XmlSerializerInputFormatterTest.cs +++ b/test/Microsoft.AspNet.Mvc.Xml.Test/XmlSerializerInputFormatterTest.cs @@ -56,8 +56,10 @@ public void CanRead_ReturnsTrueForAnySupportedContentType(string requestContentT var formatter = new XmlSerializerInputFormatter(); var contentBytes = Encoding.UTF8.GetBytes("content"); - var actionContext = GetActionContext(contentBytes, contentType: requestContentType); - var formatterContext = new InputFormatterContext(actionContext, typeof(string)); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes, contentType: requestContentType); + + var formatterContext = new InputFormatterContext(httpContext, modelState, typeof(string)); // Act var result = formatter.CanRead(formatterContext); @@ -292,7 +294,7 @@ public async Task ReadAsync_VerifyStreamIsOpenAfterRead() // Assert Assert.NotNull(model); - Assert.True(context.ActionContext.HttpContext.Request.Body.CanRead); + Assert.True(context.HttpContext.Request.Body.CanRead); } [Fact] @@ -337,8 +339,11 @@ public async Task ReadAsync_UsesContentTypeCharSet_ToReadStream() "1000"); var formatter = new XmlSerializerInputFormatter(); - var actionContext = GetActionContext(inputBytes, contentType: "application/xml; charset=utf-16"); - var context = new InputFormatterContext(actionContext, typeof(TestLevelOne)); + + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(inputBytes, contentType: "application/xml; charset=utf-16"); + + var context = new InputFormatterContext(httpContext, modelState, typeof(TestLevelOne)); // Act and Assert var ex = await Assert.ThrowsAsync(expectedException, () => formatter.ReadAsync(context)); @@ -392,8 +397,9 @@ public async Task ReadAsync_AcceptsUTF16Characters() var formatter = new XmlSerializerInputFormatter(); var contentBytes = Encodings.UTF16EncodingLittleEndian.GetBytes(input); - var actionContext = GetActionContext(contentBytes, contentType: "application/xml; charset=utf-16"); - var context = new InputFormatterContext(actionContext, typeof(TestLevelOne)); + var modelState = new ModelStateDictionary(); + var httpContext = GetHttpContext(contentBytes, contentType: "application/xml; charset=utf-16"); + var context = new InputFormatterContext(httpContext, modelState, typeof(TestLevelOne)); // Act var model = await formatter.ReadAsync(context); @@ -410,21 +416,13 @@ public async Task ReadAsync_AcceptsUTF16Characters() private InputFormatterContext GetInputFormatterContext(byte[] contentBytes, Type modelType) { - var actionContext = GetActionContext(contentBytes); - var metadata = new EmptyModelMetadataProvider().GetMetadataForType(modelType); - return new InputFormatterContext(actionContext, metadata.ModelType); - } - - private static ActionContext GetActionContext(byte[] contentBytes, - string contentType = "application/xml") - { - return new ActionContext(GetHttpContext(contentBytes, contentType), - new AspNet.Routing.RouteData(), - new ActionDescriptor()); + var httpContext = GetHttpContext(contentBytes); + return new InputFormatterContext(httpContext, new ModelStateDictionary(), modelType); } - private static HttpContext GetHttpContext(byte[] contentBytes, - string contentType = "application/xml") + private static HttpContext GetHttpContext( + byte[] contentBytes, + string contentType = "application/xml") { var request = new Mock(); var headers = new Mock(); diff --git a/test/Microsoft.AspNet.Mvc.Xml.Test/XmlSerializerOutputFormatterTest.cs b/test/Microsoft.AspNet.Mvc.Xml.Test/XmlSerializerOutputFormatterTest.cs index b8d302b665..7c8764afe2 100644 --- a/test/Microsoft.AspNet.Mvc.Xml.Test/XmlSerializerOutputFormatterTest.cs +++ b/test/Microsoft.AspNet.Mvc.Xml.Test/XmlSerializerOutputFormatterTest.cs @@ -60,12 +60,11 @@ public async Task XmlSerializerOutputFormatterCanWriteBasicTypes(object input, s await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - XmlAssert.Equal(expectedOutput, - new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8) - .ReadToEnd()); - Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] @@ -115,18 +114,21 @@ public async Task SuppliedWriterSettings_TakeAffect() await formatter.WriteAsync(formatterContext); // Assert - Assert.Same(writerSettings, formatter.WriterSettings); - var responseStream = formatterContext.ActionContext.HttpContext.Response.Body; - Assert.NotNull(responseStream); - responseStream.Position = 0; - var actualOutput = new StreamReader(responseStream, Encoding.UTF8).ReadToEnd(); - XmlAssert.Equal(expectedOutput, actualOutput); + var body = formatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] public async Task XmlSerializerOutputFormatterWritesSimpleTypes() { // Arrange + var expectedOutput = + "10"; + var sampleInput = new DummyClass { SampleInt = 10 }; var formatter = new XmlSerializerOutputFormatter(); var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType()); @@ -135,19 +137,23 @@ public async Task XmlSerializerOutputFormatterWritesSimpleTypes() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - XmlAssert.Equal("10", - new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8) - .ReadToEnd()); - Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] public async Task XmlSerializerOutputFormatterWritesComplexTypes() { // Arrange + var expectedOutput = + "TestString" + + "TestLevelOne string" + + "10"; + var sampleInput = new TestLevelTwo { SampleString = "TestString", @@ -164,20 +170,22 @@ public async Task XmlSerializerOutputFormatterWritesComplexTypes() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - XmlAssert.Equal("TestString" + - "TestLevelOne string" + - "10", - new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8) - .ReadToEnd()); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] public async Task XmlSerializerOutputFormatterWritesOnModifiedWriterSettings() { // Arrange + var expectedOutput = + "" + + "10"; + var sampleInput = new DummyClass { SampleInt = 10 }; var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType()); var formatter = new XmlSerializerOutputFormatter( @@ -191,19 +199,22 @@ public async Task XmlSerializerOutputFormatterWritesOnModifiedWriterSettings() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - XmlAssert.Equal("" + - "10", - new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8) - .ReadToEnd()); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] public async Task XmlSerializerOutputFormatterWritesUTF16Output() { // Arrange + var expectedOutput = + "" + + "10"; + var sampleInput = new DummyClass { SampleInt = 10 }; var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType(), "application/xml; charset=utf-16"); @@ -214,19 +225,21 @@ public async Task XmlSerializerOutputFormatterWritesUTF16Output() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - XmlAssert.Equal("" + - "10", - new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, - Encodings.UTF16EncodingLittleEndian).ReadToEnd()); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] public async Task XmlSerializerOutputFormatterWritesIndentedOutput() { // Arrange + var expectedOutput = + "\r\n 10\r\n"; + var sampleInput = new DummyClass { SampleInt = 10 }; var formatter = new XmlSerializerOutputFormatter(); formatter.WriterSettings.Indent = true; @@ -236,13 +249,11 @@ public async Task XmlSerializerOutputFormatterWritesIndentedOutput() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0; - var outputString = new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, - Encoding.UTF8).ReadToEnd(); - XmlAssert.Equal("\r\n 10\r\n", - outputString); + var body = outputFormatterContext.HttpContext.Response.Body; + body.Position = 0; + + var content = new StreamReader(body).ReadToEnd(); + XmlAssert.Equal(expectedOutput, content); } [Fact] @@ -257,8 +268,8 @@ public async Task VerifyBodyIsNotClosedAfterOutputIsWritten() await formatter.WriteAsync(outputFormatterContext); // Assert - Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body); - Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead); + Assert.NotNull(outputFormatterContext.HttpContext.Response.Body); + Assert.True(outputFormatterContext.HttpContext.Response.Body.CanRead); } public static IEnumerable TypesForCanWriteResult @@ -304,7 +315,7 @@ public async Task XmlSerializerOutputFormatterDoesntFlushOutputStream() var formatter = new XmlSerializerOutputFormatter(); var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType()); - var response = outputFormatterContext.ActionContext.HttpContext.Response; + var response = outputFormatterContext.HttpContext.Response; response.Body = FlushReportingStream.GetThrowingStream(); // Act & Assert @@ -346,30 +357,35 @@ public void XmlSerializer_GetSupportedContentTypes_Returns_SupportedTypes(Type d } } - private OutputFormatterContext GetOutputFormatterContext(object outputValue, Type outputType, - string contentType = "application/xml; charset=utf-8") + private OutputFormatterContext GetOutputFormatterContext( + object outputValue, + Type outputType, + string contentType = "application/xml; charset=utf-8") { return new OutputFormatterContext { Object = outputValue, DeclaredType = outputType, - ActionContext = GetActionContext(contentType) + HttpContext = GetHttpContext(contentType) }; } - private static ActionContext GetActionContext(string contentType) + private static HttpContext GetHttpContext(string contentType) { var request = new Mock(); + var headers = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase)); headers["Accept-Charset"] = MediaTypeHeaderValue.Parse(contentType).Charset; request.Setup(r => r.ContentType).Returns(contentType); request.SetupGet(r => r.Headers).Returns(headers); + var response = new Mock(); response.SetupGet(f => f.Body).Returns(new MemoryStream()); + var httpContext = new Mock(); httpContext.SetupGet(c => c.Request).Returns(request.Object); httpContext.SetupGet(c => c.Response).Returns(response.Object); - return new ActionContext(httpContext.Object, routeData: null, actionDescriptor: null); + return httpContext.Object; } private class TestXmlSerializerOutputFormatter : XmlSerializerOutputFormatter diff --git a/test/WebSites/ContentNegotiationWebSite/CustomFormatter.cs b/test/WebSites/ContentNegotiationWebSite/CustomFormatter.cs index ff34277cd6..6a0d473920 100644 --- a/test/WebSites/ContentNegotiationWebSite/CustomFormatter.cs +++ b/test/WebSites/ContentNegotiationWebSite/CustomFormatter.cs @@ -35,7 +35,7 @@ public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHea public override async Task WriteResponseBodyAsync(OutputFormatterContext context) { - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; response.ContentType = ContentType + ";charset=utf-8"; await response.WriteAsync(context.Object.ToString()); } diff --git a/test/WebSites/ContentNegotiationWebSite/PlainTextFormatter.cs b/test/WebSites/ContentNegotiationWebSite/PlainTextFormatter.cs index 366a10e0d9..9264692c6e 100644 --- a/test/WebSites/ContentNegotiationWebSite/PlainTextFormatter.cs +++ b/test/WebSites/ContentNegotiationWebSite/PlainTextFormatter.cs @@ -33,7 +33,7 @@ public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHea public override async Task WriteResponseBodyAsync(OutputFormatterContext context) { - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; response.ContentType = "text/plain;charset=utf-8"; await response.WriteAsync(context.Object as string); } diff --git a/test/WebSites/ContentNegotiationWebSite/VCardFormatter_V3.cs b/test/WebSites/ContentNegotiationWebSite/VCardFormatter_V3.cs index 6c8bac4a5f..a6fb17ccda 100644 --- a/test/WebSites/ContentNegotiationWebSite/VCardFormatter_V3.cs +++ b/test/WebSites/ContentNegotiationWebSite/VCardFormatter_V3.cs @@ -39,7 +39,7 @@ public override async Task WriteResponseBodyAsync(OutputFormatterContext context builder.AppendLine(); builder.AppendLine("END:VCARD"); - var responseStream = new NonDisposableStream(context.ActionContext.HttpContext.Response.Body); + var responseStream = new NonDisposableStream(context.HttpContext.Response.Body); using (var writer = new StreamWriter(responseStream, context.SelectedEncoding, bufferSize: 1024)) { await writer.WriteAsync(builder.ToString()); diff --git a/test/WebSites/ContentNegotiationWebSite/VCardFormatter_V4.cs b/test/WebSites/ContentNegotiationWebSite/VCardFormatter_V4.cs index 304d7b8d2e..ad901892da 100644 --- a/test/WebSites/ContentNegotiationWebSite/VCardFormatter_V4.cs +++ b/test/WebSites/ContentNegotiationWebSite/VCardFormatter_V4.cs @@ -42,7 +42,7 @@ public override async Task WriteResponseBodyAsync(OutputFormatterContext context builder.AppendLine(); builder.AppendLine("END:VCARD"); - var responseStream = new NonDisposableStream(context.ActionContext.HttpContext.Response.Body); + var responseStream = new NonDisposableStream(context.HttpContext.Response.Body); using (var writer = new StreamWriter(responseStream, context.SelectedEncoding, bufferSize: 1024)) { await writer.WriteAsync(builder.ToString()); diff --git a/test/WebSites/FormatFilterWebSite/CustomFormatter.cs b/test/WebSites/FormatFilterWebSite/CustomFormatter.cs index 2a215e0458..27ad6f3d5c 100644 --- a/test/WebSites/FormatFilterWebSite/CustomFormatter.cs +++ b/test/WebSites/FormatFilterWebSite/CustomFormatter.cs @@ -27,7 +27,7 @@ public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHea var actionReturn = context.Object as Product; if (actionReturn != null) { - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; context.SelectedContentType = contentType; return true; } @@ -37,7 +37,7 @@ public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHea public override async Task WriteResponseBodyAsync(OutputFormatterContext context) { - var response = context.ActionContext.HttpContext.Response; + var response = context.HttpContext.Response; await response.WriteAsync(context.Object.ToString()); } } diff --git a/test/WebSites/FormatterWebSite/StringInputFormatter.cs b/test/WebSites/FormatterWebSite/StringInputFormatter.cs index d6ea797b17..a6b177a236 100644 --- a/test/WebSites/FormatterWebSite/StringInputFormatter.cs +++ b/test/WebSites/FormatterWebSite/StringInputFormatter.cs @@ -19,7 +19,7 @@ public StringInputFormatter() public override Task ReadRequestBodyAsync(InputFormatterContext context) { - var request = context.ActionContext.HttpContext.Request; + var request = context.HttpContext.Request; MediaTypeHeaderValue requestContentType = null; MediaTypeHeaderValue.TryParse(request.ContentType, out requestContentType); var effectiveEncoding = SelectCharacterEncoding(requestContentType);