Fix #2330 - Reimagine *FormatterContext
This change simplifies InputFormatterContext/OutputFormatterContext by swapping ActionContext for HttpContext. This change is important especially for InputFormatterContext as it decouples ModelState from ActionContext - allowing us to fix a related bug where the _wrong_ ModelState can be passed in for a TryUpdateModel operation.
This commit is contained in:
parent
fcf7b15c64
commit
39fe063aee
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public class InputFormatterContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="InputFormatterContext"/>.
|
||||
/// </summary>
|
||||
public InputFormatterContext([NotNull] ActionContext actionContext,
|
||||
[NotNull] Type modelType)
|
||||
/// <param name="httpContext">
|
||||
/// The <see cref="Http.HttpContext"/> for the current operation.
|
||||
/// </param>
|
||||
/// <param name="modelState">
|
||||
/// The <see cref="ModelStateDictionary"/> for recording errors.
|
||||
/// </param>
|
||||
/// <param name="modelType">
|
||||
/// The <see cref="Type"/> of the model to deserialize.
|
||||
/// </param>
|
||||
public InputFormatterContext(
|
||||
[NotNull] HttpContext httpContext,
|
||||
[NotNull] ModelStateDictionary modelState,
|
||||
[NotNull] Type modelType)
|
||||
{
|
||||
ActionContext = actionContext;
|
||||
HttpContext = httpContext;
|
||||
ModelState = modelState;
|
||||
ModelType = modelType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Action context associated with the current call.
|
||||
/// Gets the <see cref="Http.HttpContext"/> associated with the current operation.
|
||||
/// </summary>
|
||||
public ActionContext ActionContext { get; private set; }
|
||||
public HttpContext HttpContext { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the expected type of the model represented by the request body.
|
||||
/// Gets the <see cref="ModelStateDictionary"/> associated with the current operation.
|
||||
/// </summary>
|
||||
public ModelStateDictionary ModelState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the expected <see cref="Type"/> of the model represented by the request body.
|
||||
/// </summary>
|
||||
public Type ModelType { get; private set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Microsoft.AspNet.Mvc
|
|||
public Type DeclaredType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action context associated with the current call.
|
||||
/// Gets or sets the <see cref="HttpContext"/> context associated with the current operation.
|
||||
/// </summary>
|
||||
public ActionContext ActionContext { get; set; }
|
||||
public HttpContext HttpContext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The encoding which is chosen by the selected formatter.
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
var formatterContext = new OutputFormatterContext()
|
||||
{
|
||||
ActionContext = context,
|
||||
HttpContext = context.HttpContext,
|
||||
DeclaredType = objectResult.DeclaredType,
|
||||
Object = Value,
|
||||
};
|
||||
|
|
@ -125,7 +125,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// If no formatter was provided, then run Conneg with the formatters configured in options.
|
||||
var formatters = formatterContext
|
||||
.ActionContext
|
||||
.HttpContext
|
||||
.RequestServices
|
||||
.GetRequiredService<IOptions<MvcOptions>>()
|
||||
|
|
@ -140,7 +139,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
// If the available user-configured formatters can't write this type, then fall back to the
|
||||
// 'global' one.
|
||||
formatter = formatterContext
|
||||
.ActionContext
|
||||
.HttpContext
|
||||
.RequestServices
|
||||
.GetRequiredService<JsonOutputFormatter>();
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var formatterContext = new OutputFormatterContext()
|
||||
{
|
||||
DeclaredType = DeclaredType,
|
||||
ActionContext = context,
|
||||
HttpContext = context.HttpContext,
|
||||
Object = Value,
|
||||
StatusCode = StatusCode
|
||||
};
|
||||
|
|
@ -83,8 +83,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
OutputFormatterContext formatterContext,
|
||||
IEnumerable<IOutputFormatter> formatters)
|
||||
{
|
||||
var logger = formatterContext.ActionContext.HttpContext.RequestServices
|
||||
.GetRequiredService<ILogger<ObjectResult>>();
|
||||
var logger = formatterContext.HttpContext.RequestServices.GetRequiredService<ILogger<ObjectResult>>();
|
||||
|
||||
// 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 @@ namespace Microsoft.AspNet.Mvc
|
|||
// 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 @@ namespace Microsoft.AspNet.Mvc
|
|||
private IEnumerable<MediaTypeHeaderValue> 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<IOptions<MvcOptions>>()
|
||||
.Options;
|
||||
var options = formatterContext
|
||||
.HttpContext
|
||||
.RequestServices
|
||||
.GetRequiredService<IOptions<MvcOptions>>()
|
||||
.Options;
|
||||
|
||||
var respectAcceptHeader = true;
|
||||
if (options.RespectBrowserAcceptHeader == false
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <inheritdoc />
|
||||
public Task WriteAsync(OutputFormatterContext context)
|
||||
{
|
||||
var response = context.ActionContext.HttpContext.Response;
|
||||
var response = context.HttpContext.Response;
|
||||
response.StatusCode = StatusCodes.Status406NotAcceptable;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <inheritdoc />
|
||||
public virtual async Task<object> ReadAsync(InputFormatterContext context)
|
||||
{
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
var request = context.HttpContext.Request;
|
||||
if (request.ContentLength == 0)
|
||||
{
|
||||
return GetDefaultValueForType(context.ModelType);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
public override Task<object> 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 @@ namespace Microsoft.AspNet.Mvc
|
|||
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
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
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))
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <returns>The <see cref="Encoding"/> to use when reading the request or writing the response.</returns>
|
||||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
selectedMediaType.Charset = selectedEncoding.WebName;
|
||||
|
||||
context.SelectedContentType = context.SelectedContentType ?? selectedMediaType;
|
||||
var response = context.ActionContext.HttpContext.Response;
|
||||
var response = context.HttpContext.Response;
|
||||
response.ContentType = selectedMediaType.ToString();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
using (var valueAsStream = ((Stream)context.Object))
|
||||
{
|
||||
var response = context.ActionContext.HttpContext.Response;
|
||||
var response = context.HttpContext.Response;
|
||||
|
||||
if (context.SelectedContentType != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
return;
|
||||
}
|
||||
|
||||
var response = context.ActionContext.HttpContext.Response;
|
||||
var response = context.HttpContext.Response;
|
||||
|
||||
await response.WriteAsync(valueAsString, context.SelectedEncoding);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected async override Task<ModelBindingResult> BindModelCoreAsync([NotNull] ModelBindingContext bindingContext)
|
||||
protected async override Task<ModelBindingResult> BindModelCoreAsync(
|
||||
[NotNull] ModelBindingContext bindingContext)
|
||||
{
|
||||
var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices;
|
||||
|
||||
var actionContext = requestServices.GetRequiredService<IScopedInstance<ActionContext>>().Value;
|
||||
var formatters = requestServices.GetRequiredService<IScopedInstance<ActionBindingContext>>().Value.InputFormatters;
|
||||
var httpContext = bindingContext.OperationBindingContext.HttpContext;
|
||||
var formatters = requestServices
|
||||
.GetRequiredService<IScopedInstance<ActionBindingContext>>().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)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
|
|||
|
||||
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 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
|
|||
{
|
||||
response.StatusCode = (int)responseMessage.StatusCode;
|
||||
|
||||
var responseFeature = context.ActionContext.HttpContext.GetFeature<IHttpResponseFeature>();
|
||||
var responseFeature = context.HttpContext.GetFeature<IHttpResponseFeature>();
|
||||
if (responseFeature != null)
|
||||
{
|
||||
responseFeature.ReasonPhrase = responseMessage.ReasonPhrase;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
/// <returns>Task which reads the input.</returns>
|
||||
public override Task<object> 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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
_dataAnnotationRequiredAttributeValidation.Validate(
|
||||
type,
|
||||
context.ActionContext.ModelState);
|
||||
context.ModelState);
|
||||
|
||||
var serializer = GetCachedSerializer(type);
|
||||
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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))
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
/// <returns>Task which reads the input.</returns>
|
||||
public override Task<object> ReadRequestBodyAsync(InputFormatterContext context)
|
||||
{
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
var request = context.HttpContext.Request;
|
||||
|
||||
MediaTypeHeaderValue requestContentType;
|
||||
MediaTypeHeaderValue.TryParse(request.ContentType, out requestContentType);
|
||||
|
|
|
|||
|
|
@ -139,12 +139,12 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
/// <inheritdoc />
|
||||
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))
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
|
||||
var context = new OutputFormatterContext()
|
||||
{
|
||||
ActionContext = actionContext,
|
||||
HttpContext = actionContext.HttpContext,
|
||||
Object = input,
|
||||
DeclaredType = typeof(string)
|
||||
};
|
||||
|
|
@ -530,7 +530,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
new ActionDescriptor());
|
||||
var formatterContext = new OutputFormatterContext()
|
||||
{
|
||||
ActionContext = tempActionContext,
|
||||
HttpContext = tempActionContext.HttpContext,
|
||||
Object = nonStringValue,
|
||||
DeclaredType = nonStringValue.GetType()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
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<TooManyModelErrorsException>(error.Exception);
|
||||
}
|
||||
|
||||
|
|
@ -189,17 +192,18 @@ namespace Microsoft.AspNet.Mvc
|
|||
// 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 @@ namespace Microsoft.AspNet.Mvc
|
|||
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);
|
||||
}
|
||||
|
||||
[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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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/json")
|
||||
private static HttpContext GetHttpContext(
|
||||
byte[] contentBytes,
|
||||
string contentType = "application/json")
|
||||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
|
|
|
|||
|
|
@ -62,11 +62,13 @@ namespace Microsoft.AspNet.Mvc.Core.Test.Formatters
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Core.Test.Formatters
|
|||
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;
|
||||
|
||||
var streamReader = new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8);
|
||||
Assert.Equal(expectedOutput, streamReader.ReadToEnd());
|
||||
Assert.NotNull(body);
|
||||
body.Position = 0;
|
||||
|
||||
var content = new StreamReader(body, Encoding.UTF8).ReadToEnd();
|
||||
Assert.Equal(expectedOutput, content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -155,12 +159,14 @@ namespace Microsoft.AspNet.Mvc.Core.Test.Formatters
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Core.Test.Formatters
|
|||
await formatter.WriteResponseBodyAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
var actualData = memStream.ToArray();
|
||||
var actualData = body.ToArray();
|
||||
Assert.Equal(expectedData, actualData);
|
||||
}
|
||||
|
||||
|
|
@ -200,11 +206,12 @@ namespace Microsoft.AspNet.Mvc.Core.Test.Formatters
|
|||
{
|
||||
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)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
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<Customer>));
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var context = new InputFormatterContext(httpContext, modelState, typeof(JsonPatchDocument<Customer>));
|
||||
|
||||
// Act
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
|
@ -45,8 +46,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
"{\"op\": \"remove\", \"path\" : \"Customer/Name\"}]";
|
||||
var contentBytes = Encoding.UTF8.GetBytes(content);
|
||||
|
||||
var actionContext = GetActionContext(contentBytes);
|
||||
var context = new InputFormatterContext(actionContext, typeof(JsonPatchDocument<Customer>));
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var context = new InputFormatterContext(httpContext, modelState, typeof(JsonPatchDocument<Customer>));
|
||||
|
||||
// Act
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
|
@ -72,8 +74,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
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<Customer>));
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes, contentType: requestContentType);
|
||||
var formatterContext = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelState,
|
||||
typeof(JsonPatchDocument<Customer>));
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(formatterContext);
|
||||
|
|
@ -92,8 +98,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
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);
|
||||
Assert.Contains(exceptionMessage, 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());
|
||||
}
|
||||
|
||||
private static HttpContext GetHttpContext(byte[] contentBytes,
|
||||
private static HttpContext GetHttpContext(
|
||||
byte[] contentBytes,
|
||||
string contentType = "application/json-patch+json")
|
||||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
{
|
||||
Object = value,
|
||||
DeclaredType = typeToUse,
|
||||
ActionContext = null,
|
||||
HttpContext = null,
|
||||
};
|
||||
var contetType = useNonNullContentType ? MediaTypeHeaderValue.Parse("text/plain") : null;
|
||||
var formatter = new HttpNoContentOutputFormatter();
|
||||
|
|
@ -67,7 +67,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
{
|
||||
Object = "Something non null.",
|
||||
DeclaredType = declaredType,
|
||||
ActionContext = null,
|
||||
HttpContext = null,
|
||||
};
|
||||
var contetType = MediaTypeHeaderValue.Parse("text/plain");
|
||||
var formatter = new HttpNoContentOutputFormatter();
|
||||
|
|
@ -93,7 +93,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
{
|
||||
Object = value,
|
||||
DeclaredType = typeof(string),
|
||||
ActionContext = null,
|
||||
HttpContext = null,
|
||||
};
|
||||
|
||||
var contetType = MediaTypeHeaderValue.Parse("text/plain");
|
||||
|
|
@ -117,7 +117,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
var formatterContext = new OutputFormatterContext()
|
||||
{
|
||||
Object = null,
|
||||
ActionContext = new ActionContext(defaultHttpContext, new RouteData(), new ActionDescriptor())
|
||||
HttpContext = defaultHttpContext,
|
||||
};
|
||||
|
||||
var formatter = new HttpNoContentOutputFormatter();
|
||||
|
|
@ -137,7 +137,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
var formatterContext = new OutputFormatterContext()
|
||||
{
|
||||
Object = null,
|
||||
ActionContext = new ActionContext(defaultHttpContext, new RouteData(), new ActionDescriptor()),
|
||||
HttpContext = defaultHttpContext,
|
||||
StatusCode = StatusCodes.Status201Created
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
var formatterContext = new OutputFormatterContext()
|
||||
{
|
||||
Object = "someValue",
|
||||
ActionContext = actionContext,
|
||||
HttpContext = mockHttpContext.Object,
|
||||
DeclaredType = typeof(string)
|
||||
};
|
||||
|
||||
|
|
@ -85,8 +85,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
var mockHttpContext = new Mock<HttpContext>();
|
||||
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<InvalidOperationException>(
|
||||
|
|
@ -108,8 +107,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
Object = null,
|
||||
DeclaredType = typeof(string),
|
||||
ActionContext = new ActionContext(mockHttpContext.Object, new RouteData(), new ActionDescriptor()),
|
||||
HttpContext = mockHttpContext.Object,
|
||||
SelectedEncoding = encoding
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShimTest
|
|||
{
|
||||
Object = outputValue,
|
||||
DeclaredType = outputType,
|
||||
ActionContext = new ActionContext(httpContext, routeData: null, actionDescriptor: null)
|
||||
HttpContext = httpContext,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,8 +79,9 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
// Assert
|
||||
Assert.NotNull(model);
|
||||
Assert.True(context.ActionContext.HttpContext.Request.Body.CanRead);
|
||||
Assert.True(context.HttpContext.Request.Body.CanRead);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -328,8 +329,11 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
"<DummyClass><SampleInt>1000</SampleInt></DummyClass>");
|
||||
|
||||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
AssertModelStateErrorMessages(
|
||||
typeof(Address).FullName,
|
||||
context.ActionContext,
|
||||
context,
|
||||
expectedErrorMessages: new[]
|
||||
{
|
||||
string.Format(requiredErrorMessageFormat, nameof(Address.Zipcode), typeof(Address).FullName),
|
||||
|
|
@ -895,10 +901,10 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
AssertModelStateErrorMessages(
|
||||
typeof(Address).FullName,
|
||||
context.ActionContext,
|
||||
context,
|
||||
expectedErrorMessages: new[]
|
||||
{
|
||||
string.Format(requiredErrorMessageFormat, nameof(Address.Zipcode), typeof(Address).FullName),
|
||||
|
|
@ -931,10 +937,10 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
// 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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
AssertModelStateErrorMessages(
|
||||
typeof(Employee).FullName,
|
||||
context.ActionContext,
|
||||
context,
|
||||
expectedErrorMessages: new[]
|
||||
{
|
||||
string.Format(requiredErrorMessageFormat, nameof(Employee.Id), typeof(Employee).FullName)
|
||||
|
|
@ -951,7 +957,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
AssertModelStateErrorMessages(
|
||||
typeof(Product).FullName,
|
||||
context.ActionContext,
|
||||
context,
|
||||
expectedErrorMessages: new[]
|
||||
{
|
||||
string.Format(requiredErrorMessageFormat, nameof(Product.Id), typeof(Product).FullName)
|
||||
|
|
@ -976,17 +982,17 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
// 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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
AssertModelStateErrorMessages(
|
||||
typeof(Student).FullName,
|
||||
context.ActionContext,
|
||||
context,
|
||||
expectedErrorMessages: new[]
|
||||
{
|
||||
string.Format(requiredErrorMessageFormat, nameof(Student.Id), typeof(Student).FullName)
|
||||
|
|
@ -1019,10 +1025,10 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
// 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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
});
|
||||
AssertModelStateErrorMessages(
|
||||
typeof(Address).FullName,
|
||||
context.ActionContext,
|
||||
context,
|
||||
expectedErrorMessages: new[]
|
||||
{
|
||||
string.Format(requiredErrorMessageFormat, nameof(Address.IsResidential), typeof(Address).FullName),
|
||||
|
|
@ -1056,10 +1062,10 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
// 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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
});
|
||||
AssertModelStateErrorMessages(
|
||||
typeof(GpsCoordinate).FullName,
|
||||
context.ActionContext,
|
||||
context,
|
||||
expectedErrorMessages: new[]
|
||||
{
|
||||
string.Format(
|
||||
|
|
@ -1081,7 +1087,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
});
|
||||
AssertModelStateErrorMessages(
|
||||
typeof(ValueTypePropertiesModel).FullName,
|
||||
context.ActionContext,
|
||||
context,
|
||||
expectedErrorMessages: new[]
|
||||
{
|
||||
string.Format(
|
||||
|
|
@ -1105,11 +1111,11 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
private void AssertModelStateErrorMessages(
|
||||
string modelStateKey,
|
||||
ActionContext actionContext,
|
||||
InputFormatterContext context,
|
||||
IEnumerable<string> 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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
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<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
|
|
|
|||
|
|
@ -102,12 +102,11 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
// 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 =
|
||||
"<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleInt>10</SampleInt></DummyClass>";
|
||||
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var formatter = new XmlDataContractSerializerOutputFormatter();
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
|
|
@ -177,18 +181,23 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
XmlAssert.Equal("<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleInt>10</SampleInt></DummyClass>",
|
||||
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 =
|
||||
"<TestLevelTwo xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleString>TestString</SampleString>" +
|
||||
"<TestOne><SampleInt>10</SampleInt><sampleString>TestLevelOne string</sampleString>" +
|
||||
"</TestOne></TestLevelTwo>";
|
||||
|
||||
var sampleInput = new TestLevelTwo
|
||||
{
|
||||
SampleString = "TestString",
|
||||
|
|
@ -205,24 +214,26 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
XmlAssert.Equal("<TestLevelTwo xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleString>TestString</SampleString>" +
|
||||
"<TestOne><SampleInt>10</SampleInt><sampleString>TestLevelOne string</sampleString>" +
|
||||
"</TestOne></TestLevelTwo>",
|
||||
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 =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
|
||||
"<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleInt>10</SampleInt></DummyClass>";
|
||||
|
||||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
XmlAssert.Equal("<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
|
||||
"<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleInt>10</SampleInt></DummyClass>",
|
||||
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 =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
|
||||
"<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleInt>10</SampleInt></DummyClass>";
|
||||
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType(),
|
||||
"application/xml; charset=utf-16");
|
||||
|
|
@ -255,19 +269,21 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
XmlAssert.Equal("<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
|
||||
"<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleInt>10</SampleInt></DummyClass>",
|
||||
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 =
|
||||
"<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"\r\n <SampleInt>10</SampleInt>\r\n</DummyClass>";
|
||||
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var formatter = new XmlDataContractSerializerOutputFormatter();
|
||||
formatter.WriterSettings.Indent = true;
|
||||
|
|
@ -277,13 +293,11 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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("<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"\r\n <SampleInt>10</SampleInt>\r\n</DummyClass>",
|
||||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
{
|
||||
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<HttpRequest>();
|
||||
|
||||
var headers = new HeaderDictionary(new Dictionary<string, string[]>(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<HttpResponse>();
|
||||
response.SetupGet(f => f.Body).Returns(new MemoryStream());
|
||||
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
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
|
||||
|
|
|
|||
|
|
@ -56,8 +56,10 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
// Assert
|
||||
Assert.NotNull(model);
|
||||
Assert.True(context.ActionContext.HttpContext.Request.Body.CanRead);
|
||||
Assert.True(context.HttpContext.Request.Body.CanRead);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -337,8 +339,11 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
"<DummyClass><SampleInt>1000</SampleInt></DummyClass>");
|
||||
|
||||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
|
||||
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<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
|
|
|
|||
|
|
@ -60,12 +60,11 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 =
|
||||
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>";
|
||||
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var formatter = new XmlSerializerOutputFormatter();
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
|
|
@ -135,19 +137,23 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
XmlAssert.Equal("<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
|
||||
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 =
|
||||
"<TestLevelTwo xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleString>TestString</SampleString>" +
|
||||
"<TestOne><sampleString>TestLevelOne string</sampleString>" +
|
||||
"<SampleInt>10</SampleInt></TestOne></TestLevelTwo>";
|
||||
|
||||
var sampleInput = new TestLevelTwo
|
||||
{
|
||||
SampleString = "TestString",
|
||||
|
|
@ -164,20 +170,22 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
XmlAssert.Equal("<TestLevelTwo xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleString>TestString</SampleString>" +
|
||||
"<TestOne><sampleString>TestLevelOne string</sampleString>" +
|
||||
"<SampleInt>10</SampleInt></TestOne></TestLevelTwo>",
|
||||
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 =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
|
||||
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>";
|
||||
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
var formatter = new XmlSerializerOutputFormatter(
|
||||
|
|
@ -191,19 +199,22 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
XmlAssert.Equal("<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
|
||||
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
|
||||
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 =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
|
||||
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>";
|
||||
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var outputFormatterContext =
|
||||
GetOutputFormatterContext(sampleInput, sampleInput.GetType(), "application/xml; charset=utf-16");
|
||||
|
|
@ -214,19 +225,21 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
XmlAssert.Equal("<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
|
||||
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
|
||||
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 =
|
||||
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n <SampleInt>10</SampleInt>\r\n</DummyClass>";
|
||||
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var formatter = new XmlSerializerOutputFormatter();
|
||||
formatter.WriterSettings.Indent = true;
|
||||
|
|
@ -236,13 +249,11 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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("<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n <SampleInt>10</SampleInt>\r\n</DummyClass>",
|
||||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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<object[]> TypesForCanWriteResult
|
||||
|
|
@ -304,7 +315,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
}
|
||||
}
|
||||
|
||||
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<HttpRequest>();
|
||||
|
||||
var headers = new HeaderDictionary(new Dictionary<string, string[]>(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<HttpResponse>();
|
||||
response.SetupGet(f => f.Body).Returns(new MemoryStream());
|
||||
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
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
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace ContentNegotiationWebSite
|
|||
|
||||
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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace ContentNegotiationWebSite
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ namespace ContentNegotiationWebSite
|
|||
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());
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ namespace ContentNegotiationWebSite
|
|||
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());
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace FormatFilterWebSite
|
|||
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 @@ namespace FormatFilterWebSite
|
|||
|
||||
public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
|
||||
{
|
||||
var response = context.ActionContext.HttpContext.Response;
|
||||
var response = context.HttpContext.Response;
|
||||
await response.WriteAsync(context.Object.ToString());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace FormatterWebSite
|
|||
|
||||
public override Task<object> 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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue