1. Moving input formatting related classes to MVC Core.(for tests as well).
2. Cleaning up the IInputFormatter to the final version. 3. Updating the input formatters and the context to be compliant with the IInputFormatter interface. 4. Adding Functional Tests. - Not cleaning up TempInputFormatterProvider. Conflicts: src/Microsoft.AspNet.Mvc.Core/Formatters/InputFormatter.cs src/Microsoft.AspNet.Mvc.Core/Formatters/JsonInputFormatter.cs src/Microsoft.AspNet.Mvc.Core/Formatters/TempInputFormatterProvider.cs src/Microsoft.AspNet.Mvc.Core/Formatters/XmlDataContractSerializerInputFormatter.cs src/Microsoft.AspNet.Mvc.Core/Formatters/XmlSerializerInputFormatter.cs src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs src/Microsoft.AspNet.Mvc.ModelBinding/Microsoft.AspNet.Mvc.ModelBinding.kproj test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj Conflicts: src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj src/Microsoft.AspNet.Mvc.HeaderValueAbstractions/Microsoft.AspNet.Mvc.HeaderValueAbstractions.kproj src/Microsoft.AspNet.Mvc.ModelBinding/Microsoft.AspNet.Mvc.ModelBinding.kproj src/Microsoft.AspNet.Mvc.ModelBinding/ValueProviders/FormValueProviderFactory.cs test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj test/Microsoft.AspNet.Mvc.ModelBinding.Test/Microsoft.AspNet.Mvc.ModelBinding.Test.kproj Conflicts: src/Microsoft.AspNet.Mvc.Core/Formatters/FormattingUtilities.cs src/Microsoft.AspNet.Mvc.Core/Formatters/TempInputFormatterProvider.cs
This commit is contained in:
parent
4f69e17f53
commit
64d797a489
|
|
@ -57,7 +57,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var incomingAcceptHeader = HeaderParsingHelpers.GetAcceptHeaders(
|
||||
formatterContext.ActionContext.HttpContext.Request.Accept);
|
||||
var sortedAcceptHeaders = SortMediaTypeWithQualityHeaderValues(incomingAcceptHeader)
|
||||
.Where(header => header.Quality != FormattingUtilities.NoMatch)
|
||||
.Where(header => header.Quality != HttpHeaderUtilitites.NoMatch)
|
||||
.ToArray();
|
||||
|
||||
IOutputFormatter selectedFormatter = null;
|
||||
|
|
|
|||
|
|
@ -241,18 +241,16 @@ namespace Microsoft.AspNet.Mvc
|
|||
modelAccessor: null,
|
||||
modelType: parameterType);
|
||||
var providerContext = new InputFormatterProviderContext(
|
||||
actionBindingContext.ActionContext.HttpContext,
|
||||
actionBindingContext.ActionContext,
|
||||
modelMetadata,
|
||||
modelState);
|
||||
|
||||
var inputFormatter = actionBindingContext.InputFormatterProvider.GetInputFormatter(
|
||||
providerContext);
|
||||
|
||||
var formatterContext = new InputFormatterContext(actionBindingContext.ActionContext.HttpContext,
|
||||
modelMetadata,
|
||||
modelState);
|
||||
await inputFormatter.ReadAsync(formatterContext);
|
||||
parameterValues[parameter.Name] = formatterContext.Model;
|
||||
var formatterContext = new InputFormatterContext(actionBindingContext.ActionContext,
|
||||
modelMetadata.ModelType);
|
||||
parameterValues[parameter.Name] = await inputFormatter.ReadAsync(formatterContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using System.IO;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Stream that delegates to an inner stream.
|
||||
|
|
@ -5,9 +5,10 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains methods which are used by input formatters.
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads an object from the request body.
|
||||
/// </summary>
|
||||
public interface IInputFormatter
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether this <see cref="IInputFormatter"/> can de-serialize
|
||||
/// an object of the specified type.
|
||||
/// </summary>
|
||||
/// <param name="context">Input formatter context associated with this call.</param>
|
||||
/// <returns>True if this <see cref="IInputFormatter"/> supports the passed in
|
||||
/// request's content-type and is able to de-serialize the request body.
|
||||
/// False otherwise.</returns>
|
||||
bool CanRead(InputFormatterContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called during deserialization to read an object from the request.
|
||||
/// </summary>
|
||||
/// <param name="context">Input formatter context associated with this call.</param>
|
||||
/// <returns>A task that deserializes the request body.</returns>
|
||||
Task<object> ReadAsync(InputFormatterContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public interface IInputFormatterProvider
|
||||
{
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents information 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)
|
||||
{
|
||||
ActionContext = actionContext;
|
||||
ModelType = modelType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Action context associated with the current call.
|
||||
/// </summary>
|
||||
public ActionContext ActionContext { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the expected type of the model represented by the request body.
|
||||
/// </summary>
|
||||
public Type ModelType { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -2,21 +2,22 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class InputFormatterProviderContext
|
||||
{
|
||||
public InputFormatterProviderContext([NotNull] HttpContext httpContext,
|
||||
public InputFormatterProviderContext([NotNull] ActionContext actionContext,
|
||||
[NotNull] ModelMetadata metadata,
|
||||
[NotNull] ModelStateDictionary modelState)
|
||||
{
|
||||
HttpContext = httpContext;
|
||||
ActionContext = actionContext;
|
||||
Metadata = metadata;
|
||||
ModelState = modelState;
|
||||
}
|
||||
|
||||
public HttpContext HttpContext { get; private set; }
|
||||
public ActionContext ActionContext { get; private set; }
|
||||
|
||||
public ModelMetadata Metadata { get; private set; }
|
||||
|
||||
|
|
@ -8,10 +8,11 @@ using System.Linq;
|
|||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class JsonInputFormatter : IInputFormatter
|
||||
{
|
||||
|
|
@ -66,20 +67,34 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
|
||||
/// <summary>
|
||||
/// Gets or sets if deserialization errors are captured. When set, these errors appear in
|
||||
/// the <see cref="ModelStateDictionary"/> instance of <see cref="InputFormatterContext"/>.
|
||||
/// the <see cref="ActionContext.ModelState"/> instance of <see cref="InputFormatterContext"/>.
|
||||
/// </summary>
|
||||
public bool CaptureDeserilizationErrors { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task ReadAsync([NotNull] InputFormatterContext context)
|
||||
public bool CanRead(InputFormatterContext context)
|
||||
{
|
||||
var request = context.HttpContext.Request;
|
||||
var contentType = context.ActionContext.HttpContext.Request.ContentType;
|
||||
MediaTypeHeaderValue requestContentType;
|
||||
if (!MediaTypeHeaderValue.TryParse(contentType, out requestContentType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return SupportedMediaTypes
|
||||
.Any(supportedMediaType => supportedMediaType.IsSubsetOf(requestContentType));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<object> ReadAsync([NotNull] InputFormatterContext context)
|
||||
{
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
if (request.ContentLength == 0)
|
||||
{
|
||||
var modelType = context.Metadata.ModelType;
|
||||
context.Model = modelType.GetTypeInfo().IsValueType ? Activator.CreateInstance(modelType) :
|
||||
var modelType = context.ModelType;
|
||||
var model = modelType.GetTypeInfo().IsValueType ? Activator.CreateInstance(modelType) :
|
||||
null;
|
||||
return;
|
||||
return model;
|
||||
}
|
||||
|
||||
MediaTypeHeaderValue requestContentType = null;
|
||||
|
|
@ -89,7 +104,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
// Never non-null since SelectCharacterEncoding() throws in error / not found scenarios
|
||||
var effectiveEncoding = SelectCharacterEncoding(requestContentType);
|
||||
|
||||
context.Model = await ReadInternal(context, effectiveEncoding);
|
||||
return await ReadInternal(context, effectiveEncoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -118,8 +133,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
private Task<object> ReadInternal(InputFormatterContext context,
|
||||
Encoding effectiveEncoding)
|
||||
{
|
||||
var type = context.Metadata.ModelType;
|
||||
var request = context.HttpContext.Request;
|
||||
var type = context.ModelType;
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
|
||||
using (var jsonReader = CreateJsonReader(context, request.Body, effectiveEncoding))
|
||||
{
|
||||
|
|
@ -133,7 +148,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
errorHandler = (sender, e) =>
|
||||
{
|
||||
var exception = e.ErrorContext.Error;
|
||||
context.ModelState.AddModelError(e.ErrorContext.Path, e.ErrorContext.Error);
|
||||
context.ActionContext.ModelState.AddModelError(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
|
||||
// overflow the stack for x64 CLR processes
|
||||
|
|
@ -181,7 +196,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
}
|
||||
|
||||
// No supported encoding was found so there is no way for us to start reading.
|
||||
throw new InvalidOperationException(Resources.FormatMediaTypeFormatterNoEncoding(GetType().FullName));
|
||||
throw new InvalidOperationException(Resources.FormatInputFormatterNoEncoding(GetType().FullName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -85,8 +85,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
private static int CompareBasedOnQualityFactor(MediaTypeWithQualityHeaderValue mediaType1,
|
||||
MediaTypeWithQualityHeaderValue mediaType2)
|
||||
{
|
||||
var mediaType1Quality = mediaType1.Quality ?? FormattingUtilities.Match;
|
||||
var mediaType2Quality = mediaType2.Quality ?? FormattingUtilities.Match;
|
||||
var mediaType1Quality = mediaType1.Quality ?? HttpHeaderUtilitites.Match;
|
||||
var mediaType2Quality = mediaType2.Quality ?? HttpHeaderUtilitites.Match;
|
||||
var qualityDifference = mediaType1Quality - mediaType2Quality;
|
||||
if (qualityDifference < 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
var sortedAcceptCharsetHeaders = acceptCharsetHeaders
|
||||
.Where(acceptCharset =>
|
||||
acceptCharset.Quality != FormattingUtilities.NoMatch)
|
||||
acceptCharset.Quality != HttpHeaderUtilitites.NoMatch)
|
||||
.OrderByDescending(
|
||||
m => m, StringWithQualityHeaderValueComparer.QualityComparer);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
public int Compare([NotNull] StringWithQualityHeaderValue stringWithQuality1,
|
||||
[NotNull] StringWithQualityHeaderValue stringWithQuality2)
|
||||
{
|
||||
var quality1 = stringWithQuality1.Quality ?? FormattingUtilities.Match;
|
||||
var quality2 = stringWithQuality2.Quality ?? FormattingUtilities.Match;
|
||||
var quality1 = stringWithQuality1.Quality ?? HttpHeaderUtilitites.Match;
|
||||
var quality2 = stringWithQuality2.Quality ?? HttpHeaderUtilitites.Match;
|
||||
var qualityDifference = quality1 - quality2;
|
||||
if (qualityDifference < 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,13 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
@ -23,20 +17,15 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
public IInputFormatter GetInputFormatter(InputFormatterProviderContext context)
|
||||
{
|
||||
var request = context.HttpContext.Request;
|
||||
MediaTypeHeaderValue contentType;
|
||||
if (!MediaTypeHeaderValue.TryParse(request.ContentType, out contentType))
|
||||
{
|
||||
// TODO: https://github.com/aspnet/Mvc/issues/458
|
||||
throw new InvalidOperationException("400: Bad Request");
|
||||
}
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
var formatterContext = new InputFormatterContext(context.ActionContext,
|
||||
context.Metadata.ModelType);
|
||||
|
||||
// TODO: https://github.com/aspnet/Mvc/issues/1014
|
||||
var formatters = _defaultFormattersProvider.InputFormatters;
|
||||
foreach (var formatter in formatters)
|
||||
{
|
||||
var formatterMatched = formatter.SupportedMediaTypes
|
||||
.Any(supportedMediaType =>
|
||||
supportedMediaType.IsSubsetOf(contentType));
|
||||
var formatterMatched = formatter.CanRead(formatterContext);
|
||||
if (formatterMatched)
|
||||
{
|
||||
return formatter;
|
||||
|
|
@ -46,7 +35,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
// TODO: https://github.com/aspnet/Mvc/issues/458
|
||||
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
|
||||
"415: Unsupported content type {0}",
|
||||
contentType.RawValue));
|
||||
request.ContentType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
|
@ -11,7 +12,7 @@ using System.Threading.Tasks;
|
|||
using System.Xml;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// This class handles deserialization of input XML data
|
||||
|
|
@ -58,21 +59,34 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
get { return _readerQuotas; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool CanRead(InputFormatterContext context)
|
||||
{
|
||||
var contentType = context.ActionContext.HttpContext.Request.ContentType;
|
||||
MediaTypeHeaderValue requestContentType;
|
||||
if (!MediaTypeHeaderValue.TryParse(contentType, out requestContentType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return SupportedMediaTypes
|
||||
.Any(supportedMediaType => supportedMediaType.IsSubsetOf(requestContentType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the input XML.
|
||||
/// </summary>
|
||||
/// <param name="context">The input formatter context which contains the body to be read.</param>
|
||||
/// <returns>Task which reads the input.</returns>
|
||||
public async Task ReadAsync(InputFormatterContext context)
|
||||
public async Task<object> ReadAsync(InputFormatterContext context)
|
||||
{
|
||||
var request = context.HttpContext.Request;
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
if (request.ContentLength == 0)
|
||||
{
|
||||
context.Model = GetDefaultValueForType(context.Metadata.ModelType);
|
||||
return;
|
||||
return GetDefaultValueForType(context.ModelType);
|
||||
}
|
||||
|
||||
context.Model = await ReadInternal(context);
|
||||
return await ReadInternal(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -107,8 +121,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
|
||||
private Task<object> ReadInternal(InputFormatterContext context)
|
||||
{
|
||||
var type = context.Metadata.ModelType;
|
||||
var request = context.HttpContext.Request;
|
||||
var type = context.ModelType;
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
|
||||
using (var xmlReader = CreateXmlReader(new DelegatingStream(request.Body)))
|
||||
{
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -11,7 +12,7 @@ using System.Xml;
|
|||
using System.Xml.Serialization;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// This class handles deserialization of input XML data
|
||||
|
|
@ -58,21 +59,34 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
get { return _readerQuotas; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool CanRead(InputFormatterContext context)
|
||||
{
|
||||
var contentType = context.ActionContext.HttpContext.Request.ContentType;
|
||||
MediaTypeHeaderValue requestContentType;
|
||||
if (!MediaTypeHeaderValue.TryParse(contentType, out requestContentType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return SupportedMediaTypes
|
||||
.Any(supportedMediaType => supportedMediaType.IsSubsetOf(requestContentType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the input XML.
|
||||
/// </summary>
|
||||
/// <param name="context">The input formatter context which contains the body to be read.</param>
|
||||
/// <returns>Task which reads the input.</returns>
|
||||
public async Task ReadAsync(InputFormatterContext context)
|
||||
public async Task<object> ReadAsync(InputFormatterContext context)
|
||||
{
|
||||
var request = context.HttpContext.Request;
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
if (request.ContentLength == 0)
|
||||
{
|
||||
context.Model = GetDefaultValueForType(context.Metadata.ModelType);
|
||||
return;
|
||||
return GetDefaultValueForType(context.ModelType);
|
||||
}
|
||||
|
||||
context.Model = await ReadInternal(context);
|
||||
return await ReadInternal(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -107,8 +121,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
|
||||
private Task<object> ReadInternal(InputFormatterContext context)
|
||||
{
|
||||
var type = context.Metadata.ModelType;
|
||||
var request = context.HttpContext.Request;
|
||||
var type = context.ModelType;
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
|
||||
using (var xmlReader = CreateXmlReader(new DelegatingStream(request.Body)))
|
||||
{
|
||||
|
|
@ -51,8 +51,16 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of the <see cref="OutputFormatterDescriptor" /> which are used to construct
|
||||
/// a list of <see cref="IOutputFormatter"/> by <see cref="IOutputFormattersProvider"/>.
|
||||
/// </summary>
|
||||
public List<OutputFormatterDescriptor> OutputFormatters { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of the <see cref="InputFormatterDescriptor" /> which are used to construct
|
||||
/// a list of <see cref="IInputFormatter"/> by <see cref="IInputFormatterProvider"/>.
|
||||
/// </summary>
|
||||
public List<InputFormatterDescriptor> InputFormatters { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1066,6 +1066,22 @@ namespace Microsoft.AspNet.Mvc.Core
|
|||
return string.Format(CultureInfo.CurrentCulture, GetString("OutputFormatterNoEncoding"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No encoding found for input formatter '{0}'. There must be at least one supported encoding registered in order for the formatter to read content.
|
||||
/// </summary>
|
||||
internal static string InputFormatterNoEncoding
|
||||
{
|
||||
get { return GetString("InputFormatterNoEncoding"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No encoding found for input formatter '{0}'. There must be at least one supported encoding registered in order for the formatter to read content.
|
||||
/// </summary>
|
||||
internal static string FormatInputFormatterNoEncoding(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("InputFormatterNoEncoding"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No supported media type registered for output formatter '{0}'. There must be at least one supported media type registered in order for the output formatter to write content.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -81,4 +81,4 @@ namespace Microsoft.AspNet.Mvc
|
|||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -315,6 +315,9 @@
|
|||
<data name="OutputFormatterNoEncoding" xml:space="preserve">
|
||||
<value>No encoding found for output formatter '{0}'. There must be at least one supported encoding registered in order for the output formatter to write content.</value>
|
||||
</data>
|
||||
<data name="InputFormatterNoEncoding" xml:space="preserve">
|
||||
<value>No encoding found for input formatter '{0}'. There must be at least one supported encoding registered in order for the formatter to read content.</value>
|
||||
</data>
|
||||
<data name="OutputFormatterNoMediaType" xml:space="preserve">
|
||||
<value>No supported media type registered for output formatter '{0}'. There must be at least one supported media type registered in order for the output formatter to write content.</value>
|
||||
</data>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||
{
|
||||
public static class FormattingUtilities
|
||||
public static class HttpHeaderUtilitites
|
||||
{
|
||||
/// <summary>
|
||||
/// Quality factor to indicate a perfect match.
|
||||
|
|
@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
|||
return null;
|
||||
}
|
||||
|
||||
var quality = FormattingUtilities.Match;
|
||||
var quality = HttpHeaderUtilitites.Match;
|
||||
string qualityStringValue = null;
|
||||
if (mediaTypeHeaderValue.Parameters.TryGetValue("q", out qualityStringValue))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,10 +16,5 @@
|
|||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
|||
var value = inputArray[0].Trim();
|
||||
|
||||
// Unspecified q factor value is equal to a match.
|
||||
var quality = FormattingUtilities.Match;
|
||||
var quality = HttpHeaderUtilitites.Match;
|
||||
if (inputArray.Length > 1)
|
||||
{
|
||||
var parameter = inputArray[1].Trim();
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public interface IInputFormatter
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the mutable collection of media types supported by this <see cref="JsonInputFormatter"/> instance.
|
||||
/// </summary>
|
||||
IList<MediaTypeHeaderValue> SupportedMediaTypes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mutable collection of character encodings supported by this <see cref="JsonInputFormatter"/>
|
||||
/// instance.
|
||||
/// </summary>
|
||||
IList<Encoding> SupportedEncodings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Called during deserialization to read an object from the request.
|
||||
/// </summary>
|
||||
Task ReadAsync(InputFormatterContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class InputFormatterContext
|
||||
{
|
||||
public InputFormatterContext([NotNull] HttpContext httpContext,
|
||||
[NotNull] ModelMetadata metadata,
|
||||
[NotNull] ModelStateDictionary modelState)
|
||||
{
|
||||
HttpContext = httpContext;
|
||||
Metadata = metadata;
|
||||
ModelState = modelState;
|
||||
}
|
||||
|
||||
public HttpContext HttpContext { get; private set; }
|
||||
|
||||
public ModelMetadata Metadata { get; private set; }
|
||||
|
||||
public ModelStateDictionary ModelState { get; private set; }
|
||||
|
||||
public object Model { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -74,22 +74,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
return GetString("JQuerySyntaxMissingClosingBracket");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No encoding found for input formatter '{0}'. There must be at least one supported encoding registered in order for the formatter to read content.
|
||||
/// </summary>
|
||||
internal static string MediaTypeFormatterNoEncoding
|
||||
{
|
||||
get { return GetString("MediaTypeFormatterNoEncoding"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No encoding found for input formatter '{0}'. There must be at least one supported encoding registered in order for the formatter to read content.
|
||||
/// </summary>
|
||||
internal static string FormatMediaTypeFormatterNoEncoding(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("MediaTypeFormatterNoEncoding"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Property '{0}' on type '{1}' is invalid. Value-typed properties marked as [Required] must also be marked with [DataMember(IsRequired=true)] to be recognized as required. Consider attributing the declaring type with [DataContract] and the property with [DataMember(IsRequired=true)].
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -129,9 +129,6 @@
|
|||
<data name="JQuerySyntaxMissingClosingBracket" xml:space="preserve">
|
||||
<value>The key is invalid JQuery syntax because it is missing a closing bracket.</value>
|
||||
</data>
|
||||
<data name="MediaTypeFormatterNoEncoding" xml:space="preserve">
|
||||
<value>No encoding found for input formatter '{0}'. There must be at least one supported encoding registered in order for the formatter to read content.</value>
|
||||
</data>
|
||||
<data name="MissingDataMemberIsRequired" xml:space="preserve">
|
||||
<value>Property '{0}' on type '{1}' is invalid. Value-typed properties marked as [Required] must also be marked with [DataMember(IsRequired=true)] to be recognized as required. Consider attributing the declaring type with [DataContract] and the property with [DataMember(IsRequired=true)].</value>
|
||||
</data>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
public class FormValueProviderFactory : IValueProviderFactory
|
||||
{
|
||||
private static MediaTypeHeaderValue _formEncodedContentType =
|
||||
MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
|
||||
MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
|
||||
|
||||
public IValueProvider GetValueProvider([NotNull] ValueProviderFactoryContext context)
|
||||
{
|
||||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
MediaTypeHeaderValue requestContentType = null;
|
||||
return MediaTypeHeaderValue.TryParse(request.ContentType, out requestContentType) &&
|
||||
_formEncodedContentType.IsSubsetOf(requestContentType);
|
||||
_formEncodedContentType.IsSubsetOf(requestContentType);
|
||||
}
|
||||
|
||||
private static CultureInfo GetCultureInfo(HttpRequest request)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class DelegatingStreamTests
|
||||
{
|
||||
|
|
@ -8,14 +8,43 @@ using System.IO;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class JsonInputFormatterTest
|
||||
{
|
||||
{
|
||||
|
||||
[Theory]
|
||||
[InlineData("application/json", true)]
|
||||
[InlineData("application/*", true)]
|
||||
[InlineData("*/*", true)]
|
||||
[InlineData("text/json", true)]
|
||||
[InlineData("text/*", true)]
|
||||
[InlineData("text/xml", false)]
|
||||
[InlineData("application/xml", false)]
|
||||
[InlineData("", false)]
|
||||
[InlineData(null, false)]
|
||||
[InlineData("invalid", false)]
|
||||
public void CanRead_ReturnsTrueForAnySupportedContentType(string requestContentType, bool expectedCanRead)
|
||||
{
|
||||
// Arrange
|
||||
var formatter = new JsonInputFormatter();
|
||||
var contentBytes = Encoding.UTF8.GetBytes("content");
|
||||
|
||||
var actionContext = GetActionContext(contentBytes, contentType: requestContentType);
|
||||
var formatterContext = new InputFormatterContext(actionContext, typeof(string));
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(formatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedCanRead, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultMediaType_ReturnsApplicationJson()
|
||||
{
|
||||
|
|
@ -48,16 +77,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var formatter = new JsonInputFormatter();
|
||||
var contentBytes = Encoding.UTF8.GetBytes(content);
|
||||
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var modelState = new ModelStateDictionary();
|
||||
var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, type);
|
||||
var context = new InputFormatterContext(httpContext, metadata, modelState);
|
||||
var actionContext = GetActionContext(contentBytes);
|
||||
var context = new InputFormatterContext(actionContext, type);
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, context.Model);
|
||||
Assert.Equal(expected, model);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -68,18 +95,17 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var formatter = new JsonInputFormatter();
|
||||
var contentBytes = Encoding.UTF8.GetBytes(content);
|
||||
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var modelState = new ModelStateDictionary();
|
||||
var actionContext = GetActionContext(contentBytes);
|
||||
var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(User));
|
||||
var context = new InputFormatterContext(httpContext, metadata, modelState);
|
||||
var context = new InputFormatterContext(actionContext, metadata.ModelType);
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
var model = Assert.IsType<User>(context.Model);
|
||||
Assert.Equal("Person Name", model.Name);
|
||||
Assert.Equal(30, model.Age);
|
||||
var userModel = Assert.IsType<User>(model);
|
||||
Assert.Equal("Person Name", userModel.Name);
|
||||
Assert.Equal(30, userModel.Age);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -90,10 +116,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var formatter = new JsonInputFormatter();
|
||||
var contentBytes = Encoding.UTF8.GetBytes(content);
|
||||
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetActionContext(contentBytes);
|
||||
var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(User));
|
||||
var context = new InputFormatterContext(httpContext, metadata, modelState);
|
||||
var context = new InputFormatterContext(httpContext, metadata.ModelType);
|
||||
|
||||
// Act and Assert
|
||||
await Assert.ThrowsAsync<JsonReaderException>(() => formatter.ReadAsync(context));
|
||||
|
|
@ -107,17 +132,24 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var formatter = new JsonInputFormatter { CaptureDeserilizationErrors = true };
|
||||
var contentBytes = Encoding.UTF8.GetBytes(content);
|
||||
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var modelState = new ModelStateDictionary();
|
||||
var actionContext = GetActionContext(contentBytes);
|
||||
var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(User));
|
||||
var context = new InputFormatterContext(httpContext, metadata, modelState);
|
||||
var context = new InputFormatterContext(actionContext, metadata.ModelType);
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Could not convert string to decimal: not-an-age. Path 'Age', line 1, position 39.",
|
||||
modelState["Age"].Errors[0].Exception.Message);
|
||||
Assert.Equal("Could not convert string to decimal: not-an-age. Path 'Age', line 1, position 39.",
|
||||
actionContext.ModelState["Age"].Errors[0].Exception.Message);
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
@ -125,12 +157,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
headers.SetupGet(h => h["Content-Type"]).Returns(contentType);
|
||||
request.SetupGet(r => r.Headers).Returns(headers.Object);
|
||||
request.SetupGet(f => f.Body).Returns(new MemoryStream(contentBytes));
|
||||
request.SetupGet(f => f.ContentType).Returns(contentType);
|
||||
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
httpContext.SetupGet(c => c.Request).Returns(request.Object);
|
||||
httpContext.SetupGet(c => c.Request).Returns(request.Object);
|
||||
return httpContext.Object;
|
||||
}
|
||||
|
||||
|
|
@ -10,10 +10,11 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class DataContractSerializerInputFormatterTests
|
||||
{
|
||||
|
|
@ -43,6 +44,33 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
public TestLevelOne TestOne { get; set; }
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("application/xml", true)]
|
||||
[InlineData("application/*", true)]
|
||||
[InlineData("*/*", true)]
|
||||
[InlineData("text/xml", true)]
|
||||
[InlineData("text/*", true)]
|
||||
[InlineData("text/json", false)]
|
||||
[InlineData("application/json", false)]
|
||||
[InlineData("", false)]
|
||||
[InlineData(null, false)]
|
||||
[InlineData("invalid", false)]
|
||||
public void CanRead_ReturnsTrueForAnySupportedContentType(string requestContentType, bool expectedCanRead)
|
||||
{
|
||||
// Arrange
|
||||
var formatter = new XmlDataContractSerializerInputFormatter();
|
||||
var contentBytes = Encoding.UTF8.GetBytes("content");
|
||||
|
||||
var actionContext = GetActionContext(contentBytes, contentType: requestContentType);
|
||||
var formatterContext = new InputFormatterContext(actionContext, typeof(string));
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(formatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedCanRead, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void XmlDataContractSerializerFormatterHasProperSuppportedMediaTypes()
|
||||
{
|
||||
|
|
@ -85,15 +113,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelOne));
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
Assert.IsType<TestLevelOne>(context.Model);
|
||||
Assert.NotNull(model);
|
||||
Assert.IsType<TestLevelOne>(model);
|
||||
|
||||
var model = context.Model as TestLevelOne;
|
||||
Assert.Equal(expectedInt, model.SampleInt);
|
||||
Assert.Equal(expectedString, model.sampleString);
|
||||
var levelOneModel = model as TestLevelOne;
|
||||
Assert.Equal(expectedInt, levelOneModel.SampleInt);
|
||||
Assert.Equal(expectedString, levelOneModel.sampleString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -114,16 +142,16 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
Assert.IsType<TestLevelTwo>(context.Model);
|
||||
Assert.NotNull(model);
|
||||
Assert.IsType<TestLevelTwo>(model);
|
||||
|
||||
var model = context.Model as TestLevelTwo;
|
||||
Assert.Equal(expectedLevelTwoString, model.SampleString);
|
||||
Assert.Equal(expectedInt, model.TestOne.SampleInt);
|
||||
Assert.Equal(expectedString, model.TestOne.sampleString);
|
||||
var levelTwoModel = model as TestLevelTwo;
|
||||
Assert.Equal(expectedLevelTwoString, levelTwoModel.SampleString);
|
||||
Assert.Equal(expectedInt, levelTwoModel.TestOne.SampleInt);
|
||||
Assert.Equal(expectedString, levelTwoModel.TestOne.sampleString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -141,13 +169,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
Assert.IsType<DummyClass>(context.Model);
|
||||
var model = context.Model as DummyClass;
|
||||
Assert.Equal(expectedInt, model.SampleInt);
|
||||
Assert.NotNull(model);
|
||||
Assert.IsType<DummyClass>(model);
|
||||
var dummyModel = model as DummyClass;
|
||||
Assert.Equal(expectedInt, dummyModel.SampleInt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -205,11 +233,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
Assert.True(context.HttpContext.Request.Body.CanRead);
|
||||
Assert.NotNull(model);
|
||||
Assert.True(context.ActionContext.HttpContext.Request.Body.CanRead);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -254,14 +282,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
var model = context.Model as TestLevelTwo;
|
||||
Assert.NotNull(model);
|
||||
var levelTwoModel = model as TestLevelTwo;
|
||||
Buffer.BlockCopy(sampleStringBytes, 0, expectedBytes, 0, sampleStringBytes.Length);
|
||||
Buffer.BlockCopy(bom, 0, expectedBytes, sampleStringBytes.Length, bom.Length);
|
||||
Assert.Equal(expectedBytes, Encoding.UTF8.GetBytes(model.SampleString));
|
||||
Assert.Equal(expectedBytes, Encoding.UTF8.GetBytes(levelTwoModel.SampleString));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -280,36 +308,43 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelOne));
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
Assert.IsType<TestLevelOne>(context.Model);
|
||||
Assert.NotNull(model);
|
||||
Assert.IsType<TestLevelOne>(model);
|
||||
|
||||
var model = context.Model as TestLevelOne;
|
||||
Assert.Equal(expectedInt, model.SampleInt);
|
||||
Assert.Equal(expectedString, model.sampleString);
|
||||
var levelOneModel = model as TestLevelOne;
|
||||
Assert.Equal(expectedInt, levelOneModel.SampleInt);
|
||||
Assert.Equal(expectedString, levelOneModel.sampleString);
|
||||
}
|
||||
|
||||
private InputFormatterContext GetInputFormatterContext(byte[] contentBytes, Type modelType)
|
||||
{
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var modelState = new ModelStateDictionary();
|
||||
var actionContext = GetActionContext(contentBytes);
|
||||
var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, modelType);
|
||||
return new InputFormatterContext(httpContext, metadata, modelState);
|
||||
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());
|
||||
}
|
||||
private static HttpContext GetHttpContext(byte[] contentBytes,
|
||||
string contentType = "application/xml")
|
||||
string contentType = "application/xml")
|
||||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
headers.SetupGet(h => h["Content-Type"]).Returns(contentType);
|
||||
request.SetupGet(r => r.Headers).Returns(headers.Object);
|
||||
request.SetupGet(f => f.Body).Returns(new MemoryStream(contentBytes));
|
||||
request.SetupGet(f => f.ContentType).Returns(contentType);
|
||||
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
httpContext.SetupGet(c => c.Request).Returns(request.Object);
|
||||
httpContext.SetupGet(c => c.Request).Returns(request.Object);
|
||||
return httpContext.Object;
|
||||
}
|
||||
}
|
||||
|
|
@ -9,10 +9,11 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class XmlSerializerInputFormatterTests
|
||||
{
|
||||
|
|
@ -34,6 +35,33 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
public TestLevelOne TestOne { get; set; }
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("application/xml", true)]
|
||||
[InlineData("application/*", true)]
|
||||
[InlineData("*/*", true)]
|
||||
[InlineData("text/xml", true)]
|
||||
[InlineData("text/*", true)]
|
||||
[InlineData("text/json", false)]
|
||||
[InlineData("application/json", false)]
|
||||
[InlineData("", false)]
|
||||
[InlineData("invalid", false)]
|
||||
[InlineData(null, false)]
|
||||
public void CanRead_ReturnsTrueForAnySupportedContentType(string requestContentType, bool expectedCanRead)
|
||||
{
|
||||
// Arrange
|
||||
var formatter = new XmlSerializerInputFormatter();
|
||||
var contentBytes = Encoding.UTF8.GetBytes("content");
|
||||
|
||||
var actionContext = GetActionContext(contentBytes, contentType: requestContentType);
|
||||
var formatterContext = new InputFormatterContext(actionContext, typeof(string));
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(formatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedCanRead, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void XmlSerializerFormatterHasProperSuppportedMediaTypes()
|
||||
{
|
||||
|
|
@ -78,16 +106,17 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelOne));
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
Assert.IsType<TestLevelOne>(context.Model);
|
||||
Assert.NotNull(model);
|
||||
Assert.IsType<TestLevelOne>(model);
|
||||
|
||||
var model = context.Model as TestLevelOne;
|
||||
Assert.Equal(expectedInt, model.SampleInt);
|
||||
Assert.Equal(expectedString, model.sampleString);
|
||||
Assert.Equal(XmlConvert.ToDateTime(expectedDateTime, XmlDateTimeSerializationMode.Utc), model.SampleDate);
|
||||
var levelOneModel = model as TestLevelOne;
|
||||
Assert.Equal(expectedInt, levelOneModel.SampleInt);
|
||||
Assert.Equal(expectedString, levelOneModel.sampleString);
|
||||
Assert.Equal(XmlConvert.ToDateTime(expectedDateTime, XmlDateTimeSerializationMode.Utc),
|
||||
levelOneModel.SampleDate);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -110,17 +139,18 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
Assert.IsType<TestLevelTwo>(context.Model);
|
||||
Assert.NotNull(model);
|
||||
Assert.IsType<TestLevelTwo>(model);
|
||||
|
||||
var model = context.Model as TestLevelTwo;
|
||||
Assert.Equal(expectedLevelTwoString, model.SampleString);
|
||||
Assert.Equal(expectedInt, model.TestOne.SampleInt);
|
||||
Assert.Equal(expectedString, model.TestOne.sampleString);
|
||||
Assert.Equal(XmlConvert.ToDateTime(expectedDateTime, XmlDateTimeSerializationMode.Utc), model.TestOne.SampleDate);
|
||||
var levelTwoModel = model as TestLevelTwo;
|
||||
Assert.Equal(expectedLevelTwoString, levelTwoModel.SampleString);
|
||||
Assert.Equal(expectedInt, levelTwoModel.TestOne.SampleInt);
|
||||
Assert.Equal(expectedString, levelTwoModel.TestOne.sampleString);
|
||||
Assert.Equal(XmlConvert.ToDateTime(expectedDateTime, XmlDateTimeSerializationMode.Utc),
|
||||
levelTwoModel.TestOne.SampleDate);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -138,13 +168,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
Assert.IsType<DummyClass>(context.Model);
|
||||
var model = context.Model as DummyClass;
|
||||
Assert.Equal(expectedInt, model.SampleInt);
|
||||
Assert.NotNull(model);
|
||||
Assert.IsType<DummyClass>(model);
|
||||
var dummyModel = model as DummyClass;
|
||||
Assert.Equal(expectedInt, dummyModel.SampleInt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -206,11 +236,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
Assert.True(context.HttpContext.Request.Body.CanRead);
|
||||
Assert.NotNull(model);
|
||||
Assert.True(context.ActionContext.HttpContext.Request.Body.CanRead);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -255,14 +285,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
var model = context.Model as TestLevelTwo;
|
||||
Assert.NotNull(model);
|
||||
var levelTwoModel = model as TestLevelTwo;
|
||||
Buffer.BlockCopy(sampleStringBytes, 0, expectedBytes, 0, sampleStringBytes.Length);
|
||||
Buffer.BlockCopy(bom, 0, expectedBytes, sampleStringBytes.Length, bom.Length);
|
||||
Assert.Equal(expectedBytes, Encoding.UTF8.GetBytes(model.SampleString));
|
||||
Assert.Equal(expectedBytes, Encoding.UTF8.GetBytes(levelTwoModel.SampleString));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -283,37 +313,44 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelOne));
|
||||
|
||||
// Act
|
||||
await formatter.ReadAsync(context);
|
||||
var model = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(context.Model);
|
||||
Assert.IsType<TestLevelOne>(context.Model);
|
||||
Assert.NotNull(model);
|
||||
Assert.IsType<TestLevelOne>(model);
|
||||
|
||||
var model = context.Model as TestLevelOne;
|
||||
Assert.Equal(expectedInt, model.SampleInt);
|
||||
Assert.Equal(expectedString, model.sampleString);
|
||||
Assert.Equal(XmlConvert.ToDateTime(expectedDateTime, XmlDateTimeSerializationMode.Utc), model.SampleDate);
|
||||
var levelOneModel = model as TestLevelOne;
|
||||
Assert.Equal(expectedInt, levelOneModel.SampleInt);
|
||||
Assert.Equal(expectedString, levelOneModel.sampleString);
|
||||
Assert.Equal(XmlConvert.ToDateTime(expectedDateTime, XmlDateTimeSerializationMode.Utc), levelOneModel.SampleDate);
|
||||
}
|
||||
|
||||
private InputFormatterContext GetInputFormatterContext(byte[] contentBytes, Type modelType)
|
||||
{
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var modelState = new ModelStateDictionary();
|
||||
var actionContext = GetActionContext(contentBytes);
|
||||
var metadata = new EmptyModelMetadataProvider().GetMetadataForType(null, modelType);
|
||||
return new InputFormatterContext(httpContext, metadata, modelState);
|
||||
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());
|
||||
}
|
||||
private static HttpContext GetHttpContext(byte[] contentBytes,
|
||||
string contentType = "application/xml")
|
||||
string contentType = "application/xml")
|
||||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
headers.SetupGet(h => h["Content-Type"]).Returns(contentType);
|
||||
request.SetupGet(r => r.Headers).Returns(headers.Object);
|
||||
request.SetupGet(f => f.Body).Returns(new MemoryStream(contentBytes));
|
||||
request.SetupGet(f => f.ContentType).Returns(contentType);
|
||||
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
httpContext.SetupGet(c => c.Request).Returns(request.Object);
|
||||
httpContext.SetupGet(c => c.Request).Returns(request.Object);
|
||||
return httpContext.Object;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.OptionDescriptors;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Xunit;
|
||||
|
|
@ -14,12 +17,53 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var expected = "The type 'System.String' must derive from " +
|
||||
"'Microsoft.AspNet.Mvc.ModelBinding.IInputFormatter'.";
|
||||
"'Microsoft.AspNet.Mvc.IInputFormatter'.";
|
||||
|
||||
var type = typeof(string);
|
||||
|
||||
// Act & Assert
|
||||
ExceptionAssert.ThrowsArgument(() => new InputFormatterDescriptor(type), "type", expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConstructorSets_InputFormatterType()
|
||||
{
|
||||
// Arrange
|
||||
var type = typeof(TestInputFormatter);
|
||||
|
||||
// Act
|
||||
var descriptor = new InputFormatterDescriptor(type);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(type, descriptor.OptionType);
|
||||
Assert.Null(descriptor.Instance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConstructorSets_InputFormatterInstanceAndType()
|
||||
{
|
||||
// Arrange
|
||||
var testFormatter = new TestInputFormatter();
|
||||
|
||||
// Act
|
||||
var descriptor = new InputFormatterDescriptor(testFormatter);
|
||||
|
||||
// Assert
|
||||
Assert.Same(testFormatter, descriptor.Instance);
|
||||
Assert.Equal(testFormatter.GetType(), descriptor.OptionType);
|
||||
}
|
||||
|
||||
private class TestInputFormatter : IInputFormatter
|
||||
{
|
||||
public bool CanRead(InputFormatterContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<object> ReadAsync(InputFormatterContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.Mvc.OptionDescriptors;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Xunit;
|
||||
|
|
@ -21,5 +24,46 @@ namespace Microsoft.AspNet.Mvc.Core
|
|||
// Act & Assert
|
||||
ExceptionAssert.ThrowsArgument(() => new OutputFormatterDescriptor(type), "type", expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConstructorSets_OutputFormatterType()
|
||||
{
|
||||
// Arrange
|
||||
var type = typeof(TestOutputFormatter);
|
||||
|
||||
// Act
|
||||
var descriptor = new OutputFormatterDescriptor(type);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(type, descriptor.OptionType);
|
||||
Assert.Null(descriptor.Instance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConstructorSets_OutputFormatterInsnaceAndType()
|
||||
{
|
||||
// Arrange
|
||||
var testFormatter = new TestOutputFormatter();
|
||||
|
||||
// Act
|
||||
var descriptor = new OutputFormatterDescriptor(testFormatter);
|
||||
|
||||
// Assert
|
||||
Assert.Same(testFormatter, descriptor.Instance);
|
||||
Assert.Equal(testFormatter.GetType(), descriptor.OptionType);
|
||||
}
|
||||
|
||||
private class TestOutputFormatter : IOutputFormatter
|
||||
{
|
||||
public bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task WriteAsync(OutputFormatterContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,8 +37,13 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
Assert.Equal(sampleInputInt.ToString(), await response.ReadBodyAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task JsonInputFormatter_IsSelectedForJsonRequest()
|
||||
[Theory]
|
||||
[InlineData("application/json")]
|
||||
[InlineData("application/*")]
|
||||
[InlineData("*/*")]
|
||||
[InlineData("text/json")]
|
||||
[InlineData("text/*")]
|
||||
public async Task JsonInputFormatter_IsSelectedForJsonRequest(string requestContentType)
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
|
|
@ -47,13 +52,33 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var input = "{\"SampleInt\":10}";
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync("http://localhost/Home/Index", input, "application/json");
|
||||
var response = await client.PostAsync("http://localhost/Home/Index", input, requestContentType);
|
||||
|
||||
//Assert
|
||||
Assert.Equal(200, response.StatusCode);
|
||||
Assert.Equal(sampleInputInt.ToString(), await response.ReadBodyAsStringAsync());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData(null)]
|
||||
[InlineData("invalid")]
|
||||
public async Task JsonInputFormatter_IsNotSelectedForNonJsonRequests(string requestContentType)
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.Handler;
|
||||
var input = "{\"SampleInt\":10}";
|
||||
|
||||
// Act
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>
|
||||
(() => client.PostAsync("http://localhost/Home/CheckIfDummyIsNull", input, requestContentType));
|
||||
|
||||
//Assert
|
||||
// TODO: Change the validation after https://github.com/aspnet/Mvc/issues/458 is fixed.
|
||||
Assert.Equal("415: Unsupported content type " + requestContentType, ex.Message);
|
||||
}
|
||||
|
||||
// TODO: By default XmlSerializerInputFormatter is called because of the order in which
|
||||
// the formatters are registered. Add a test to call into DataContractSerializerInputFormatter.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
|||
null,
|
||||
MediaTypeHeaderValueRange.AllMediaRange,
|
||||
new Dictionary<string, string>(),
|
||||
FormattingUtilities.Match,
|
||||
HttpHeaderUtilitites.Match,
|
||||
"*/*"
|
||||
};
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
|||
"utf-8",
|
||||
MediaTypeHeaderValueRange.SubtypeMediaRange,
|
||||
new Dictionary<string, string>() { { "charset", "utf-8" }, { "foo", "bar" } },
|
||||
FormattingUtilities.Match,
|
||||
HttpHeaderUtilitites.Match,
|
||||
"text/*;charset=utf-8;foo=bar",
|
||||
};
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
|||
"utf-8",
|
||||
MediaTypeHeaderValueRange.None,
|
||||
new Dictionary<string, string>() { { "charset", "utf-8" }, { "foo", "bar" }, { "q", "0.0" } },
|
||||
FormattingUtilities.NoMatch,
|
||||
HttpHeaderUtilitites.NoMatch,
|
||||
"text/plain;charset=utf-8;foo=bar;q=0.0",
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
|||
public class StringWithQualityHeaderValueParsingTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("*", FormattingUtilities.Match, "*")]
|
||||
[InlineData("*", HttpHeaderUtilitites.Match, "*")]
|
||||
[InlineData("*", 0.7, "*;q=.7")]
|
||||
[InlineData("iso-8859-5", FormattingUtilities.Match, "iso-8859-5")]
|
||||
[InlineData("iso-8859-5", HttpHeaderUtilitites.Match, "iso-8859-5")]
|
||||
[InlineData("unicode-1-1", 0.8, "unicode-1-1;q=0.8")]
|
||||
[InlineData("unicode-1-1", 0.8, "unicode-1-1;q =0.8")]
|
||||
[InlineData("unicode-1-1", 0.8, "unicode-1-1;q = 0.8")]
|
||||
|
|
|
|||
|
|
@ -18,5 +18,11 @@ namespace FormatterWebSite.Controllers
|
|||
{
|
||||
return new DummyClass { SampleInt = sampleInput };
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public bool CheckIfDummyIsNull([FromBody] DummyClass dummy)
|
||||
{
|
||||
return dummy != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue