Correct StyleCop violations
- StyleCop working again (handles C# 6.0 additions) though only locally for me - disable some new rules: - ConstFieldNamesMustBeginWithUpperCaseLetter - InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyElements - StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElements - StaticReadonlyFieldsMustBeginWithUpperCaseLetter - PrefixCallsCorrectly - correct remaining violations - lots of long lines for example - use more `var`; some manual updates since StyleCop doesn't check seemingly-unused blocks nit: remove new trailing whitespace (was paranoid about adding it w/ fixes)
This commit is contained in:
parent
227f564098
commit
6df288bce7
|
|
@ -12,6 +12,11 @@
|
|||
<Analyzers>
|
||||
<Analyzer AnalyzerId="StyleCop.CSharp.NamingRules">
|
||||
<Rules>
|
||||
<Rule Name="ConstFieldNamesMustBeginWithUpperCaseLetter">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="FieldNamesMustNotBeginWithUnderscore">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
|
|
@ -22,6 +27,11 @@
|
|||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="StaticReadonlyFieldsMustBeginWithUpperCaseLetter">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
</Rules>
|
||||
<AnalyzerSettings>
|
||||
<CollectionProperty Name="Hungarian">
|
||||
|
|
@ -274,6 +284,11 @@
|
|||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="PrefixCallsCorrectly">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="PrefixLocalCallsWithThis">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
|
|
@ -384,11 +399,21 @@
|
|||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyElements">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="StaticElementsMustAppearBeforeInstanceElements">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
<Rule Name="StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElements">
|
||||
<RuleSettings>
|
||||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
</Rules>
|
||||
<AnalyzerSettings />
|
||||
</Analyzer>
|
||||
|
|
@ -399,7 +424,7 @@
|
|||
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||
</RuleSettings>
|
||||
</Rule>
|
||||
|
||||
|
||||
<!-- Creates a lot of noise with anonymous objects -->
|
||||
<Rule Name="OpeningCurlyBracketsMustBeSpacedCorrectly">
|
||||
<RuleSettings>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
return false;
|
||||
}
|
||||
|
||||
for (int idx = 0; idx < t1.Length; ++idx)
|
||||
for (var idx = 0; idx < t1.Length; ++idx)
|
||||
{
|
||||
if (t1[idx] != t2[idx])
|
||||
{
|
||||
|
|
|
|||
|
|
@ -119,7 +119,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
throw new FileNotFoundException(message, path);
|
||||
}
|
||||
|
||||
// Internal for unit testing purposes only
|
||||
/// <summary>
|
||||
/// Creates a normalized representation of the given <paramref name="path"/>. The default
|
||||
/// implementation doesn't support files with '\' in the file name and treats the '\' as
|
||||
|
|
@ -128,6 +127,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// </summary>
|
||||
/// <param name="path">The path to normalize.</param>
|
||||
/// <returns>The normalized path.</returns>
|
||||
// Internal for unit testing purposes only
|
||||
protected internal virtual string NormalizePath([NotNull] string path)
|
||||
{
|
||||
// Unix systems support '\' as part of the file name. So '\' is not
|
||||
|
|
@ -153,13 +153,13 @@ namespace Microsoft.AspNet.Mvc
|
|||
return path.Replace('\\', '/');
|
||||
}
|
||||
|
||||
// Internal for unit testing purposes only
|
||||
/// <summary>
|
||||
/// Determines if the provided path is absolute or relative. The default implementation considers
|
||||
/// paths starting with '/' to be relative.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to examine.</param>
|
||||
/// <returns>True if the path is absolute.</returns>
|
||||
// Internal for unit testing purposes only
|
||||
protected internal virtual bool IsPathRooted([NotNull] string path)
|
||||
{
|
||||
// We consider paths to be rooted if they start with '<<VolumeLetter>>:' and do
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
builder.Append('%');
|
||||
|
||||
int i = b;
|
||||
var i = b;
|
||||
AddHexDigitToStringBuilder(i >> 4, builder);
|
||||
AddHexDigitToStringBuilder(i % 16, builder);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// 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.
|
||||
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
internal sealed class AntiForgeryToken
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
public AntiForgeryToken GetCookieToken(HttpContext httpContext)
|
||||
{
|
||||
var contextAccessor = httpContext.RequestServices.GetRequiredService<IContextAccessor<AntiForgeryContext>>();
|
||||
var contextAccessor =
|
||||
httpContext.RequestServices.GetRequiredService<IContextAccessor<AntiForgeryContext>>();
|
||||
if (contextAccessor.Value != null)
|
||||
{
|
||||
return contextAccessor.Value.CookieToken;
|
||||
|
|
@ -56,7 +57,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Add the cookie to the request based context.
|
||||
// This is useful if the cookie needs to be reloaded in the context of the same request.
|
||||
var contextAccessor = httpContext.RequestServices.GetRequiredService<IContextAccessor<AntiForgeryContext>>();
|
||||
var contextAccessor =
|
||||
httpContext.RequestServices.GetRequiredService<IContextAccessor<AntiForgeryContext>>();
|
||||
Debug.Assert(contextAccessor.Value == null, "AntiForgeryContext should be set only once per request.");
|
||||
contextAccessor.SetValue(new AntiForgeryContext() { CookieToken = token });
|
||||
|
||||
|
|
|
|||
|
|
@ -233,7 +233,6 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
|
|||
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0] == methodInfo);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="ActionModel"/> for the given <see cref="MethodInfo"/>.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -67,9 +67,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
if (_viewEngine == null)
|
||||
{
|
||||
_viewEngine = ActionContext?.
|
||||
HttpContext?.
|
||||
RequestServices.GetRequiredService<ICompositeViewEngine>();
|
||||
_viewEngine =
|
||||
ActionContext?.HttpContext?.RequestServices.GetRequiredService<ICompositeViewEngine>();
|
||||
}
|
||||
|
||||
return _viewEngine;
|
||||
|
|
@ -797,7 +796,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified <paramref name="model"/> instance using values from the controller's current
|
||||
/// Updates the specified <paramref name="model"/> instance using values from the controller's current
|
||||
/// <see cref="IValueProvider"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">The type of the model object.</typeparam>
|
||||
|
|
@ -811,7 +810,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified <paramref name="model"/> instance using values from the controller's current
|
||||
/// Updates the specified <paramref name="model"/> instance using values from the controller's current
|
||||
/// <see cref="IValueProvider"/> and a <paramref name="prefix"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">The type of the model object.</typeparam>
|
||||
|
|
@ -826,7 +825,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
if (BindingContextProvider == null)
|
||||
{
|
||||
var message = Resources.FormatPropertyOfTypeCannotBeNull(nameof(BindingContextProvider),
|
||||
var message = Resources.FormatPropertyOfTypeCannotBeNull(nameof(BindingContextProvider),
|
||||
GetType().FullName);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
|
@ -836,7 +835,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified <paramref name="model"/> instance using the <paramref name="valueProvider"/> and a
|
||||
/// Updates the specified <paramref name="model"/> instance using the <paramref name="valueProvider"/> and a
|
||||
/// <paramref name="prefix"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">The type of the model object.</typeparam>
|
||||
|
|
@ -853,7 +852,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
if (BindingContextProvider == null)
|
||||
{
|
||||
var message = Resources.FormatPropertyOfTypeCannotBeNull(nameof(BindingContextProvider),
|
||||
var message = Resources.FormatPropertyOfTypeCannotBeNull(nameof(BindingContextProvider),
|
||||
GetType().FullName);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
|
@ -870,14 +869,14 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified <paramref name="model"/> instance using values from the controller's current
|
||||
/// Updates the specified <paramref name="model"/> instance using values from the controller's current
|
||||
/// <see cref="IValueProvider"/> and a <paramref name="prefix"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">The type of the model object.</typeparam>
|
||||
/// <param name="model">The model instance to update.</param>
|
||||
/// <param name="prefix">The prefix to use when looking up values in the current <see cref="IValueProvider"/>.
|
||||
/// </param>
|
||||
/// <param name="includeExpressions"> <see cref="Expression"/>(s) which represent top-level properties
|
||||
/// <param name="includeExpressions"> <see cref="Expression"/>(s) which represent top-level properties
|
||||
/// which need to be included for the current model.</param>
|
||||
/// <returns>A <see cref="Task"/> that on completion returns <c>true</c> if the update is successful</returns>
|
||||
[NonAction]
|
||||
|
|
@ -907,7 +906,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified <paramref name="model"/> instance using values from the controller's current
|
||||
/// Updates the specified <paramref name="model"/> instance using values from the controller's current
|
||||
/// <see cref="IValueProvider"/> and a <paramref name="prefix"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">The type of the model object.</typeparam>
|
||||
|
|
@ -925,7 +924,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
if (BindingContextProvider == null)
|
||||
{
|
||||
var message = Resources.FormatPropertyOfTypeCannotBeNull(nameof(BindingContextProvider),
|
||||
var message = Resources.FormatPropertyOfTypeCannotBeNull(nameof(BindingContextProvider),
|
||||
GetType().FullName);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
|
@ -943,7 +942,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified <paramref name="model"/> instance using the <paramref name="valueProvider"/> and a
|
||||
/// Updates the specified <paramref name="model"/> instance using the <paramref name="valueProvider"/> and a
|
||||
/// <paramref name="prefix"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">The type of the model object.</typeparam>
|
||||
|
|
@ -951,7 +950,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <param name="prefix">The prefix to use when looking up values in the <paramref name="valueProvider"/>
|
||||
/// </param>
|
||||
/// <param name="valueProvider">The <see cref="IValueProvider"/> used for looking up values.</param>
|
||||
/// <param name="includeExpressions"> <see cref="Expression"/>(s) which represent top-level properties
|
||||
/// <param name="includeExpressions"> <see cref="Expression"/>(s) which represent top-level properties
|
||||
/// which need to be included for the current model.</param>
|
||||
/// <returns>A <see cref="Task"/> that on completion returns <c>true</c> if the update is successful</returns>
|
||||
[NonAction]
|
||||
|
|
@ -964,7 +963,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
if (BindingContextProvider == null)
|
||||
{
|
||||
var message = Resources.FormatPropertyOfTypeCannotBeNull(nameof(BindingContextProvider),
|
||||
var message = Resources.FormatPropertyOfTypeCannotBeNull(nameof(BindingContextProvider),
|
||||
GetType().FullName);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
|
@ -982,7 +981,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified <paramref name="model"/> instance using the <paramref name="valueProvider"/> and a
|
||||
/// Updates the specified <paramref name="model"/> instance using the <paramref name="valueProvider"/> and a
|
||||
/// <paramref name="prefix"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">The type of the model object.</typeparam>
|
||||
|
|
@ -1002,7 +1001,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
if (BindingContextProvider == null)
|
||||
{
|
||||
var message = Resources.FormatPropertyOfTypeCannotBeNull(nameof(BindingContextProvider),
|
||||
var message = Resources.FormatPropertyOfTypeCannotBeNull(nameof(BindingContextProvider),
|
||||
GetType().FullName);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNet.Mvc.Logging;
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
using Microsoft.AspNet.Mvc.Logging;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
public class DefaultAssemblyProvider : IAssemblyProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the set of assembly names that are used as root for discovery of
|
||||
/// Gets the set of assembly names that are used as root for discovery of
|
||||
/// MVC controllers, view components and views.
|
||||
/// </summary>
|
||||
protected virtual HashSet<string> ReferenceAssemblies { get; } = new HashSet<string>(StringComparer.Ordinal)
|
||||
|
|
@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
/// <summary>
|
||||
/// Returns a list of libraries that references the assemblies in <see cref="ReferenceAssemblies"/>.
|
||||
/// By default it returns all assemblies that reference any of the primary MVC assemblies
|
||||
/// By default it returns all assemblies that reference any of the primary MVC assemblies
|
||||
/// while ignoring MVC assemblies.
|
||||
/// </summary>
|
||||
/// <returns>A set of <see cref="ILibraryInformation"/>.</returns>
|
||||
|
|
|
|||
|
|
@ -87,7 +87,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
foreach (var parameter in parameterMetadata)
|
||||
{
|
||||
var parameterType = parameter.ModelType;
|
||||
var modelBindingContext = GetModelBindingContext(parameter, actionBindingContext, operationBindingContext);
|
||||
var modelBindingContext =
|
||||
GetModelBindingContext(parameter, actionBindingContext, operationBindingContext);
|
||||
if (await actionBindingContext.ModelBinder.BindModelAsync(modelBindingContext))
|
||||
{
|
||||
arguments[parameter.PropertyName] = modelBindingContext.Model;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
public class DefaultPropertyBindingPredicateProvider<TModel> : IPropertyBindingPredicateProvider
|
||||
where TModel : class
|
||||
{
|
||||
private static readonly Func<ModelBindingContext, string, bool> _defaultFilter = (context, propertyName) => true;
|
||||
private static readonly Func<ModelBindingContext, string, bool> _defaultFilter =
|
||||
(context, propertyName) => true;
|
||||
|
||||
/// <summary>
|
||||
/// The prefix which is used while generating the property filter.
|
||||
|
|
@ -57,7 +58,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
private Func<ModelBindingContext, string, bool> GetPredicateFromExpression(IEnumerable<Expression<Func<TModel, object>>> includeExpressions)
|
||||
private Func<ModelBindingContext, string, bool> GetPredicateFromExpression(
|
||||
IEnumerable<Expression<Func<TModel, object>>> includeExpressions)
|
||||
{
|
||||
var expression = ModelBindingHelper.GetIncludePredicateExpression(Prefix, includeExpressions.ToArray());
|
||||
return expression.Compile();
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ namespace Microsoft.AspNet.Mvc.Description
|
|||
get { return DefaultOrder.DefaultFrameworkSortOrder; }
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Invoke(ApiDescriptionProviderContext context, Action callNext)
|
||||
{
|
||||
|
|
@ -157,7 +156,8 @@ namespace Microsoft.AspNet.Mvc.Description
|
|||
// Process parameters that only appear on the path template if any.
|
||||
foreach (var templateParameter in templateParameters)
|
||||
{
|
||||
var parameterDescription = GetParameter(parameterDescriptor: null, templateParameter: templateParameter);
|
||||
var parameterDescription =
|
||||
GetParameter(parameterDescriptor: null, templateParameter: templateParameter);
|
||||
apiDescription.ParameterDescriptions.Add(parameterDescription);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// 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.
|
||||
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public interface IAuthorizationFilter : IFilter
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// 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.
|
||||
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public interface IExceptionFilter : IFilter
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// 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.
|
||||
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public interface IInputFormatterSelector
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||
public abstract class HttpMethodAttribute : Attribute, IActionHttpMethodProvider, IRouteTemplateProvider
|
||||
{
|
||||
private int? _order;
|
||||
private readonly IEnumerable<string> _httpMethods;
|
||||
private int? _order;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="HttpMethodAttribute"/> with the given
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ namespace Microsoft.AspNet.Mvc.Logging
|
|||
public Type ActionConstraintMetadataType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The constraint order if this is an <see cref="IActionConstraint"/>. See <see cref="IActionConstraint.Order"/>.
|
||||
/// The constraint order if this is an <see cref="IActionConstraint"/>. See
|
||||
/// <see cref="IActionConstraint.Order"/>.
|
||||
/// </summary>
|
||||
public int Order { get; }
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ namespace Microsoft.AspNet.Mvc.Logging
|
|||
AttributeRouteInfo = new AttributeRouteInfoValues(inner.AttributeRouteInfo);
|
||||
RouteValueDefaults = inner.RouteValueDefaults.ToDictionary(i => i.Key, i => i.Value.ToString());
|
||||
ActionConstraints = inner.ActionConstraints?.Select(a => new ActionConstraintValues(a))?.ToList();
|
||||
HttpMethods = inner.ActionConstraints?.OfType<HttpMethodConstraint>().SelectMany(c => c.HttpMethods).ToList();
|
||||
HttpMethods =
|
||||
inner.ActionConstraints?.OfType<HttpMethodConstraint>().SelectMany(c => c.HttpMethods).ToList();
|
||||
Properties = inner.Properties.ToDictionary(i => i.Key.ToString(), i => i.Value.GetType());
|
||||
var controllerActionDescriptor = inner as ControllerActionDescriptor;
|
||||
if (controllerActionDescriptor != null)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// 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 Microsoft.Framework.Logging;
|
||||
using Microsoft.AspNet.Mvc.ApplicationModels;
|
||||
using Microsoft.Framework.Logging;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Logging
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.AspNet.Mvc.ApplicationModels;
|
||||
using Microsoft.Framework.Logging;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Logging
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
using System;
|
||||
// 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.Linq;
|
||||
using Microsoft.Framework.Logging;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
if (formatter == null)
|
||||
{
|
||||
var unsupportedContentType = Resources.FormatUnsupportedContentType(
|
||||
bindingContext.OperationBindingContext.HttpContext.Request.ContentType);
|
||||
bindingContext.OperationBindingContext.HttpContext.Request.ContentType);
|
||||
bindingContext.ModelState.AddModelError(bindingContext.ModelName, unsupportedContentType);
|
||||
|
||||
// Should always return true so that the model binding process ends here.
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
where TModel : class
|
||||
{
|
||||
var includeExpression = GetIncludePredicateExpression(prefix, includeExpressions);
|
||||
Func<ModelBindingContext, string, bool> predicate = includeExpression.Compile();
|
||||
var predicate = includeExpression.Compile();
|
||||
|
||||
return TryUpdateModelAsync(
|
||||
model,
|
||||
|
|
|
|||
|
|
@ -432,7 +432,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
|
||||
if (defaultValue != null)
|
||||
{
|
||||
selectList = UpdateSelectListItemsWithDefaultValue(selectList, defaultValue, allowMultiple, out selectedValues);
|
||||
selectList =
|
||||
UpdateSelectListItemsWithDefaultValue(selectList, defaultValue, allowMultiple, out selectedValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -606,7 +607,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
|
||||
// Only the style of the span is changed according to the errors if message is null or empty.
|
||||
// Otherwise the content and style is handled by the client-side validation.
|
||||
var className = (modelError != null) ? HtmlHelper.ValidationMessageCssClassName : HtmlHelper.ValidationMessageValidCssClassName;
|
||||
var className = (modelError != null) ?
|
||||
HtmlHelper.ValidationMessageCssClassName :
|
||||
HtmlHelper.ValidationMessageValidCssClassName;
|
||||
tagBuilder.AddCssClass(className);
|
||||
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
|
|
|
|||
|
|
@ -702,7 +702,6 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
return CreateForm();
|
||||
}
|
||||
|
||||
|
||||
protected virtual HtmlString GenerateHidden(
|
||||
ModelMetadata metadata,
|
||||
string name,
|
||||
|
|
|
|||
|
|
@ -237,8 +237,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
case '-':
|
||||
case '_':
|
||||
case ':':
|
||||
// Note '.' is valid according to the HTML 4.01 specification. Disallowed here to avoid confusion
|
||||
// with CSS class selectors or when using jQuery.
|
||||
// Note '.' is valid according to the HTML 4.01 specification. Disallowed here to avoid
|
||||
// confusion with CSS class selectors or when using jQuery.
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ namespace Microsoft.AspNet.Mvc.Routing
|
|||
public class AttributeRoute : IRouter
|
||||
{
|
||||
private readonly IRouter _next;
|
||||
private readonly LinkGenerationDecisionTree _linkGenerationTree;
|
||||
private readonly TemplateRoute[] _matchingRoutes;
|
||||
private readonly IDictionary<string, AttributeRouteLinkGenerationEntry> _namedEntries;
|
||||
|
||||
private ILogger _logger;
|
||||
private ILogger _constraintLogger;
|
||||
private readonly LinkGenerationDecisionTree _linkGenerationTree;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="AttributeRoute"/>.
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
private readonly IActionSelector _actionSelector;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UrlHelper"/> class using the specified action context and action selector.
|
||||
/// Initializes a new instance of the <see cref="UrlHelper"/> class using the specified action context and
|
||||
/// action selector.
|
||||
/// </summary>
|
||||
/// <param name="contextAccessor">The <see cref="IContextAccessor{TContext}"/> to access the action context
|
||||
/// of the current request.</param>
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <remarks>
|
||||
/// <see cref="ContentViewComponentResult"/> always writes HTML encoded text from the
|
||||
/// <see cref="EncodedContent"/> property.
|
||||
///
|
||||
///
|
||||
/// When using <see cref="ContentViewComponentResult(string)"/>, the provided content will be HTML
|
||||
/// encoded and stored in <see cref="EncodedContent"/>.
|
||||
///
|
||||
///
|
||||
/// To write pre-encoded conent, use <see cref="ContentViewComponentResult(HtmlString)"/>.
|
||||
/// </remarks>
|
||||
public class ContentViewComponentResult : IViewComponentResult
|
||||
|
|
|
|||
|
|
@ -8,12 +8,11 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
public class ViewContext : ActionContext
|
||||
{
|
||||
private DynamicViewData _viewBag;
|
||||
|
||||
// We need a default FormContext if the user uses html <form> instead of an MvcForm
|
||||
private readonly FormContext _defaultFormContext = new FormContext();
|
||||
|
||||
private FormContext _formContext;
|
||||
private DynamicViewData _viewBag;
|
||||
|
||||
public ViewContext(
|
||||
[NotNull] ActionContext actionContext,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
public class ViewDataDictionary<TModel> : ViewDataDictionary
|
||||
{
|
||||
// References may not show up due to ITypeActivator use in RazorPageActivator.
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ViewDataDictionary{TModel}"/> class.
|
||||
/// </summary>
|
||||
|
|
@ -15,6 +14,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// For use when creating a <see cref="ViewDataDictionary{TModel}"/> for a new top-level scope.
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
// References may not show up due to ITypeActivator use in RazorPageActivator.
|
||||
public ViewDataDictionary(
|
||||
[NotNull] IModelMetadataProvider metadataProvider,
|
||||
[NotNull] ModelStateDictionary modelState)
|
||||
|
|
@ -22,7 +22,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
}
|
||||
|
||||
// References may not show up due to ITypeActivator use in RazorPageActivator.
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ViewDataDictionary{TModel}"/> class based in part on an
|
||||
/// existing <see cref="ViewDataDictionary"/> instance.
|
||||
|
|
@ -40,14 +39,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
// References may not show up due to ITypeActivator use in RazorPageActivator.
|
||||
public ViewDataDictionary([NotNull] ViewDataDictionary source)
|
||||
: base(source, declaredModelType: typeof(TModel))
|
||||
{
|
||||
}
|
||||
|
||||
// Model parameter type is object to allow "model: null" calls even when TModel is a value type. A TModel
|
||||
// parameter would likely require IEquatable<TModel> type restrictions to pass expected null value to the base
|
||||
// constructor.
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ViewDataDictionary{TModel}"/> class based in part on an
|
||||
/// existing <see cref="ViewDataDictionary"/> instance. This constructor is careful to avoid exceptions
|
||||
|
|
@ -64,6 +61,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
// Model parameter type is object to allow "model: null" calls even when TModel is a value type. A TModel
|
||||
// parameter would likely require IEquatable<TModel> type restrictions to pass expected null value to the base
|
||||
// constructor.
|
||||
public ViewDataDictionary([NotNull] ViewDataDictionary source, object model)
|
||||
: base(source, model, declaredModelType: typeof(TModel))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
|
||||
public class BindAttribute : Attribute, IModelNameProvider, IPropertyBindingPredicateProvider
|
||||
{
|
||||
private static readonly Func<ModelBindingContext, string, bool> _defaultFilter = (context, propertyName) => true;
|
||||
private static readonly Func<ModelBindingContext, string, bool> _defaultFilter =
|
||||
(context, propertyName) => true;
|
||||
|
||||
private Func<ModelBindingContext, string, bool> _predicateFromInclude;
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var rawValueArray = RawValueToObjectArray(rawValue);
|
||||
foreach (var rawValueElement in rawValueArray)
|
||||
{
|
||||
var innerModelMetadata =
|
||||
var innerModelMetadata =
|
||||
bindingContext.OperationBindingContext.MetadataProvider.GetMetadataForType(null, typeof(TElement));
|
||||
var innerBindingContext = new ModelBindingContext(bindingContext,
|
||||
bindingContext.ModelName,
|
||||
|
|
@ -101,7 +101,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
foreach (var indexName in indexNames)
|
||||
{
|
||||
var fullChildName = ModelBindingHelper.CreateIndexModelName(bindingContext.ModelName, indexName);
|
||||
var childModelMetadata =
|
||||
var childModelMetadata =
|
||||
bindingContext.OperationBindingContext.MetadataProvider.GetMetadataForType(null, typeof(TElement));
|
||||
var childBindingContext = new ModelBindingContext(bindingContext, fullChildName, childModelMetadata);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var propertyModelName = ModelBindingHelper.CreatePropertyModelName(bindingContext.ModelName,
|
||||
propertyMetadata.PropertyName);
|
||||
|
||||
var propertyBindingContext = new ModelBindingContext(bindingContext,
|
||||
var propertyBindingContext = new ModelBindingContext(bindingContext,
|
||||
propertyModelName,
|
||||
propertyMetadata);
|
||||
|
||||
|
|
|
|||
|
|
@ -80,16 +80,17 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
bindingContext.ModelName);
|
||||
}
|
||||
|
||||
var validationContext = new ModelValidationContext(bindingContext.OperationBindingContext.MetadataProvider,
|
||||
bindingContext.OperationBindingContext.ValidatorProvider,
|
||||
bindingContext.ModelState,
|
||||
bindingContext.ModelMetadata,
|
||||
containerMetadata: null);
|
||||
var validationContext = new ModelValidationContext(
|
||||
bindingContext.OperationBindingContext.MetadataProvider,
|
||||
bindingContext.OperationBindingContext.ValidatorProvider,
|
||||
bindingContext.ModelState,
|
||||
bindingContext.ModelMetadata,
|
||||
containerMetadata: null);
|
||||
|
||||
newBindingContext.ValidationNode.Validate(validationContext, parentNode: null);
|
||||
}
|
||||
|
||||
bindingContext.OperationBindingContext.BodyBindingState =
|
||||
bindingContext.OperationBindingContext.BodyBindingState =
|
||||
newBindingContext.OperationBindingContext.BodyBindingState;
|
||||
bindingContext.Model = newBindingContext.Model;
|
||||
return true;
|
||||
|
|
@ -147,13 +148,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var metadata = oldBindingContext.ModelMetadata.BinderMetadata as IValueProviderMetadata;
|
||||
if (metadata != null)
|
||||
{
|
||||
// ValueProvider property might contain a filtered list of value providers.
|
||||
// ValueProvider property might contain a filtered list of value providers.
|
||||
// While deciding to bind a particular property which is annotated with a IValueProviderMetadata,
|
||||
// instead of refiltering an already filtered list, we need to filter value providers from a global list
|
||||
// of all value providers. This is so that every artifact that is explicitly marked using an
|
||||
// IValueProviderMetadata can restrict model binding to only use value providers which support this
|
||||
// instead of refiltering an already filtered list, we need to filter value providers from a global
|
||||
// list of all value providers. This is so that every artifact that is explicitly marked using an
|
||||
// IValueProviderMetadata can restrict model binding to only use value providers which support this
|
||||
// IValueProviderMetadata.
|
||||
var valueProvider = oldBindingContext.OperationBindingContext.ValueProvider as IMetadataAwareValueProvider;
|
||||
var valueProvider =
|
||||
oldBindingContext.OperationBindingContext.ValueProvider as IMetadataAwareValueProvider;
|
||||
if (valueProvider != null)
|
||||
{
|
||||
newBindingContext.ValueProvider = valueProvider.Filter(metadata);
|
||||
|
|
@ -171,7 +173,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var currentModelNeedsToReadBody = newIsFormatterBasedMetadataFound || newIsFormBasedMetadataFound;
|
||||
var oldState = oldBindingContext.OperationBindingContext.BodyBindingState;
|
||||
|
||||
// We need to throw if there are multiple models which can cause body to be read multiple times.
|
||||
// We need to throw if there are multiple models which can cause body to be read multiple times.
|
||||
// Reading form data multiple times is ok since we cache form data. For the models marked to read using
|
||||
// formatters, multiple reads are not allowed.
|
||||
if (oldState == BodyBindingState.FormatterBased && currentModelNeedsToReadBody ||
|
||||
|
|
@ -179,7 +181,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
throw new InvalidOperationException(Resources.MultipleBodyParametersOrPropertiesAreNotAllowed);
|
||||
}
|
||||
|
||||
|
||||
var state = oldBindingContext.OperationBindingContext.BodyBindingState;
|
||||
if (newIsFormatterBasedMetadataFound)
|
||||
{
|
||||
|
|
@ -187,7 +189,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
}
|
||||
else if (newIsFormBasedMetadataFound && oldState != BodyBindingState.FormatterBased)
|
||||
{
|
||||
// Only update the model binding state if we have not discovered formatter based state already.
|
||||
// Only update the model binding state if we have not discovered formatter based state already.
|
||||
state = BodyBindingState.FormBased;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var binder = (IModelBinder)_activator.CreateInstance(_serviceProvider, binderType);
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
||||
// Was able to resolve a binder type, hence we should tell the model binding system to return
|
||||
// Was able to resolve a binder type, hence we should tell the model binding system to return
|
||||
// true so that none of the other model binders participate.
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// 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.
|
||||
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
internal async Task<BindResult<TModel>> TryBindStrongModel<TModel>(ModelBindingContext parentBindingContext,
|
||||
string propertyName)
|
||||
{
|
||||
var propertyModelMetadata =
|
||||
var propertyModelMetadata =
|
||||
parentBindingContext.OperationBindingContext.MetadataProvider.GetMetadataForType(modelAccessor: null,
|
||||
modelType: typeof(TModel));
|
||||
var propertyModelName =
|
||||
var propertyModelName =
|
||||
ModelBindingHelper.CreatePropertyModelName(parentBindingContext.ModelName, propertyName);
|
||||
var propertyBindingContext =
|
||||
var propertyBindingContext =
|
||||
new ModelBindingContext(parentBindingContext, propertyModelName, propertyModelMetadata);
|
||||
|
||||
if (await propertyBindingContext.OperationBindingContext.ModelBinder.BindModelAsync(propertyBindingContext))
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var complexModelDtoMetadata =
|
||||
bindingContext.OperationBindingContext.MetadataProvider.GetMetadataForType(() => originalDto,
|
||||
typeof(ComplexModelDto));
|
||||
var dtoBindingContext =
|
||||
var dtoBindingContext =
|
||||
new ModelBindingContext(bindingContext, bindingContext.ModelName, complexModelDtoMetadata);
|
||||
|
||||
await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(dtoBindingContext);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
IEnumerable<ModelMetadata> GetMetadataForProperties(object container, [NotNull] Type containerType);
|
||||
|
||||
ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, [NotNull] Type containerType, [NotNull] string propertyName);
|
||||
ModelMetadata GetMetadataForProperty(
|
||||
Func<object> modelAccessor,
|
||||
[NotNull] Type containerType,
|
||||
[NotNull] string propertyName);
|
||||
|
||||
ModelMetadata GetMetadataForType(Func<object> modelAccessor, [NotNull] Type modelType);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
|
|
@ -13,7 +12,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
/// </summary>
|
||||
public class ModelBindingContext
|
||||
{
|
||||
private static readonly Func<ModelBindingContext, string, bool>
|
||||
private static readonly Func<ModelBindingContext, string, bool>
|
||||
_defaultPropertyFilter = (context, propertyName) => true;
|
||||
|
||||
private string _modelName;
|
||||
|
|
@ -53,7 +52,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the <see cref="OperationBindingContext"/> associated with this context.
|
||||
/// Represents the <see cref="OperationBindingContext"/> associated with this context.
|
||||
/// </summary>
|
||||
public OperationBindingContext OperationBindingContext { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// 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.
|
||||
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class ClientModelValidationContext
|
||||
|
|
|
|||
|
|
@ -22,13 +22,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
// A factory for validators based on ValidationAttribute.
|
||||
internal delegate IModelValidator DataAnnotationsModelValidationFactory(ValidationAttribute attribute);
|
||||
|
||||
// A factory for validators based on IValidatableObject
|
||||
private delegate IModelValidator DataAnnotationsValidatableObjectAdapterFactory();
|
||||
|
||||
private static bool _addImplicitRequiredAttributeForValueTypes = true;
|
||||
private readonly Dictionary<Type, DataAnnotationsModelValidationFactory> _attributeFactories =
|
||||
BuildAttributeFactoriesDictionary();
|
||||
|
||||
// Factories for validation attributes
|
||||
private static readonly DataAnnotationsModelValidationFactory _defaultAttributeFactory =
|
||||
(attribute) => new DataAnnotationsModelValidator(attribute);
|
||||
|
|
@ -37,6 +30,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
private static readonly DataAnnotationsValidatableObjectAdapterFactory _defaultValidatableFactory =
|
||||
() => new ValidatableObjectAdapter();
|
||||
|
||||
private static bool _addImplicitRequiredAttributeForValueTypes = true;
|
||||
private readonly Dictionary<Type, DataAnnotationsModelValidationFactory> _attributeFactories =
|
||||
BuildAttributeFactoriesDictionary();
|
||||
|
||||
// A factory for validators based on IValidatableObject
|
||||
private delegate IModelValidator DataAnnotationsValidatableObjectAdapterFactory();
|
||||
|
||||
internal Dictionary<Type, DataAnnotationsModelValidationFactory> AttributeFactories
|
||||
{
|
||||
get { return _attributeFactories; }
|
||||
|
|
|
|||
|
|
@ -56,7 +56,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
|
||||
// We don't need to recursively traverse the graph for types that shouldn't be validated
|
||||
var modelType = metadata.Model.GetType();
|
||||
if (IsTypeExcludedFromValidation(validationContext.ModelValidationContext.ExcludeFromValidationFilters, modelType))
|
||||
if (IsTypeExcludedFromValidation(
|
||||
validationContext.ModelValidationContext.ExcludeFromValidationFilters,
|
||||
modelType))
|
||||
{
|
||||
return ShallowValidate(metadata, validationContext, validators);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// 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.
|
||||
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class ModelClientValidationRegexRule : ModelClientValidationRule
|
||||
|
|
|
|||
|
|
@ -104,7 +104,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
if (SuppressValidation || !validationContext.ModelState.CanAddErrors)
|
||||
{
|
||||
// Short circuit if validation does not need to be applied or if we've reached the max number of validation errors.
|
||||
// Short circuit if validation does not need to be applied or if we've reached the max number of
|
||||
// validation errors.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
/// <summary>
|
||||
/// Represents a <see cref="IValueProvider"/> whose values come from a collection of <see cref="IValueProvider"/>s.
|
||||
/// </summary>
|
||||
public class CompositeValueProvider : Collection<IValueProvider>, IEnumerableValueProvider, IMetadataAwareValueProvider
|
||||
public class CompositeValueProvider
|
||||
: Collection<IValueProvider>, IEnumerableValueProvider, IMetadataAwareValueProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="CompositeValueProvider"/>.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
/// A <see cref="IMetadataAwareValueProvider"/> value provider which can filter
|
||||
/// based on <see cref="IValueProviderMetadata"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TBinderMetadata">Represents a type implementing <see cref="IValueProviderMetadata"/></typeparam>
|
||||
/// <typeparam name="TBinderMetadata">
|
||||
/// Represents a type implementing <see cref="IValueProviderMetadata"/>
|
||||
/// </typeparam>
|
||||
public abstract class MetadataAwareValueProvider<TBinderMetadata> : IMetadataAwareValueProvider
|
||||
where TBinderMetadata : IValueProviderMetadata
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
where TBinderMetadata : IValueProviderMetadata
|
||||
{
|
||||
private readonly CultureInfo _culture;
|
||||
private PrefixContainer _prefixContainer;
|
||||
private readonly Func<Task<IReadableStringCollection>> _valuesFactory;
|
||||
private PrefixContainer _prefixContainer;
|
||||
private IReadableStringCollection _values;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -15,8 +15,12 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// Parses the <see cref="ICompilerOptions"/> for the current executing application and returns a
|
||||
/// <see cref="CompilationSettings"/> used for Roslyn compilation.
|
||||
/// </summary>
|
||||
/// <param name="compilerOptionsProvider">A <see cref="ICompilerOptionsProvider"/> that reads compiler options.</param>
|
||||
/// <param name="applicationEnvironment">The <see cref="IApplicationEnvironment"/> for the executing application.</param>
|
||||
/// <param name="compilerOptionsProvider">
|
||||
/// A <see cref="ICompilerOptionsProvider"/> that reads compiler options.
|
||||
/// </param>
|
||||
/// <param name="applicationEnvironment">
|
||||
/// The <see cref="IApplicationEnvironment"/> for the executing application.
|
||||
/// </param>
|
||||
/// <returns>The <see cref="CompilationSettings"/> for the current application.</returns>
|
||||
public static CompilationSettings GetCompilationSettings(
|
||||
[NotNull] this ICompilerOptionsProvider compilerOptionsProvider,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// file system.
|
||||
/// </param>
|
||||
public CompilerCache(IAssemblyProvider provider, IRazorFileSystemCache fileSystem)
|
||||
: this (GetFileInfos(provider.CandidateAssemblies), fileSystem)
|
||||
: this(GetFileInfos(provider.CandidateAssemblies), fileSystem)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,13 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// <summary>
|
||||
/// Gets a flag that indicates if the file is precompiled.
|
||||
/// </summary>
|
||||
public bool IsPreCompiled { get { return Hash != null; } }
|
||||
public bool IsPreCompiled
|
||||
{
|
||||
get
|
||||
{
|
||||
return Hash != null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="CompilerCacheEntry"/> for the nearest ViewStart that the compiled type
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Microsoft.AspNet.FileSystems;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Microsoft.Framework.Expiration.Interfaces;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
{
|
||||
|
|
|
|||
|
|
@ -119,8 +119,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
}
|
||||
|
||||
var type = assembly.GetExportedTypes()
|
||||
.First(t => t.Name.
|
||||
StartsWith(_classPrefix, StringComparison.Ordinal));
|
||||
.First(t => t.Name.StartsWith(_classPrefix, StringComparison.Ordinal));
|
||||
|
||||
return UncachedCompilationResult.Successful(type, compilationContent);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
// 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 Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
|
||||
namespace Microsoft.Framework.Runtime
|
||||
{
|
||||
[AssemblyNeutral]
|
||||
public interface IBeforeCompileContext
|
||||
{
|
||||
CSharpCompilation CSharpCompilation { get; set; }
|
||||
|
||||
IList<ResourceDescription> Resources { get; }
|
||||
|
||||
IList<Diagnostic> Diagnostics { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -24,9 +24,9 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
public interface IViewLocationExpander
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked by a <see cref="RazorViewEngine"/> to determine the values that would be consumed by this instance of
|
||||
/// <see cref="IViewLocationExpander"/>. The calculated values are used to determine if the view location has
|
||||
/// changed since the last time it was located.
|
||||
/// Invoked by a <see cref="RazorViewEngine"/> to determine the values that would be consumed by this instance
|
||||
/// of <see cref="IViewLocationExpander"/>. The calculated values are used to determine if the view location
|
||||
/// has changed since the last time it was located.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="ViewLocationExpanderContext"/> for the current view location
|
||||
/// expansion operation.</param>
|
||||
|
|
|
|||
|
|
@ -11,12 +11,13 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
public static Diagnostic ToDiagnostics([NotNull] this RazorError error, [NotNull] string filePath)
|
||||
{
|
||||
var descriptor = new DiagnosticDescriptor(id: "Razor",
|
||||
title: "Razor parsing error",
|
||||
messageFormat: error.Message.Replace("{", "{{").Replace("}", "}}"),
|
||||
category: "Razor.Parser",
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true);
|
||||
var descriptor = new DiagnosticDescriptor(
|
||||
id: "Razor",
|
||||
title: "Razor parsing error",
|
||||
messageFormat: error.Message.Replace("{", "{{").Replace("}", "}}"),
|
||||
category: "Razor.Parser",
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true);
|
||||
|
||||
var textSpan = new TextSpan(error.Location.AbsoluteIndex, error.Length);
|
||||
var linePositionStart = new LinePosition(error.Location.LineIndex, error.Location.CharacterIndex);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
return syntaxTree;
|
||||
}
|
||||
|
||||
|
||||
protected virtual string GenerateFile([NotNull] RazorFileInfo fileInfo)
|
||||
{
|
||||
return string.Format(FileFormat,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNet.FileSystems;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
|
@ -79,7 +78,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
private IEnumerable<RelativeFileInfo> GetFileInfosRecursive(string currentPath)
|
||||
{
|
||||
string path = currentPath;
|
||||
var path = currentPath;
|
||||
|
||||
var fileInfos = _fileSystem.GetDirectoryContents(path);
|
||||
if (!fileInfos.Exists)
|
||||
|
|
@ -152,16 +151,3 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Microsoft.Framework.Runtime
|
||||
{
|
||||
[AssemblyNeutral]
|
||||
public interface IBeforeCompileContext
|
||||
{
|
||||
CSharpCompilation CSharpCompilation { get; set; }
|
||||
|
||||
IList<ResourceDescription> Resources { get; }
|
||||
|
||||
IList<Diagnostic> Diagnostics { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,12 +122,14 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
if (_tagHelperActivator == null)
|
||||
{
|
||||
_tagHelperActivator = ViewContext.HttpContext.RequestServices.GetRequiredService<ITagHelperActivator>();
|
||||
_tagHelperActivator =
|
||||
ViewContext.HttpContext.RequestServices.GetRequiredService<ITagHelperActivator>();
|
||||
}
|
||||
|
||||
return _tagHelperActivator;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and activates a <see cref="ITagHelper"/>.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
IRazorPageActivator pageActivator,
|
||||
IViewStartProvider viewStartProvider,
|
||||
IRazorPage razorPage,
|
||||
bool isPartial
|
||||
)
|
||||
bool isPartial)
|
||||
{
|
||||
_viewEngine = viewEngine;
|
||||
_pageActivator = pageActivator;
|
||||
|
|
@ -53,7 +52,6 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// </summary>
|
||||
public bool IsPartial { get; }
|
||||
|
||||
|
||||
private bool EnableInstrumentation
|
||||
{
|
||||
get { return _pageExecutionFeature != null; }
|
||||
|
|
@ -97,8 +95,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
bool executeViewStart)
|
||||
{
|
||||
var razorTextWriter = new RazorTextWriter(context.Writer, context.Writer.Encoding);
|
||||
TextWriter writer = razorTextWriter;
|
||||
IBufferedTextWriter bufferedWriter = razorTextWriter;
|
||||
var writer = (TextWriter)razorTextWriter;
|
||||
var bufferedWriter = (IBufferedTextWriter)razorTextWriter;
|
||||
|
||||
if (EnableInstrumentation)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
/// </exception>
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
bool antiForgeryDefault = true;
|
||||
var antiForgeryDefault = true;
|
||||
var routePrefixedAttributes = output.FindPrefixedAttributes(RouteAttributePrefix);
|
||||
|
||||
// If "action" is already set, it means the user is attempting to use a normal <form>.
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
[Activate]
|
||||
protected internal IHtmlGenerator Generator { get; set; }
|
||||
|
||||
// TODO: https://github.com/aspnet/Razor/issues/196 Change to ValidationSummary enum once #196 has been completed.
|
||||
/// <summary>
|
||||
/// If <c>All</c> or <c>ModelOnly</c>, appends a validation summary. Acceptable values are defined by the
|
||||
/// <see cref="ValidationSummary"/> enum.
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ namespace System.Web.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets model state after the model binding process. This ModelState will be empty before model binding happens.
|
||||
/// Gets model state after the model binding process. This ModelState will be empty before model binding
|
||||
/// happens.
|
||||
/// </summary>
|
||||
public ModelStateDictionary ModelState
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,14 +15,15 @@ namespace System.Collections.Generic
|
|||
internal static class CollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Return a new array with the value added to the end. Slow and best suited to long lived arrays with few writes relative to reads.
|
||||
/// Return a new array with the value added to the end. Slow and best suited to long lived arrays with few
|
||||
/// writes relative to reads.
|
||||
/// </summary>
|
||||
public static T[] AppendAndReallocate<T>(this T[] array, T value)
|
||||
{
|
||||
Debug.Assert(array != null);
|
||||
|
||||
int originalLength = array.Length;
|
||||
T[] newArray = new T[originalLength + 1];
|
||||
var originalLength = array.Length;
|
||||
var newArray = new T[originalLength + 1];
|
||||
array.CopyTo(newArray, 0);
|
||||
newArray[originalLength] = value;
|
||||
return newArray;
|
||||
|
|
@ -36,7 +37,7 @@ namespace System.Collections.Generic
|
|||
{
|
||||
Debug.Assert(values != null);
|
||||
|
||||
T[] array = values as T[];
|
||||
var array = values as T[];
|
||||
if (array == null)
|
||||
{
|
||||
array = values.ToArray();
|
||||
|
|
@ -52,13 +53,13 @@ namespace System.Collections.Generic
|
|||
{
|
||||
Debug.Assert(enumerable != null);
|
||||
|
||||
Collection<T> collection = enumerable as Collection<T>;
|
||||
var collection = enumerable as Collection<T>;
|
||||
if (collection != null)
|
||||
{
|
||||
return collection;
|
||||
}
|
||||
// Check for IList so that collection can wrap it instead of copying
|
||||
IList<T> list = enumerable as IList<T>;
|
||||
var list = enumerable as IList<T>;
|
||||
if (list == null)
|
||||
{
|
||||
list = new List<T>(enumerable);
|
||||
|
|
@ -73,7 +74,7 @@ namespace System.Collections.Generic
|
|||
{
|
||||
Debug.Assert(enumerable != null);
|
||||
|
||||
IList<T> list = enumerable as IList<T>;
|
||||
var list = enumerable as IList<T>;
|
||||
if (list != null)
|
||||
{
|
||||
return list;
|
||||
|
|
@ -82,8 +83,8 @@ namespace System.Collections.Generic
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the enumerable as a List of T, copying if required. Optimized for common case where it is an List of T
|
||||
/// or a ListWrapperCollection of T. Avoid mutating the return value.
|
||||
/// Return the enumerable as a List of T, copying if required. Optimized for common case where it is an List of
|
||||
/// T or a ListWrapperCollection of T. Avoid mutating the return value.
|
||||
/// </summary>
|
||||
public static List<T> AsList<T>(this IEnumerable<T> enumerable)
|
||||
{
|
||||
|
|
@ -127,7 +128,7 @@ namespace System.Collections.Generic
|
|||
return default(T);
|
||||
|
||||
case 1:
|
||||
T value = list[0];
|
||||
var value = list[0];
|
||||
return value;
|
||||
|
||||
default:
|
||||
|
|
@ -137,18 +138,21 @@ namespace System.Collections.Generic
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a single value in list matching type TMatch if there is only one, null if there are none of type TMatch or calls the
|
||||
/// errorAction with errorArg1 if there is more than one.
|
||||
/// Returns a single value in list matching type TMatch if there is only one, null if there are none of type
|
||||
/// TMatch or calls the errorAction with errorArg1 if there is more than one.
|
||||
/// </summary>
|
||||
public static TMatch SingleOfTypeDefaultOrError<TInput, TMatch, TArg1>(this IList<TInput> list, Action<TArg1> errorAction, TArg1 errorArg1) where TMatch : class
|
||||
public static TMatch SingleOfTypeDefaultOrError<TInput, TMatch, TArg1>(
|
||||
this IList<TInput> list,
|
||||
Action<TArg1> errorAction,
|
||||
TArg1 errorArg1) where TMatch : class
|
||||
{
|
||||
Debug.Assert(list != null);
|
||||
Debug.Assert(errorAction != null);
|
||||
|
||||
TMatch result = null;
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
TMatch typedValue = list[i] as TMatch;
|
||||
var typedValue = list[i] as TMatch;
|
||||
if (typedValue != null)
|
||||
{
|
||||
if (result == null)
|
||||
|
|
@ -166,15 +170,16 @@ namespace System.Collections.Generic
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an ICollection to an array, removing null values. Fast path for case where there are no null values.
|
||||
/// Convert an ICollection to an array, removing null values. Fast path for case where there are no null
|
||||
/// values.
|
||||
/// </summary>
|
||||
public static T[] ToArrayWithoutNulls<T>(this ICollection<T> collection) where T : class
|
||||
{
|
||||
Debug.Assert(collection != null);
|
||||
|
||||
T[] result = new T[collection.Count];
|
||||
int count = 0;
|
||||
foreach (T value in collection)
|
||||
var result = new T[collection.Count];
|
||||
var count = 0;
|
||||
foreach (var value in collection)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
|
|
@ -188,38 +193,46 @@ namespace System.Collections.Generic
|
|||
}
|
||||
else
|
||||
{
|
||||
T[] trimmedResult = new T[count];
|
||||
var trimmedResult = new T[count];
|
||||
Array.Copy(result, trimmedResult, count);
|
||||
return trimmedResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert the array to a Dictionary using the keySelector to extract keys from values and the specified comparer. Optimized for array input.
|
||||
/// Convert the array to a Dictionary using the keySelector to extract keys from values and the specified
|
||||
/// comparer. Optimized for array input.
|
||||
/// </summary>
|
||||
public static Dictionary<TKey, TValue> ToDictionaryFast<TKey, TValue>(this TValue[] array, Func<TValue, TKey> keySelector, IEqualityComparer<TKey> comparer)
|
||||
public static Dictionary<TKey, TValue> ToDictionaryFast<TKey, TValue>(
|
||||
this TValue[] array,
|
||||
Func<TValue, TKey> keySelector,
|
||||
IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
Debug.Assert(array != null);
|
||||
Debug.Assert(keySelector != null);
|
||||
|
||||
Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>(array.Length, comparer);
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
var dictionary = new Dictionary<TKey, TValue>(array.Length, comparer);
|
||||
for (var i = 0; i < array.Length; i++)
|
||||
{
|
||||
TValue value = array[i];
|
||||
var value = array[i];
|
||||
dictionary.Add(keySelector(value), value);
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert the list to a Dictionary using the keySelector to extract keys from values and the specified comparer. Optimized for IList of T input with fast path for array.
|
||||
/// Convert the list to a Dictionary using the keySelector to extract keys from values and the specified
|
||||
/// comparer. Optimized for IList of T input with fast path for array.
|
||||
/// </summary>
|
||||
public static Dictionary<TKey, TValue> ToDictionaryFast<TKey, TValue>(this IList<TValue> list, Func<TValue, TKey> keySelector, IEqualityComparer<TKey> comparer)
|
||||
public static Dictionary<TKey, TValue> ToDictionaryFast<TKey, TValue>(
|
||||
this IList<TValue> list,
|
||||
Func<TValue, TKey> keySelector,
|
||||
IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
Debug.Assert(list != null);
|
||||
Debug.Assert(keySelector != null);
|
||||
|
||||
TValue[] array = list as TValue[];
|
||||
var array = list as TValue[];
|
||||
if (array != null)
|
||||
{
|
||||
return ToDictionaryFast(array, keySelector, comparer);
|
||||
|
|
@ -228,25 +241,29 @@ namespace System.Collections.Generic
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert the enumerable to a Dictionary using the keySelector to extract keys from values and the specified comparer. Fast paths for array and IList of T.
|
||||
/// Convert the enumerable to a Dictionary using the keySelector to extract keys from values and the specified
|
||||
/// comparer. Fast paths for array and IList of T.
|
||||
/// </summary>
|
||||
public static Dictionary<TKey, TValue> ToDictionaryFast<TKey, TValue>(this IEnumerable<TValue> enumerable, Func<TValue, TKey> keySelector, IEqualityComparer<TKey> comparer)
|
||||
public static Dictionary<TKey, TValue> ToDictionaryFast<TKey, TValue>(
|
||||
this IEnumerable<TValue> enumerable,
|
||||
Func<TValue, TKey> keySelector,
|
||||
IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
Debug.Assert(enumerable != null);
|
||||
Debug.Assert(keySelector != null);
|
||||
|
||||
TValue[] array = enumerable as TValue[];
|
||||
var array = enumerable as TValue[];
|
||||
if (array != null)
|
||||
{
|
||||
return ToDictionaryFast(array, keySelector, comparer);
|
||||
}
|
||||
IList<TValue> list = enumerable as IList<TValue>;
|
||||
var list = enumerable as IList<TValue>;
|
||||
if (list != null)
|
||||
{
|
||||
return ToDictionaryFastNoCheck(list, keySelector, comparer);
|
||||
}
|
||||
Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>(comparer);
|
||||
foreach (TValue value in enumerable)
|
||||
var dictionary = new Dictionary<TKey, TValue>(comparer);
|
||||
foreach (var value in enumerable)
|
||||
{
|
||||
dictionary.Add(keySelector(value), value);
|
||||
}
|
||||
|
|
@ -254,18 +271,22 @@ namespace System.Collections.Generic
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert the list to a Dictionary using the keySelector to extract keys from values and the specified comparer. Optimized for IList of T input. No checking for other types.
|
||||
/// Convert the list to a Dictionary using the keySelector to extract keys from values and the specified
|
||||
/// comparer. Optimized for IList of T input. No checking for other types.
|
||||
/// </summary>
|
||||
private static Dictionary<TKey, TValue> ToDictionaryFastNoCheck<TKey, TValue>(IList<TValue> list, Func<TValue, TKey> keySelector, IEqualityComparer<TKey> comparer)
|
||||
private static Dictionary<TKey, TValue> ToDictionaryFastNoCheck<TKey, TValue>(
|
||||
IList<TValue> list,
|
||||
Func<TValue, TKey> keySelector,
|
||||
IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
Debug.Assert(list != null);
|
||||
Debug.Assert(keySelector != null);
|
||||
|
||||
int listCount = list.Count;
|
||||
Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>(listCount, comparer);
|
||||
for (int i = 0; i < listCount; i++)
|
||||
var listCount = list.Count;
|
||||
var dictionary = new Dictionary<TKey, TValue>(listCount, comparer);
|
||||
for (var i = 0; i < listCount; i++)
|
||||
{
|
||||
TValue value = list[i];
|
||||
var value = list[i];
|
||||
dictionary.Add(keySelector(value), value);
|
||||
}
|
||||
return dictionary;
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ using System.Diagnostics;
|
|||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Web.Http;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using System.Net.Http.Formatting;
|
||||
|
||||
namespace System.Net.Http.Formatting
|
||||
{
|
||||
|
|
@ -48,35 +46,39 @@ namespace System.Net.Http.Formatting
|
|||
public bool ExcludeMatchOnTypeOnly { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Performs content negotiating by selecting the most appropriate <see cref="MediaTypeFormatter"/> out of the passed in
|
||||
/// <paramref name="formatters"/> for the given <paramref name="request"/> that can serialize an object of the given
|
||||
/// <paramref name="type"/>.
|
||||
/// Performs content negotiating by selecting the most appropriate <see cref="MediaTypeFormatter"/> out of the
|
||||
/// passed in <paramref name="formatters"/> for the given <paramref name="request"/> that can serialize an
|
||||
/// object of the given <paramref name="type"/>.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to be serialized.</param>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <param name="formatters">The set of <see cref="MediaTypeFormatter"/> objects from which to choose.</param>
|
||||
/// <returns>The result of the negotiation containing the most appropriate <see cref="MediaTypeFormatter"/> instance,
|
||||
/// or <c>null</c> if there is no appropriate formatter.</returns>
|
||||
public virtual ContentNegotiationResult Negotiate([NotNull] Type type, [NotNull] HttpRequestMessage request, [NotNull] IEnumerable<MediaTypeFormatter> formatters)
|
||||
/// <returns>The result of the negotiation containing the most appropriate <see cref="MediaTypeFormatter"/>
|
||||
/// instance, or <c>null</c> if there is no appropriate formatter.</returns>
|
||||
public virtual ContentNegotiationResult Negotiate(
|
||||
[NotNull] Type type,
|
||||
[NotNull] HttpRequestMessage request,
|
||||
[NotNull] IEnumerable<MediaTypeFormatter> formatters)
|
||||
{
|
||||
// Go through each formatter to compute how well it matches.
|
||||
Collection<MediaTypeFormatterMatch> matches = ComputeFormatterMatches(type, request, formatters);
|
||||
var matches = ComputeFormatterMatches(type, request, formatters);
|
||||
|
||||
// Select best formatter match among the matches
|
||||
MediaTypeFormatterMatch bestFormatterMatch = SelectResponseMediaTypeFormatter(matches);
|
||||
var bestFormatterMatch = SelectResponseMediaTypeFormatter(matches);
|
||||
|
||||
// We found a best formatter
|
||||
if (bestFormatterMatch != null)
|
||||
{
|
||||
// Find the best character encoding for the selected formatter
|
||||
Encoding bestEncodingMatch = SelectResponseCharacterEncoding(request, bestFormatterMatch.Formatter);
|
||||
var bestEncodingMatch = SelectResponseCharacterEncoding(request, bestFormatterMatch.Formatter);
|
||||
if (bestEncodingMatch != null)
|
||||
{
|
||||
bestFormatterMatch.MediaType.CharSet = bestEncodingMatch.WebName;
|
||||
}
|
||||
|
||||
MediaTypeHeaderValue bestMediaType = bestFormatterMatch.MediaType;
|
||||
MediaTypeFormatter bestFormatter = bestFormatterMatch.Formatter.GetPerRequestFormatterInstance(type, request, bestMediaType);
|
||||
var bestMediaType = bestFormatterMatch.MediaType;
|
||||
var bestFormatter =
|
||||
bestFormatterMatch.Formatter.GetPerRequestFormatterInstance(type, request, bestMediaType);
|
||||
return new ContentNegotiationResult(bestFormatter, bestMediaType);
|
||||
}
|
||||
|
||||
|
|
@ -84,25 +86,28 @@ namespace System.Net.Http.Formatting
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine how well each formatter matches by associating a <see cref="MediaTypeFormatterMatchRanking"/> value
|
||||
/// with the formatter. Then associate the quality of the match based on q-factors and other parameters. The result of this
|
||||
/// method is a collection of the matches found categorized and assigned a quality value.
|
||||
/// Determine how well each formatter matches by associating a <see cref="MediaTypeFormatterMatchRanking"/>
|
||||
/// value with the formatter. Then associate the quality of the match based on q-factors and other parameters.
|
||||
/// The result of this method is a collection of the matches found categorized and assigned a quality value.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to be serialized.</param>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <param name="formatters">The set of <see cref="MediaTypeFormatter"/> objects from which to choose.</param>
|
||||
/// <returns>A collection containing all the matches.</returns>
|
||||
protected virtual Collection<MediaTypeFormatterMatch> ComputeFormatterMatches([NotNull] Type type, [NotNull] HttpRequestMessage request, [NotNull] IEnumerable<MediaTypeFormatter> formatters)
|
||||
protected virtual Collection<MediaTypeFormatterMatch> ComputeFormatterMatches(
|
||||
[NotNull] Type type,
|
||||
[NotNull] HttpRequestMessage request,
|
||||
[NotNull] IEnumerable<MediaTypeFormatter> formatters)
|
||||
{
|
||||
IEnumerable<MediaTypeWithQualityHeaderValue> sortedAcceptValues = null;
|
||||
|
||||
// Go through each formatter to find how well it matches.
|
||||
ListWrapperCollection<MediaTypeFormatterMatch> matches = new ListWrapperCollection<MediaTypeFormatterMatch>();
|
||||
MediaTypeFormatter[] writingFormatters = GetWritingFormatters(formatters);
|
||||
for (int i = 0; i < writingFormatters.Length; i++)
|
||||
var matches =
|
||||
new ListWrapperCollection<MediaTypeFormatterMatch>();
|
||||
var writingFormatters = GetWritingFormatters(formatters);
|
||||
for (var i = 0; i < writingFormatters.Length; i++)
|
||||
{
|
||||
MediaTypeFormatter formatter = writingFormatters[i];
|
||||
MediaTypeFormatterMatch match = null;
|
||||
var formatter = writingFormatters[i];
|
||||
|
||||
// Check first that formatter can write the actual type
|
||||
if (!formatter.CanWriteType(type))
|
||||
|
|
@ -117,7 +122,9 @@ namespace System.Net.Http.Formatting
|
|||
// Sort the Accept header values in descending order based on q-factor
|
||||
sortedAcceptValues = SortMediaTypeWithQualityHeaderValuesByQFactor(request.Headers.Accept);
|
||||
}
|
||||
if ((match = MatchAcceptHeader(sortedAcceptValues, formatter)) != null)
|
||||
|
||||
var match = MatchAcceptHeader(sortedAcceptValues, formatter);
|
||||
if (match != null)
|
||||
{
|
||||
matches.Add(match);
|
||||
continue;
|
||||
|
|
@ -132,7 +139,7 @@ namespace System.Net.Http.Formatting
|
|||
|
||||
// Check whether we should match on type or stop the matching process.
|
||||
// The latter is used to generate 406 (Not Acceptable) status codes.
|
||||
bool shouldMatchOnType = ShouldMatchOnType(sortedAcceptValues);
|
||||
var shouldMatchOnType = ShouldMatchOnType(sortedAcceptValues);
|
||||
|
||||
// Match against the type of object we are writing out
|
||||
if (shouldMatchOnType && (match = MatchType(type, formatter)) != null)
|
||||
|
|
@ -150,11 +157,12 @@ namespace System.Net.Http.Formatting
|
|||
/// </summary>
|
||||
/// <param name="matches">The collection of matches.</param>
|
||||
/// <returns>The <see cref="MediaTypeFormatterMatch"/> determined to be the best match.</returns>
|
||||
protected virtual MediaTypeFormatterMatch SelectResponseMediaTypeFormatter([NotNull] ICollection<MediaTypeFormatterMatch> matches)
|
||||
protected virtual MediaTypeFormatterMatch SelectResponseMediaTypeFormatter(
|
||||
[NotNull] ICollection<MediaTypeFormatterMatch> matches)
|
||||
{
|
||||
// Performance-sensitive
|
||||
|
||||
List<MediaTypeFormatterMatch> matchList = matches.AsList();
|
||||
var matchList = matches.AsList();
|
||||
|
||||
MediaTypeFormatterMatch bestMatchOnType = null;
|
||||
MediaTypeFormatterMatch bestMatchOnAcceptHeaderLiteral = null;
|
||||
|
|
@ -164,9 +172,9 @@ namespace System.Net.Http.Formatting
|
|||
MediaTypeFormatterMatch bestMatchOnRequestMediaType = null;
|
||||
|
||||
// Go through each formatter to find the best match in each category.
|
||||
for (int i = 0; i < matchList.Count; i++)
|
||||
for (var i = 0; i < matchList.Count; i++)
|
||||
{
|
||||
MediaTypeFormatterMatch match = matchList[i];
|
||||
var match = matchList[i];
|
||||
switch (match.Ranking)
|
||||
{
|
||||
case MediaTypeFormatterMatchRanking.MatchOnCanWriteType:
|
||||
|
|
@ -186,13 +194,15 @@ namespace System.Net.Http.Formatting
|
|||
case MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderSubtypeMediaRange:
|
||||
// Matches on accept headers must choose the highest quality match.
|
||||
// A match of 0.0 means we won't use it at all.
|
||||
bestMatchOnAcceptHeaderSubtypeMediaRange = UpdateBestMatch(bestMatchOnAcceptHeaderSubtypeMediaRange, match);
|
||||
bestMatchOnAcceptHeaderSubtypeMediaRange =
|
||||
UpdateBestMatch(bestMatchOnAcceptHeaderSubtypeMediaRange, match);
|
||||
break;
|
||||
|
||||
case MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderAllMediaRange:
|
||||
// Matches on accept headers must choose the highest quality match.
|
||||
// A match of 0.0 means we won't use it at all.
|
||||
bestMatchOnAcceptHeaderAllMediaRange = UpdateBestMatch(bestMatchOnAcceptHeaderAllMediaRange, match);
|
||||
bestMatchOnAcceptHeaderAllMediaRange =
|
||||
UpdateBestMatch(bestMatchOnAcceptHeaderAllMediaRange, match);
|
||||
break;
|
||||
|
||||
case MediaTypeFormatterMatchRanking.MatchOnRequestMediaType:
|
||||
|
|
@ -206,12 +216,13 @@ namespace System.Net.Http.Formatting
|
|||
}
|
||||
|
||||
// If we received matches based on both supported media types and from media type mappings,
|
||||
// we want to give precedence to the media type mappings, but only if their quality is >= that of the supported media type.
|
||||
// We do this because media type mappings are the user's extensibility point and must take precedence over normal
|
||||
// supported media types in the case of a tie. The 99% case is where both have quality 1.0.
|
||||
// we want to give precedence to the media type mappings, but only if their quality is >= that of the
|
||||
// supported media type. We do this because media type mappings are the user's extensibility point and must
|
||||
// take precedence over normal supported media types in the case of a tie. The 99% case is where both have
|
||||
// quality 1.0.
|
||||
if (bestMatchOnMediaTypeMapping != null)
|
||||
{
|
||||
MediaTypeFormatterMatch mappingOverride = bestMatchOnMediaTypeMapping;
|
||||
var mappingOverride = bestMatchOnMediaTypeMapping;
|
||||
mappingOverride = UpdateBestMatch(mappingOverride, bestMatchOnAcceptHeaderLiteral);
|
||||
mappingOverride = UpdateBestMatch(mappingOverride, bestMatchOnAcceptHeaderSubtypeMediaRange);
|
||||
mappingOverride = UpdateBestMatch(mappingOverride, bestMatchOnAcceptHeaderAllMediaRange);
|
||||
|
|
@ -256,21 +267,24 @@ namespace System.Net.Http.Formatting
|
|||
/// If no encoding is found then we use the default for the formatter.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="Encoding"/> determined to be the best match.</returns>
|
||||
protected virtual Encoding SelectResponseCharacterEncoding([NotNull] HttpRequestMessage request, [NotNull] MediaTypeFormatter formatter)
|
||||
protected virtual Encoding SelectResponseCharacterEncoding(
|
||||
[NotNull] HttpRequestMessage request,
|
||||
[NotNull] MediaTypeFormatter formatter)
|
||||
{
|
||||
// If there are any SupportedEncodings then we pick an encoding
|
||||
List<Encoding> supportedEncodings = formatter.SupportedEncodings.ToList();
|
||||
var supportedEncodings = formatter.SupportedEncodings.ToList();
|
||||
if (supportedEncodings.Count > 0)
|
||||
{
|
||||
// Sort Accept-Charset header values
|
||||
IEnumerable<StringWithQualityHeaderValue> sortedAcceptCharsetValues = SortStringWithQualityHeaderValuesByQFactor(request.Headers.AcceptCharset);
|
||||
var sortedAcceptCharsetValues =
|
||||
SortStringWithQualityHeaderValuesByQFactor(request.Headers.AcceptCharset);
|
||||
|
||||
// Check for match based on accept-charset headers
|
||||
foreach (StringWithQualityHeaderValue acceptCharset in sortedAcceptCharsetValues)
|
||||
{
|
||||
for (int i = 0; i < supportedEncodings.Count; i++)
|
||||
for (var i = 0; i < supportedEncodings.Count; i++)
|
||||
{
|
||||
Encoding encoding = supportedEncodings[i];
|
||||
var encoding = supportedEncodings[i];
|
||||
if (encoding != null && acceptCharset.Quality != FormattingUtilities.NoMatch &&
|
||||
(acceptCharset.Value.Equals(encoding.WebName, StringComparison.OrdinalIgnoreCase) ||
|
||||
acceptCharset.Value.Equals("*", StringComparison.Ordinal)))
|
||||
|
|
@ -292,17 +306,22 @@ namespace System.Net.Http.Formatting
|
|||
/// </summary>
|
||||
/// <param name="sortedAcceptValues">The sorted accept header values to match.</param>
|
||||
/// <param name="formatter">The formatter to match against.</param>
|
||||
/// <returns>A <see cref="MediaTypeFormatterMatch"/> indicating the quality of the match or null is no match.</returns>
|
||||
protected virtual MediaTypeFormatterMatch MatchAcceptHeader([NotNull] IEnumerable<MediaTypeWithQualityHeaderValue> sortedAcceptValues, [NotNull] MediaTypeFormatter formatter)
|
||||
/// <returns>
|
||||
/// A <see cref="MediaTypeFormatterMatch"/> indicating the quality of the match or null is no match.
|
||||
/// </returns>
|
||||
protected virtual MediaTypeFormatterMatch MatchAcceptHeader(
|
||||
[NotNull] IEnumerable<MediaTypeWithQualityHeaderValue> sortedAcceptValues,
|
||||
[NotNull] MediaTypeFormatter formatter)
|
||||
{
|
||||
foreach (MediaTypeWithQualityHeaderValue acceptMediaTypeValue in sortedAcceptValues)
|
||||
{
|
||||
List<MediaTypeHeaderValue> supportedMediaTypes = formatter.SupportedMediaTypes.ToList();
|
||||
for (int i = 0; i < supportedMediaTypes.Count; i++)
|
||||
var supportedMediaTypes = formatter.SupportedMediaTypes.ToList();
|
||||
for (var i = 0; i < supportedMediaTypes.Count; i++)
|
||||
{
|
||||
MediaTypeHeaderValue supportedMediaType = supportedMediaTypes[i];
|
||||
var supportedMediaType = supportedMediaTypes[i];
|
||||
MediaTypeHeaderValueRange range;
|
||||
if (supportedMediaType != null && acceptMediaTypeValue.Quality != FormattingUtilities.NoMatch &&
|
||||
if (supportedMediaType != null &&
|
||||
acceptMediaTypeValue.Quality != FormattingUtilities.NoMatch &&
|
||||
supportedMediaType.IsSubsetOf(acceptMediaTypeValue, out range))
|
||||
{
|
||||
MediaTypeFormatterMatchRanking ranking;
|
||||
|
|
@ -321,7 +340,11 @@ namespace System.Net.Http.Formatting
|
|||
break;
|
||||
}
|
||||
|
||||
return new MediaTypeFormatterMatch(formatter, supportedMediaType, acceptMediaTypeValue.Quality, ranking);
|
||||
return new MediaTypeFormatterMatch(
|
||||
formatter,
|
||||
supportedMediaType,
|
||||
acceptMediaTypeValue.Quality,
|
||||
ranking);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -335,21 +358,29 @@ namespace System.Net.Http.Formatting
|
|||
/// </summary>
|
||||
/// <param name="request">The request to match.</param>
|
||||
/// <param name="formatter">The formatter to match against.</param>
|
||||
/// <returns>A <see cref="MediaTypeFormatterMatch"/> indicating the quality of the match or null is no match.</returns>
|
||||
protected virtual MediaTypeFormatterMatch MatchRequestMediaType([NotNull] HttpRequestMessage request, [NotNull] MediaTypeFormatter formatter)
|
||||
/// <returns>
|
||||
/// A <see cref="MediaTypeFormatterMatch"/> indicating the quality of the match or null is no match.
|
||||
/// </returns>
|
||||
protected virtual MediaTypeFormatterMatch MatchRequestMediaType(
|
||||
[NotNull] HttpRequestMessage request,
|
||||
[NotNull] MediaTypeFormatter formatter)
|
||||
{
|
||||
if (request.Content != null)
|
||||
{
|
||||
MediaTypeHeaderValue requestMediaType = request.Content.Headers.ContentType;
|
||||
var requestMediaType = request.Content.Headers.ContentType;
|
||||
if (requestMediaType != null)
|
||||
{
|
||||
List<MediaTypeHeaderValue> supportedMediaTypes = formatter.SupportedMediaTypes.ToList();
|
||||
for (int i = 0; i < supportedMediaTypes.Count; i++)
|
||||
var supportedMediaTypes = formatter.SupportedMediaTypes.ToList();
|
||||
for (var i = 0; i < supportedMediaTypes.Count; i++)
|
||||
{
|
||||
MediaTypeHeaderValue supportedMediaType = supportedMediaTypes[i];
|
||||
var supportedMediaType = supportedMediaTypes[i];
|
||||
if (supportedMediaType != null && supportedMediaType.IsSubsetOf(requestMediaType))
|
||||
{
|
||||
return new MediaTypeFormatterMatch(formatter, supportedMediaType, FormattingUtilities.Match, MediaTypeFormatterMatchRanking.MatchOnRequestMediaType);
|
||||
return new MediaTypeFormatterMatch(
|
||||
formatter,
|
||||
supportedMediaType,
|
||||
FormattingUtilities.Match,
|
||||
MediaTypeFormatterMatchRanking.MatchOnRequestMediaType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -365,8 +396,11 @@ namespace System.Net.Http.Formatting
|
|||
/// then we don't match on type unless there are no accept headers.
|
||||
/// </summary>
|
||||
/// <param name="sortedAcceptValues">The sorted accept header values to match.</param>
|
||||
/// <returns>True if not ExcludeMatchOnTypeOnly and accept headers with a q-factor bigger than 0.0 are present.</returns>
|
||||
protected virtual bool ShouldMatchOnType([NotNull] IEnumerable<MediaTypeWithQualityHeaderValue> sortedAcceptValues)
|
||||
/// <returns>
|
||||
/// True if not ExcludeMatchOnTypeOnly and accept headers with a q-factor bigger than 0.0 are present.
|
||||
/// </returns>
|
||||
protected virtual bool ShouldMatchOnType(
|
||||
[NotNull] IEnumerable<MediaTypeWithQualityHeaderValue> sortedAcceptValues)
|
||||
{
|
||||
return !(ExcludeMatchOnTypeOnly && sortedAcceptValues.Any());
|
||||
}
|
||||
|
|
@ -376,18 +410,26 @@ namespace System.Net.Http.Formatting
|
|||
/// </summary>
|
||||
/// <param name="type">The type to be serialized.</param>
|
||||
/// <param name="formatter">The formatter we are matching against.</param>
|
||||
/// <returns>A <see cref="MediaTypeFormatterMatch"/> indicating the quality of the match or null is no match.</returns>
|
||||
protected virtual MediaTypeFormatterMatch MatchType([NotNull] Type type, [NotNull] MediaTypeFormatter formatter)
|
||||
/// <returns>
|
||||
/// A <see cref="MediaTypeFormatterMatch"/> indicating the quality of the match or null is no match.
|
||||
/// </returns>
|
||||
protected virtual MediaTypeFormatterMatch MatchType(
|
||||
[NotNull] Type type,
|
||||
[NotNull] MediaTypeFormatter formatter)
|
||||
{
|
||||
// We already know that we do match on type -- otherwise we wouldn't even be called --
|
||||
// so this is just a matter of determining how we match.
|
||||
MediaTypeHeaderValue mediaType = null;
|
||||
List<MediaTypeHeaderValue> supportedMediaTypes = formatter.SupportedMediaTypes.ToList();
|
||||
var supportedMediaTypes = formatter.SupportedMediaTypes.ToList();
|
||||
if (supportedMediaTypes.Count > 0)
|
||||
{
|
||||
mediaType = supportedMediaTypes[0];
|
||||
}
|
||||
return new MediaTypeFormatterMatch(formatter, mediaType, FormattingUtilities.Match, MediaTypeFormatterMatchRanking.MatchOnCanWriteType);
|
||||
return new MediaTypeFormatterMatch(
|
||||
formatter,
|
||||
mediaType,
|
||||
FormattingUtilities.Match,
|
||||
MediaTypeFormatterMatchRanking.MatchOnCanWriteType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -396,13 +438,16 @@ namespace System.Net.Http.Formatting
|
|||
/// </summary>
|
||||
/// <param name="headerValues">The header values to sort.</param>
|
||||
/// <returns>The sorted header values.</returns>
|
||||
protected virtual IEnumerable<MediaTypeWithQualityHeaderValue> SortMediaTypeWithQualityHeaderValuesByQFactor(ICollection<MediaTypeWithQualityHeaderValue> headerValues)
|
||||
protected virtual IEnumerable<MediaTypeWithQualityHeaderValue> SortMediaTypeWithQualityHeaderValuesByQFactor(
|
||||
ICollection<MediaTypeWithQualityHeaderValue> headerValues)
|
||||
{
|
||||
if (headerValues.Count > 1)
|
||||
{
|
||||
// Use OrderBy() instead of Array.Sort() as it performs fewer comparisons. In this case the comparisons
|
||||
// are quite expensive so OrderBy() performs better.
|
||||
return headerValues.OrderByDescending(m => m, MediaTypeWithQualityHeaderValueComparer.QualityComparer).ToArray();
|
||||
return headerValues
|
||||
.OrderByDescending(m => m, MediaTypeWithQualityHeaderValueComparer.QualityComparer)
|
||||
.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -411,18 +456,21 @@ namespace System.Net.Http.Formatting
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sort Accept-Charset, Accept-Encoding, Accept-Language and related header field values with similar syntax rules
|
||||
/// (if more than 1) in descending order based on q-factor.
|
||||
/// Sort Accept-Charset, Accept-Encoding, Accept-Language and related header field values with similar syntax
|
||||
/// rules (if more than 1) in descending order based on q-factor.
|
||||
/// </summary>
|
||||
/// <param name="headerValues">The header values to sort.</param>
|
||||
/// <returns>The sorted header values.</returns>
|
||||
protected virtual IEnumerable<StringWithQualityHeaderValue> SortStringWithQualityHeaderValuesByQFactor([NotNull] ICollection<StringWithQualityHeaderValue> headerValues)
|
||||
protected virtual IEnumerable<StringWithQualityHeaderValue> SortStringWithQualityHeaderValuesByQFactor(
|
||||
[NotNull] ICollection<StringWithQualityHeaderValue> headerValues)
|
||||
{
|
||||
if (headerValues.Count > 1)
|
||||
{
|
||||
// Use OrderBy() instead of Array.Sort() as it performs fewer comparisons. In this case the comparisons
|
||||
// are quite expensive so OrderBy() performs better.
|
||||
return headerValues.OrderByDescending(m => m, StringWithQualityHeaderValueComparer.QualityComparer).ToArray();
|
||||
return headerValues
|
||||
.OrderByDescending(m => m, StringWithQualityHeaderValueComparer.QualityComparer)
|
||||
.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -431,10 +479,12 @@ namespace System.Net.Http.Formatting
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates whether a match is better than the current match and if so returns the replacement; otherwise returns the
|
||||
/// current match.
|
||||
/// Evaluates whether a match is better than the current match and if so returns the replacement; otherwise
|
||||
/// returns the current match.
|
||||
/// </summary>
|
||||
protected virtual MediaTypeFormatterMatch UpdateBestMatch(MediaTypeFormatterMatch current, MediaTypeFormatterMatch potentialReplacement)
|
||||
protected virtual MediaTypeFormatterMatch UpdateBestMatch(
|
||||
MediaTypeFormatterMatch current,
|
||||
MediaTypeFormatterMatch potentialReplacement)
|
||||
{
|
||||
if (potentialReplacement == null)
|
||||
{
|
||||
|
|
@ -452,7 +502,6 @@ namespace System.Net.Http.Formatting
|
|||
private static MediaTypeFormatter[] GetWritingFormatters(IEnumerable<MediaTypeFormatter> formatters)
|
||||
{
|
||||
Debug.Assert(formatters != null);
|
||||
MediaTypeFormatterCollection formatterCollection = formatters as MediaTypeFormatterCollection;
|
||||
return formatters.AsArray();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,9 @@ using System.Globalization;
|
|||
using System.Linq;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace System.Net.Http
|
||||
{
|
||||
|
|
@ -161,7 +160,9 @@ namespace System.Net.Http
|
|||
/// <returns></returns>
|
||||
public static XmlDictionaryReaderQuotas CreateDefaultReaderQuotas()
|
||||
{
|
||||
#if NETFX_CORE // MaxDepth is a DOS mitigation. We don't support MaxDepth in portable libraries because it is strictly client side.
|
||||
// MaxDepth is a DOS mitigation. We don't support MaxDepth in portable libraries because it is strictly
|
||||
// client side.
|
||||
#if NETFX_CORE
|
||||
return XmlDictionaryReaderQuotas.Max;
|
||||
#else
|
||||
return new XmlDictionaryReaderQuotas()
|
||||
|
|
@ -187,7 +188,9 @@ namespace System.Net.Http
|
|||
return token;
|
||||
}
|
||||
|
||||
if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1)
|
||||
if (token.StartsWith("\"", StringComparison.Ordinal) &&
|
||||
token.EndsWith("\"", StringComparison.Ordinal) &&
|
||||
token.Length > 1)
|
||||
{
|
||||
return token.Substring(1, token.Length - 2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,20 +15,27 @@ namespace System.Net.Http.Formatting
|
|||
public interface IContentNegotiator
|
||||
{
|
||||
/// <summary>
|
||||
/// Performs content negotiating by selecting the most appropriate <see cref="MediaTypeFormatter"/> out of the passed in
|
||||
/// <paramref name="formatters"/> for the given <paramref name="request"/> that can serialize an object of the given
|
||||
/// <paramref name="type"/>.
|
||||
/// Performs content negotiating by selecting the most appropriate <see cref="MediaTypeFormatter"/> out of the
|
||||
/// passed in <paramref name="formatters"/> for the given <paramref name="request"/> that can serialize an
|
||||
/// object of the given <paramref name="type"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Implementations of this method should call <see cref="MediaTypeFormatter.GetPerRequestFormatterInstance(Type, HttpRequestMessage, MediaTypeHeaderValue)"/>
|
||||
/// Implementations of this method should call <see cref="MediaTypeFormatter.GetPerRequestFormatterInstance"/>
|
||||
/// on the selected <see cref="MediaTypeFormatter">formatter</see> and return the result of that method.
|
||||
/// </remarks>
|
||||
/// <param name="type">The type to be serialized.</param>
|
||||
/// <param name="request">Request message, which contains the header values used to perform negotiation.</param>
|
||||
/// <param name="request">
|
||||
/// Request message, which contains the header values used to perform negotiation.
|
||||
/// </param>
|
||||
/// <param name="formatters">The set of <see cref="MediaTypeFormatter"/> objects from which to choose.</param>
|
||||
/// <returns>The result of the negotiation containing the most appropriate <see cref="MediaTypeFormatter"/> instance,
|
||||
/// or <c>null</c> if there is no appropriate formatter.</returns>
|
||||
ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters);
|
||||
/// <returns>
|
||||
/// The result of the negotiation containing the most appropriate <see cref="MediaTypeFormatter"/> instance,
|
||||
/// or <c>null</c> if there is no appropriate formatter.
|
||||
/// </returns>
|
||||
ContentNegotiationResult Negotiate(
|
||||
Type type,
|
||||
HttpRequestMessage request,
|
||||
IEnumerable<MediaTypeFormatter> formatters);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,13 +12,20 @@ namespace System.Net.Http.Formatting
|
|||
/// </summary>
|
||||
internal static class MediaTypeConstants
|
||||
{
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationXmlMediaType = new MediaTypeHeaderValue("application/xml");
|
||||
private static readonly MediaTypeHeaderValue _defaultTextXmlMediaType = new MediaTypeHeaderValue("text/xml");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationJsonMediaType = new MediaTypeHeaderValue("application/json");
|
||||
private static readonly MediaTypeHeaderValue _defaultTextJsonMediaType = new MediaTypeHeaderValue("text/json");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationOctetStreamMediaType = new MediaTypeHeaderValue("application/octet-stream");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationFormUrlEncodedMediaType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationBsonMediaType = new MediaTypeHeaderValue("application/bson");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationXmlMediaType =
|
||||
new MediaTypeHeaderValue("application/xml");
|
||||
private static readonly MediaTypeHeaderValue _defaultTextXmlMediaType =
|
||||
new MediaTypeHeaderValue("text/xml");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationJsonMediaType =
|
||||
new MediaTypeHeaderValue("application/json");
|
||||
private static readonly MediaTypeHeaderValue _defaultTextJsonMediaType =
|
||||
new MediaTypeHeaderValue("text/json");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationOctetStreamMediaType =
|
||||
new MediaTypeHeaderValue("application/octet-stream");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationFormUrlEncodedMediaType =
|
||||
new MediaTypeHeaderValue("application/x-www-form-urlencoded");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationBsonMediaType =
|
||||
new MediaTypeHeaderValue("application/bson");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="MediaTypeHeaderValue"/> instance representing <c>application/octet-stream</c>.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#if ASPNETCORE50
|
||||
|
||||
using System.Net.Http.Headers;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace System.Net.Http.Formatting
|
||||
{
|
||||
|
|
@ -17,10 +16,19 @@ namespace System.Net.Http.Formatting
|
|||
/// Initializes a new instance of the <see cref="MediaTypeFormatterMatch"/> class.
|
||||
/// </summary>
|
||||
/// <param name="formatter">The matching formatter.</param>
|
||||
/// <param name="mediaType">The media type. Can be <c>null</c> in which case the media type <c>application/octet-stream</c> is used.</param>
|
||||
/// <param name="quality">The quality of the match. Can be <c>null</c> in which case it is considered a full match with a value of 1.0</param>
|
||||
/// <param name="mediaType">
|
||||
/// The media type. Can be <c>null</c> in which case the media type <c>application/octet-stream</c> is used.
|
||||
/// </param>
|
||||
/// <param name="quality">
|
||||
/// The quality of the match. Can be <c>null</c> in which case it is considered a full match with a value of
|
||||
/// 1.0.
|
||||
/// </param>
|
||||
/// <param name="ranking">The kind of match.</param>
|
||||
public MediaTypeFormatterMatch(MediaTypeFormatter formatter, MediaTypeHeaderValue mediaType, double? quality, MediaTypeFormatterMatchRanking ranking)
|
||||
public MediaTypeFormatterMatch(
|
||||
MediaTypeFormatter formatter,
|
||||
MediaTypeHeaderValue mediaType,
|
||||
double? quality,
|
||||
MediaTypeFormatterMatchRanking ranking)
|
||||
{
|
||||
Formatter = formatter;
|
||||
MediaType = mediaType != null ? mediaType : MediaTypeConstants.ApplicationOctetStreamMediaType;
|
||||
|
|
|
|||
|
|
@ -3,12 +3,10 @@
|
|||
|
||||
#if ASPNETCORE50
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace System.Net.Http.Formatting
|
||||
{
|
||||
|
|
@ -20,10 +18,11 @@ namespace System.Net.Http.Formatting
|
|||
/// <summary>
|
||||
/// Determines whether two <see cref="MediaTypeHeaderValue"/> instances match. The instance
|
||||
/// <paramref name="mediaType1"/> is said to match <paramref name="mediaType2"/> if and only if
|
||||
/// <paramref name="mediaType1"/> is a strict subset of the values and parameters of <paramref name="mediaType2"/>.
|
||||
/// <paramref name="mediaType1"/> is a strict subset of the values and parameters of
|
||||
/// <paramref name="mediaType2"/>.
|
||||
/// That is, if the media type and media type parameters of <paramref name="mediaType1"/> are all present
|
||||
/// and match those of <paramref name="mediaType2"/> then it is a match even though <paramref name="mediaType2"/> may have additional
|
||||
/// parameters.
|
||||
/// and match those of <paramref name="mediaType2"/> then it is a match even though
|
||||
/// <paramref name="mediaType2"/> may have additional parameters.
|
||||
/// </summary>
|
||||
/// <param name="mediaType1">The first media type.</param>
|
||||
/// <param name="mediaType2">The second media type.</param>
|
||||
|
|
@ -37,16 +36,23 @@ namespace System.Net.Http.Formatting
|
|||
/// <summary>
|
||||
/// Determines whether two <see cref="MediaTypeHeaderValue"/> instances match. The instance
|
||||
/// <paramref name="mediaType1"/> is said to match <paramref name="mediaType2"/> if and only if
|
||||
/// <paramref name="mediaType1"/> is a strict subset of the values and parameters of <paramref name="mediaType2"/>.
|
||||
/// <paramref name="mediaType1"/> is a strict subset of the values and parameters of
|
||||
/// <paramref name="mediaType2"/>.
|
||||
/// That is, if the media type and media type parameters of <paramref name="mediaType1"/> are all present
|
||||
/// and match those of <paramref name="mediaType2"/> then it is a match even though <paramref name="mediaType2"/> may have additional
|
||||
/// parameters.
|
||||
/// and match those of <paramref name="mediaType2"/> then it is a match even though
|
||||
/// <paramref name="mediaType2"/> may have additional parameters.
|
||||
/// </summary>
|
||||
/// <param name="mediaType1">The first media type.</param>
|
||||
/// <param name="mediaType2">The second media type.</param>
|
||||
/// <param name="mediaType2Range">Indicates whether <paramref name="mediaType2"/> is a regular media type, a subtype media range, or a full media range</param>
|
||||
/// <param name="mediaType2Range">
|
||||
/// Indicates whether <paramref name="mediaType2"/> is a regular media type, a subtype media range, or a full
|
||||
/// media range.
|
||||
/// </param>
|
||||
/// <returns><c>true</c> if this is a subset of <paramref name="mediaType2"/>; false otherwise.</returns>
|
||||
public static bool IsSubsetOf(this MediaTypeHeaderValue mediaType1, MediaTypeHeaderValue mediaType2, out MediaTypeHeaderValueRange mediaType2Range)
|
||||
public static bool IsSubsetOf(
|
||||
this MediaTypeHeaderValue mediaType1,
|
||||
MediaTypeHeaderValue mediaType2,
|
||||
out MediaTypeHeaderValueRange mediaType2Range)
|
||||
{
|
||||
// Performance-sensitive
|
||||
Debug.Assert(mediaType1 != null);
|
||||
|
|
@ -57,8 +63,8 @@ namespace System.Net.Http.Formatting
|
|||
return false;
|
||||
}
|
||||
|
||||
ParsedMediaTypeHeaderValue parsedMediaType1 = new ParsedMediaTypeHeaderValue(mediaType1);
|
||||
ParsedMediaTypeHeaderValue parsedMediaType2 = new ParsedMediaTypeHeaderValue(mediaType2);
|
||||
var parsedMediaType1 = new ParsedMediaTypeHeaderValue(mediaType1);
|
||||
var parsedMediaType2 = new ParsedMediaTypeHeaderValue(mediaType2);
|
||||
mediaType2Range = parsedMediaType2.IsAllMediaRange ? MediaTypeHeaderValueRange.AllMediaRange :
|
||||
parsedMediaType2.IsSubtypeMediaRange ? MediaTypeHeaderValueRange.SubtypeMediaRange :
|
||||
MediaTypeHeaderValueRange.None;
|
||||
|
|
@ -80,18 +86,19 @@ namespace System.Net.Http.Formatting
|
|||
|
||||
// So far we either have a full match or a subset match. Now check that all of
|
||||
// mediaType1's parameters are present and equal in mediatype2
|
||||
// Optimize for the common case where the parameters inherit from Collection<T> and cache the count which is faster for Collection<T>.
|
||||
Collection<NameValueHeaderValue> parameters1 = mediaType1.Parameters.AsCollection();
|
||||
int parameterCount1 = parameters1.Count;
|
||||
Collection<NameValueHeaderValue> parameters2 = mediaType2.Parameters.AsCollection();
|
||||
int parameterCount2 = parameters2.Count;
|
||||
for (int i = 0; i < parameterCount1; i++)
|
||||
// Optimize for the common case where the parameters inherit from Collection<T> and cache the count which
|
||||
// is faster for Collection<T>.
|
||||
var parameters1 = mediaType1.Parameters.AsCollection();
|
||||
var parameterCount1 = parameters1.Count;
|
||||
var parameters2 = mediaType2.Parameters.AsCollection();
|
||||
var parameterCount2 = parameters2.Count;
|
||||
for (var i = 0; i < parameterCount1; i++)
|
||||
{
|
||||
NameValueHeaderValue parameter1 = parameters1[i];
|
||||
bool found = false;
|
||||
for (int j = 0; j < parameterCount2; j++)
|
||||
var parameter1 = parameters1[i];
|
||||
var found = false;
|
||||
for (var j = 0; j < parameterCount2; j++)
|
||||
{
|
||||
NameValueHeaderValue parameter2 = parameters2[j];
|
||||
var parameter2 = parameters2[j];
|
||||
if (parameter1.Equals(parameter2))
|
||||
{
|
||||
found = true;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ namespace System.Net.Http.Formatting
|
|||
/// header field q-values.
|
||||
internal class MediaTypeWithQualityHeaderValueComparer : IComparer<MediaTypeWithQualityHeaderValue>
|
||||
{
|
||||
private static readonly MediaTypeWithQualityHeaderValueComparer _mediaTypeComparer = new MediaTypeWithQualityHeaderValueComparer();
|
||||
private static readonly MediaTypeWithQualityHeaderValueComparer _mediaTypeComparer =
|
||||
new MediaTypeWithQualityHeaderValueComparer();
|
||||
|
||||
private MediaTypeWithQualityHeaderValueComparer()
|
||||
{
|
||||
|
|
@ -27,11 +28,12 @@ namespace System.Net.Http.Formatting
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="MediaTypeWithQualityHeaderValue"/> based on their quality value (a.k.a their "q-value").
|
||||
/// Values with identical q-values are considered equal (i.e the result is 0) with the exception that sub-type wild-cards are
|
||||
/// considered less than specific media types and full wild-cards are considered less than sub-type wild-cards. This allows to
|
||||
/// sort a sequence of <see cref="StringWithQualityHeaderValue"/> following their q-values in the order of specific media types,
|
||||
/// sub-type wildcards, and last any full wild-cards.
|
||||
/// Compares two <see cref="MediaTypeWithQualityHeaderValue"/> based on their quality value (a.k.a their
|
||||
/// "q-value"). Values with identical q-values are considered equal (i.e the result is 0) with the exception
|
||||
/// that sub-type wild-cards are considered less than specific media types and full wild-cards are considered
|
||||
/// less than sub-type wild-cards. This allows to sort a sequence of <see cref="StringWithQualityHeaderValue"/>
|
||||
/// following their q-values in the order of specific media types, subtype wild-cards, and last any full
|
||||
/// wild-cards.
|
||||
/// </summary>
|
||||
/// <param name="mediaType1">The first <see cref="MediaTypeWithQualityHeaderValue"/> to compare.</param>
|
||||
/// <param name="mediaType2">The second <see cref="MediaTypeWithQualityHeaderValue"/> to compare.</param>
|
||||
|
|
@ -46,12 +48,11 @@ namespace System.Net.Http.Formatting
|
|||
return 0;
|
||||
}
|
||||
|
||||
int returnValue = CompareBasedOnQualityFactor(mediaType1, mediaType2);
|
||||
|
||||
var returnValue = CompareBasedOnQualityFactor(mediaType1, mediaType2);
|
||||
if (returnValue == 0)
|
||||
{
|
||||
ParsedMediaTypeHeaderValue parsedMediaType1 = new ParsedMediaTypeHeaderValue(mediaType1);
|
||||
ParsedMediaTypeHeaderValue parsedMediaType2 = new ParsedMediaTypeHeaderValue(mediaType2);
|
||||
var parsedMediaType1 = new ParsedMediaTypeHeaderValue(mediaType1);
|
||||
var parsedMediaType2 = new ParsedMediaTypeHeaderValue(mediaType2);
|
||||
|
||||
if (!parsedMediaType1.TypesEqual(ref parsedMediaType2))
|
||||
{
|
||||
|
|
@ -88,14 +89,16 @@ namespace System.Net.Http.Formatting
|
|||
return returnValue;
|
||||
}
|
||||
|
||||
private static int CompareBasedOnQualityFactor(MediaTypeWithQualityHeaderValue mediaType1, MediaTypeWithQualityHeaderValue mediaType2)
|
||||
private static int CompareBasedOnQualityFactor(
|
||||
MediaTypeWithQualityHeaderValue mediaType1,
|
||||
MediaTypeWithQualityHeaderValue mediaType2)
|
||||
{
|
||||
Debug.Assert(mediaType1 != null);
|
||||
Debug.Assert(mediaType2 != null);
|
||||
|
||||
double mediaType1Quality = mediaType1.Quality ?? FormattingUtilities.Match;
|
||||
double mediaType2Quality = mediaType2.Quality ?? FormattingUtilities.Match;
|
||||
double qualityDifference = mediaType1Quality - mediaType2Quality;
|
||||
var mediaType1Quality = mediaType1.Quality ?? FormattingUtilities.Match;
|
||||
var mediaType2Quality = mediaType2.Quality ?? FormattingUtilities.Match;
|
||||
var qualityDifference = mediaType1Quality - mediaType2Quality;
|
||||
if (qualityDifference < 0)
|
||||
{
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using System.Net.Http.Headers;
|
|||
|
||||
namespace System.Net.Http.Formatting
|
||||
{
|
||||
// This type is instanciated by frequently called comparison methods so is very performance sensitive
|
||||
// This type is instantiated by frequently called comparison methods so is very performance sensitive
|
||||
internal struct ParsedMediaTypeHeaderValue
|
||||
{
|
||||
private const char MediaRangeAsterisk = '*';
|
||||
|
|
@ -22,13 +22,15 @@ namespace System.Net.Http.Formatting
|
|||
public ParsedMediaTypeHeaderValue(MediaTypeHeaderValue mediaTypeHeaderValue)
|
||||
{
|
||||
Debug.Assert(mediaTypeHeaderValue != null);
|
||||
string mediaType = _mediaType = mediaTypeHeaderValue.MediaType;
|
||||
var mediaType = _mediaType = mediaTypeHeaderValue.MediaType;
|
||||
_delimiterIndex = mediaType.IndexOf(MediaTypeSubtypeDelimiter);
|
||||
Debug.Assert(_delimiterIndex > 0, "The constructor of the MediaTypeHeaderValue would have failed if there wasn't a type and subtype.");
|
||||
Debug.Assert(
|
||||
_delimiterIndex > 0,
|
||||
"The constructor of the MediaTypeHeaderValue would have failed if there wasn't a type and subtype.");
|
||||
|
||||
_isAllMediaRange = false;
|
||||
_isSubtypeMediaRange = false;
|
||||
int mediaTypeLength = mediaType.Length;
|
||||
var mediaTypeLength = mediaType.Length;
|
||||
if (_delimiterIndex == mediaTypeLength - 2)
|
||||
{
|
||||
if (mediaType[mediaTypeLength - 1] == MediaRangeAsterisk)
|
||||
|
|
@ -58,17 +60,31 @@ namespace System.Net.Http.Formatting
|
|||
{
|
||||
return false;
|
||||
}
|
||||
return String.Compare(_mediaType, 0, other._mediaType, 0, _delimiterIndex, StringComparison.OrdinalIgnoreCase) == 0;
|
||||
|
||||
return string.Compare(
|
||||
strA: _mediaType,
|
||||
indexA: 0,
|
||||
strB: other._mediaType,
|
||||
indexB: 0,
|
||||
length: _delimiterIndex,
|
||||
comparisonType: StringComparison.OrdinalIgnoreCase) == 0;
|
||||
}
|
||||
|
||||
public bool SubTypesEqual(ref ParsedMediaTypeHeaderValue other)
|
||||
{
|
||||
int _subTypeLength = _mediaType.Length - _delimiterIndex - 1;
|
||||
var _subTypeLength = _mediaType.Length - _delimiterIndex - 1;
|
||||
if (_subTypeLength != other._mediaType.Length - other._delimiterIndex - 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return String.Compare(_mediaType, _delimiterIndex + 1, other._mediaType, other._delimiterIndex + 1, _subTypeLength, StringComparison.OrdinalIgnoreCase) == 0;
|
||||
|
||||
return string.Compare(
|
||||
strA: _mediaType,
|
||||
indexA: _delimiterIndex + 1,
|
||||
strB: other._mediaType,
|
||||
indexB: other._delimiterIndex + 1,
|
||||
length: _subTypeLength,
|
||||
comparisonType: StringComparison.OrdinalIgnoreCase) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,10 +31,10 @@ namespace System.Net.Http.Formatting
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="StringWithQualityHeaderValue"/> based on their quality value (a.k.a their "q-value").
|
||||
/// Values with identical q-values are considered equal (i.e the result is 0) with the exception of wild-card
|
||||
/// values (i.e. a value of "*") which are considered less than non-wild-card values. This allows to sort
|
||||
/// a sequence of <see cref="StringWithQualityHeaderValue"/> following their q-values ending up with any
|
||||
/// Compares two <see cref="StringWithQualityHeaderValue"/> based on their quality value (a.k.a their
|
||||
/// "q-value"). Values with identical q-values are considered equal (i.e the result is 0) with the exception of
|
||||
/// wild-card values (i.e. a value of "*") which are considered less than non-wild-card values. This allows to
|
||||
/// sort a sequence of <see cref="StringWithQualityHeaderValue"/> following their q-values ending up with any
|
||||
/// wild-cards at the end.
|
||||
/// </summary>
|
||||
/// <param name="stringWithQuality1">The first value to compare.</param>
|
||||
|
|
@ -46,9 +46,9 @@ namespace System.Net.Http.Formatting
|
|||
Debug.Assert(stringWithQuality1 != null);
|
||||
Debug.Assert(stringWithQuality2 != null);
|
||||
|
||||
double quality1 = stringWithQuality1.Quality ?? FormattingUtilities.Match;
|
||||
double quality2 = stringWithQuality2.Quality ?? FormattingUtilities.Match;
|
||||
double qualityDifference = quality1 - quality2;
|
||||
var quality1 = stringWithQuality1.Quality ?? FormattingUtilities.Match;
|
||||
var quality2 = stringWithQuality2.Quality ?? FormattingUtilities.Match;
|
||||
var qualityDifference = quality1 - quality2;
|
||||
if (qualityDifference < 0)
|
||||
{
|
||||
return -1;
|
||||
|
|
@ -58,7 +58,7 @@ namespace System.Net.Http.Formatting
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (!String.Equals(stringWithQuality1.Value, stringWithQuality2.Value, StringComparison.OrdinalIgnoreCase))
|
||||
if (!string.Equals(stringWithQuality1.Value, stringWithQuality2.Value, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (String.Equals(stringWithQuality1.Value, "*", StringComparison.Ordinal))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
|
|||
var i = 0;
|
||||
while (true)
|
||||
{
|
||||
int indexOpen = key.IndexOf('[', i);
|
||||
var indexOpen = key.IndexOf('[', i);
|
||||
if (indexOpen < 0)
|
||||
{
|
||||
// Fast path, no normalization needed.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ namespace System.Web.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpError"/> class containing error message <paramref name="message"/>.
|
||||
/// Initializes a new instance of the <see cref="HttpError"/> class containing error message
|
||||
/// <paramref name="message"/>.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message to associate with this instance.</param>
|
||||
public HttpError([NotNull] string message)
|
||||
|
|
@ -42,7 +43,9 @@ namespace System.Web.Http
|
|||
/// Initializes a new instance of the <see cref="HttpError"/> class for <paramref name="exception"/>.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to use for error information.</param>
|
||||
/// <param name="includeErrorDetail"><c>true</c> to include the exception information in the error; <c>false</c> otherwise</param>
|
||||
/// <param name="includeErrorDetail">
|
||||
/// <c>true</c> to include the exception information in the error;<c>false</c> otherwise.
|
||||
/// </param>
|
||||
public HttpError([NotNull] Exception exception, bool includeErrorDetail)
|
||||
: this()
|
||||
{
|
||||
|
|
@ -64,7 +67,9 @@ namespace System.Web.Http
|
|||
/// Initializes a new instance of the <see cref="HttpError"/> class for <paramref name="modelState"/>.
|
||||
/// </summary>
|
||||
/// <param name="modelState">The invalid model state to use for error information.</param>
|
||||
/// <param name="includeErrorDetail"><c>true</c> to include exception messages in the error; <c>false</c> otherwise</param>
|
||||
/// <param name="includeErrorDetail">
|
||||
/// <c>true</c> to include exception messages in the error; <c>false</c> otherwise.
|
||||
/// </param>
|
||||
public HttpError([NotNull] ModelStateDictionary modelState, bool includeErrorDetail)
|
||||
: this()
|
||||
{
|
||||
|
|
@ -105,8 +110,9 @@ namespace System.Web.Http
|
|||
|
||||
/// <summary>
|
||||
/// The high-level, user-visible message explaining the cause of the error. Information carried in this field
|
||||
/// should be considered public in that it will go over the wire regardless of the value of error detail policy.
|
||||
/// As a result care should be taken not to disclose sensitive information about the server or the application.
|
||||
/// should be considered public in that it will go over the wire regardless of the value of error detail
|
||||
/// policy. As a result care should be taken not to disclose sensitive information about the server or the
|
||||
/// application.
|
||||
/// </summary>
|
||||
public string Message
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,19 +20,22 @@ namespace System.Net.Http
|
|||
/// </summary>
|
||||
public static class HttpRequestMessageExtensions
|
||||
{
|
||||
|
||||
#if !ASPNETCORE50
|
||||
|
||||
/// <summary>
|
||||
/// Helper method for creating an <see cref="HttpResponseMessage"/> message with a "416 (Requested Range Not Satisfiable)" status code.
|
||||
/// This response can be used in combination with the <see cref="ByteRangeStreamContent"/> to indicate that the requested range or
|
||||
/// ranges do not overlap with the current resource. The response contains a "Content-Range" header indicating the valid upper and lower
|
||||
/// bounds for requested ranges.
|
||||
/// Helper method for creating an <see cref="HttpResponseMessage"/> message with a "416 (Requested Range Not
|
||||
/// Satisfiable)" status code. This response can be used in combination with the
|
||||
/// <see cref="ByteRangeStreamContent"/> to indicate that the requested range or
|
||||
/// ranges do not overlap with the current resource. The response contains a "Content-Range" header indicating
|
||||
/// the valid upper and lower bounds for requested ranges.
|
||||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <param name="invalidByteRangeException">An <see cref="InvalidByteRangeException"/> instance, typically thrown by a
|
||||
/// <see cref="ByteRangeStreamContent"/> instance.</param>
|
||||
/// <returns>An 416 (Requested Range Not Satisfiable) error response with a Content-Range header indicating the valid range.</returns>
|
||||
/// <param name="invalidByteRangeException">An <see cref="InvalidByteRangeException"/> instance, typically
|
||||
/// thrown by a <see cref="ByteRangeStreamContent"/> instance.</param>
|
||||
/// <returns>
|
||||
/// An 416 (Requested Range Not Satisfiable) error response with a Content-Range header indicating the valid
|
||||
/// range.
|
||||
/// </returns>
|
||||
public static HttpResponseMessage CreateErrorResponse(
|
||||
[NotNull] this HttpRequestMessage request,
|
||||
[NotNull] InvalidByteRangeException invalidByteRangeException)
|
||||
|
|
@ -47,9 +50,10 @@ namespace System.Net.Http
|
|||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/> representing an error
|
||||
/// with an instance of <see cref="ObjectContent{T}"/> wrapping an <see cref="HttpError"/> with message <paramref name="message"/>.
|
||||
/// If no formatter is found, this method returns a response with status 406 NotAcceptable.
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/>
|
||||
/// representing an error with an instance of <see cref="ObjectContent{T}"/> wrapping an
|
||||
/// <see cref="HttpError"/> with message <paramref name="message"/>. If no formatter is found, this method
|
||||
/// returns a response with status 406 NotAcceptable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method requires that <paramref name="request"/> has been associated with an instance of
|
||||
|
|
@ -58,7 +62,10 @@ namespace System.Net.Http
|
|||
/// <param name="request">The request.</param>
|
||||
/// <param name="statusCode">The status code of the created response.</param>
|
||||
/// <param name="message">The error message.</param>
|
||||
/// <returns>An error response with error message <paramref name="message"/> and status code <paramref name="statusCode"/>.</returns>
|
||||
/// <returns>
|
||||
/// An error response with error message <paramref name="message"/> and status code
|
||||
/// <paramref name="statusCode"/>.
|
||||
/// </returns>
|
||||
public static HttpResponseMessage CreateErrorResponse(
|
||||
[NotNull] this HttpRequestMessage request,
|
||||
HttpStatusCode statusCode,
|
||||
|
|
@ -68,9 +75,11 @@ namespace System.Net.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/> representing an error
|
||||
/// with an instance of <see cref="ObjectContent{T}"/> wrapping an <see cref="HttpError"/> with error message <paramref name="message"/>
|
||||
/// for exception <paramref name="exception"/>. If no formatter is found, this method returns a response with status 406 NotAcceptable.
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/>
|
||||
/// representing an error with an instance of <see cref="ObjectContent{T}"/> wrapping an
|
||||
/// <see cref="HttpError"/> with error message <paramref name="message"/> for exception
|
||||
/// <paramref name="exception"/>. If no formatter is found, this method returns a response with status 406
|
||||
/// NotAcceptable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method requires that <paramref name="request"/> has been associated with an instance of
|
||||
|
|
@ -93,9 +102,10 @@ namespace System.Net.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/> representing an error
|
||||
/// with an instance of <see cref="ObjectContent{T}"/> wrapping an <see cref="HttpError"/> for exception <paramref name="exception"/>.
|
||||
/// If no formatter is found, this method returns a response with status 406 NotAcceptable.
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/>
|
||||
/// representing an error with an instance of <see cref="ObjectContent{T}"/> wrapping an
|
||||
/// <see cref="HttpError"/> for exception <paramref name="exception"/>. If no formatter is found, this method
|
||||
/// returns a response with status 406 NotAcceptable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method requires that <paramref name="request"/> has been associated with an instance of
|
||||
|
|
@ -104,7 +114,9 @@ namespace System.Net.Http
|
|||
/// <param name="request">The request.</param>
|
||||
/// <param name="statusCode">The status code of the created response.</param>
|
||||
/// <param name="exception">The exception.</param>
|
||||
/// <returns>An error response for <paramref name="exception"/> with status code <paramref name="statusCode"/>.</returns>
|
||||
/// <returns>
|
||||
/// An error response for <paramref name="exception"/> with status code <paramref name="statusCode"/>.
|
||||
/// </returns>
|
||||
public static HttpResponseMessage CreateErrorResponse(
|
||||
[NotNull] this HttpRequestMessage request,
|
||||
HttpStatusCode statusCode,
|
||||
|
|
@ -114,9 +126,10 @@ namespace System.Net.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/> representing an error
|
||||
/// with an instance of <see cref="ObjectContent{T}"/> wrapping an <see cref="HttpError"/> for model state <paramref name="modelState"/>.
|
||||
/// If no formatter is found, this method returns a response with status 406 NotAcceptable.
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/>
|
||||
/// representing an error with an instance of <see cref="ObjectContent{T}"/> wrapping an
|
||||
/// <see cref="HttpError"/> for model state <paramref name="modelState"/>. If no formatter is found, this
|
||||
/// method returns a response with status 406 NotAcceptable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method requires that <paramref name="request"/> has been associated with an instance of
|
||||
|
|
@ -125,7 +138,9 @@ namespace System.Net.Http
|
|||
/// <param name="request">The request.</param>
|
||||
/// <param name="statusCode">The status code of the created response.</param>
|
||||
/// <param name="modelState">The model state.</param>
|
||||
/// <returns>An error response for <paramref name="modelState"/> with status code <paramref name="statusCode"/>.</returns>
|
||||
/// <returns>
|
||||
/// An error response for <paramref name="modelState"/> with status code <paramref name="statusCode"/>.
|
||||
/// </returns>
|
||||
public static HttpResponseMessage CreateErrorResponse(
|
||||
[NotNull] this HttpRequestMessage request,
|
||||
HttpStatusCode statusCode,
|
||||
|
|
@ -135,9 +150,9 @@ namespace System.Net.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/> representing an error
|
||||
/// with an instance of <see cref="ObjectContent{T}"/> wrapping <paramref name="error"/> as the content. If no formatter
|
||||
/// is found, this method returns a response with status 406 NotAcceptable.
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/>
|
||||
/// representing an error with an instance of <see cref="ObjectContent{T}"/> wrapping <paramref name="error"/>
|
||||
/// as the content. If no formatter is found, this method returns a response with status 406 NotAcceptable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method requires that <paramref name="request"/> has been associated with an instance of
|
||||
|
|
@ -146,7 +161,9 @@ namespace System.Net.Http
|
|||
/// <param name="request">The request.</param>
|
||||
/// <param name="statusCode">The status code of the created response.</param>
|
||||
/// <param name="error">The error to wrap.</param>
|
||||
/// <returns>An error response wrapping <paramref name="error"/> with status code <paramref name="statusCode"/>.</returns>
|
||||
/// <returns>
|
||||
/// An error response wrapping <paramref name="error"/> with status code <paramref name="statusCode"/>.
|
||||
/// </returns>
|
||||
public static HttpResponseMessage CreateErrorResponse(
|
||||
[NotNull] this HttpRequestMessage request,
|
||||
HttpStatusCode statusCode,
|
||||
|
|
@ -156,9 +173,10 @@ namespace System.Net.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/> with an instance
|
||||
/// of <see cref="ObjectContent{T}"/> as the content and <see cref="System.Net.HttpStatusCode.OK"/> as the status code
|
||||
/// if a formatter can be found. If no formatter is found, this method returns a response with status 406 NotAcceptable.
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/> with an
|
||||
/// instance of <see cref="ObjectContent{T}"/> as the content and <see cref="System.Net.HttpStatusCode.OK"/>
|
||||
/// as the status code if a formatter can be found. If no formatter is found, this method returns a response
|
||||
/// with status 406 NotAcceptable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method requires that <paramref name="request"/> has been associated with an instance of
|
||||
|
|
@ -167,16 +185,18 @@ namespace System.Net.Http
|
|||
/// <typeparam name="T">The type of the value.</typeparam>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <param name="value">The value to wrap. Can be <c>null</c>.</param>
|
||||
/// <returns>A response wrapping <paramref name="value"/> with <see cref="System.Net.HttpStatusCode.OK"/> status code.</returns>
|
||||
/// <returns>
|
||||
/// A response wrapping <paramref name="value"/> with <see cref="System.Net.HttpStatusCode.OK"/> status code.
|
||||
/// </returns>
|
||||
public static HttpResponseMessage CreateResponse<T>([NotNull] this HttpRequestMessage request, T value)
|
||||
{
|
||||
return request.CreateResponse<T>(HttpStatusCode.OK, value, formatters: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/> with an instance
|
||||
/// of <see cref="ObjectContent{T}"/> as the content if a formatter can be found. If no formatter is found, this
|
||||
/// method returns a response with status 406 NotAcceptable.
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/> with an
|
||||
/// instance of <see cref="ObjectContent{T}"/> as the content if a formatter can be found. If no formatter is
|
||||
/// found, this method returns a response with status 406 NotAcceptable.
|
||||
/// configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
|
|
@ -188,15 +208,18 @@ namespace System.Net.Http
|
|||
/// <param name="statusCode">The status code of the created response.</param>
|
||||
/// <param name="value">The value to wrap. Can be <c>null</c>.</param>
|
||||
/// <returns>A response wrapping <paramref name="value"/> with <paramref name="statusCode"/>.</returns>
|
||||
public static HttpResponseMessage CreateResponse<T>(this HttpRequestMessage request, HttpStatusCode statusCode, T value)
|
||||
public static HttpResponseMessage CreateResponse<T>(
|
||||
this HttpRequestMessage request,
|
||||
HttpStatusCode statusCode,
|
||||
T value)
|
||||
{
|
||||
return request.CreateResponse<T>(statusCode, value, formatters: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/> with an instance
|
||||
/// of <see cref="ObjectContent{T}"/> as the content if a formatter can be found. If no formatter is found, this
|
||||
/// method returns a response with status 406 NotAcceptable.
|
||||
/// Helper method that performs content negotiation and creates a <see cref="HttpResponseMessage"/> with an
|
||||
/// instance of <see cref="ObjectContent{T}"/> as the content if a formatter can be found. If no formatter is
|
||||
/// found, this method returns a response with status 406 NotAcceptable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method will use the provided <paramref name="configuration"/> or it will get the
|
||||
|
|
@ -238,29 +261,39 @@ namespace System.Net.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that creates a <see cref="HttpResponseMessage"/> with an <see cref="ObjectContent{T}"/> instance containing the provided
|
||||
/// <paramref name="value"/>. The given <paramref name="mediaType"/> is used to find an instance of <see cref="MediaTypeFormatter"/>.
|
||||
/// Helper method that creates a <see cref="HttpResponseMessage"/> with an <see cref="ObjectContent{T}"/>
|
||||
/// instance containing the provided <paramref name="value"/>. The given <paramref name="mediaType"/> is used
|
||||
/// to find an instance of <see cref="MediaTypeFormatter"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the value.</typeparam>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <param name="statusCode">The status code of the created response.</param>
|
||||
/// <param name="value">The value to wrap. Can be <c>null</c>.</param>
|
||||
/// <param name="mediaType">The media type used to look up an instance of <see cref="MediaTypeFormatter"/>.</param>
|
||||
/// <param name="mediaType">
|
||||
/// The media type used to look up an instance of <see cref="MediaTypeFormatter"/>.
|
||||
/// </param>
|
||||
/// <returns>A response wrapping <paramref name="value"/> with <paramref name="statusCode"/>.</returns>
|
||||
public static HttpResponseMessage CreateResponse<T>(this HttpRequestMessage request, HttpStatusCode statusCode, T value, string mediaType)
|
||||
public static HttpResponseMessage CreateResponse<T>(
|
||||
this HttpRequestMessage request,
|
||||
HttpStatusCode statusCode,
|
||||
T value,
|
||||
string mediaType)
|
||||
{
|
||||
return request.CreateResponse(statusCode, value, new MediaTypeHeaderValue(mediaType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that creates a <see cref="HttpResponseMessage"/> with an <see cref="ObjectContent{T}"/> instance containing the provided
|
||||
/// <paramref name="value"/>. The given <paramref name="mediaType"/> is used to find an instance of <see cref="MediaTypeFormatter"/>.
|
||||
/// Helper method that creates a <see cref="HttpResponseMessage"/> with an <see cref="ObjectContent{T}"/>
|
||||
/// instance containing the provided <paramref name="value"/>. The given <paramref name="mediaType"/> is used
|
||||
/// to find an instance of <see cref="MediaTypeFormatter"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the value.</typeparam>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <param name="statusCode">The status code of the created response.</param>
|
||||
/// <param name="value">The value to wrap. Can be <c>null</c>.</param>
|
||||
/// <param name="mediaType">The media type used to look up an instance of <see cref="MediaTypeFormatter"/>.</param>
|
||||
/// <param name="mediaType">
|
||||
/// The media type used to look up an instance of <see cref="MediaTypeFormatter"/>.
|
||||
/// </param>
|
||||
/// <returns>A response wrapping <paramref name="value"/> with <paramref name="statusCode"/>.</returns>
|
||||
public static HttpResponseMessage CreateResponse<T>(
|
||||
[NotNull] this HttpRequestMessage request,
|
||||
|
|
@ -287,8 +320,8 @@ namespace System.Net.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that creates a <see cref="HttpResponseMessage"/> with an <see cref="ObjectContent{T}"/> instance containing the provided
|
||||
/// <paramref name="value"/> and the given <paramref name="formatter"/>.
|
||||
/// Helper method that creates a <see cref="HttpResponseMessage"/> with an <see cref="ObjectContent{T}"/>
|
||||
/// instance containing the provided <paramref name="value"/> and the given <paramref name="formatter"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the value.</typeparam>
|
||||
/// <param name="request">The request.</param>
|
||||
|
|
@ -306,15 +339,17 @@ namespace System.Net.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that creates a <see cref="HttpResponseMessage"/> with an <see cref="ObjectContent{T}"/> instance containing the provided
|
||||
/// <paramref name="value"/> and the given <paramref name="formatter"/>.
|
||||
/// Helper method that creates a <see cref="HttpResponseMessage"/> with an <see cref="ObjectContent{T}"/>
|
||||
/// instance containing the provided <paramref name="value"/> and the given <paramref name="formatter"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the value.</typeparam>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <param name="statusCode">The status code of the created response.</param>
|
||||
/// <param name="value">The value to wrap. Can be <c>null</c>.</param>
|
||||
/// <param name="formatter">The formatter to use.</param>
|
||||
/// <param name="mediaType">The media type override to set on the response's content. Can be <c>null</c>.</param>
|
||||
/// <param name="mediaType">
|
||||
/// The media type override to set on the response's content. Can be <c>null</c>.
|
||||
/// </param>
|
||||
/// <returns>A response wrapping <paramref name="value"/> with <paramref name="statusCode"/>.</returns>
|
||||
public static HttpResponseMessage CreateResponse<T>(
|
||||
[NotNull] this HttpRequestMessage request,
|
||||
|
|
@ -328,15 +363,17 @@ namespace System.Net.Http
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that creates a <see cref="HttpResponseMessage"/> with an <see cref="ObjectContent{T}"/> instance containing the provided
|
||||
/// <paramref name="value"/> and the given <paramref name="formatter"/>.
|
||||
/// Helper method that creates a <see cref="HttpResponseMessage"/> with an <see cref="ObjectContent{T}"/>
|
||||
/// instance containing the provided <paramref name="value"/> and the given <paramref name="formatter"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the value.</typeparam>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <param name="statusCode">The status code of the created response.</param>
|
||||
/// <param name="value">The value to wrap. Can be <c>null</c>.</param>
|
||||
/// <param name="formatter">The formatter to use.</param>
|
||||
/// <param name="mediaType">The media type override to set on the response's content. Can be <c>null</c>.</param>
|
||||
/// <param name="mediaType">
|
||||
/// The media type override to set on the response's content. Can be <c>null</c>.
|
||||
/// </param>
|
||||
/// <returns>A response wrapping <paramref name="value"/> with <paramref name="statusCode"/>.</returns>
|
||||
public static HttpResponseMessage CreateResponse<T>(
|
||||
[NotNull] this HttpRequestMessage request,
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ using Microsoft.Framework.OptionsModel;
|
|||
|
||||
namespace Microsoft.AspNet.Mvc.WebApiCompatShim
|
||||
{
|
||||
public class WebApiCompatShimOptionsSetup : IConfigureOptions<MvcOptions>, IConfigureOptions<WebApiCompatShimOptions>
|
||||
public class WebApiCompatShimOptionsSetup
|
||||
: IConfigureOptions<MvcOptions>, IConfigureOptions<WebApiCompatShimOptions>
|
||||
{
|
||||
public readonly static string DefaultAreaName = "api";
|
||||
public static readonly string DefaultAreaName = "api";
|
||||
|
||||
public int Order
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
// 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 Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
|
||||
namespace Microsoft.Framework.Runtime
|
||||
{
|
||||
[AssemblyNeutral]
|
||||
public interface IAfterCompileContext
|
||||
{
|
||||
CSharpCompilation CSharpCompilation { get; set; }
|
||||
|
||||
IList<Diagnostic> Diagnostics { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.Framework.Runtime
|
||||
{
|
||||
[AssemblyNeutral]
|
||||
public interface ICompileModule
|
||||
{
|
||||
void BeforeCompile(IBeforeCompileContext context);
|
||||
|
||||
void AfterCompile(IAfterCompileContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -26,19 +26,19 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
var describe = new ServiceDescriber(configuration);
|
||||
|
||||
//
|
||||
// Options and core services.
|
||||
//
|
||||
|
||||
yield return describe.Transient<IConfigureOptions<MvcOptions>, MvcOptionsSetup>();
|
||||
yield return describe.Transient<IConfigureOptions<RazorViewEngineOptions>, RazorViewEngineOptionsSetup>();
|
||||
yield return describe.Transient<IAssemblyProvider, DefaultAssemblyProvider>();
|
||||
yield return describe.Transient(typeof(INestedProviderManager<>), typeof(NestedProviderManager<>));
|
||||
yield return describe.Transient(typeof(INestedProviderManagerAsync<>), typeof(NestedProviderManagerAsync<>));
|
||||
yield return describe.Transient(
|
||||
typeof(INestedProviderManagerAsync<>),
|
||||
typeof(NestedProviderManagerAsync<>));
|
||||
yield return describe.Transient<MvcMarkerService, MvcMarkerService>();
|
||||
|
||||
//
|
||||
// Core action discovery, filters and action execution.
|
||||
//
|
||||
|
||||
// These are consumed only when creating action descriptors, then they can be de-allocated
|
||||
yield return describe.Transient<IControllerModelBuilder, DefaultControllerModelBuilder>();
|
||||
yield return describe.Transient<IActionModelBuilder, DefaultActionModelBuilder>();
|
||||
|
|
@ -74,9 +74,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
yield return describe.Transient<INestedProvider<FilterProviderContext>, DefaultFilterProvider>();
|
||||
|
||||
//
|
||||
// Dataflow - ModelBinding, Validation and Formatting
|
||||
//
|
||||
|
||||
yield return describe.Transient<IModelMetadataProvider, DataAnnotationsModelMetadataProvider>();
|
||||
yield return describe.Scoped<IActionBindingContextProvider, DefaultActionBindingContextProvider>();
|
||||
|
||||
|
|
@ -93,11 +92,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
yield return describe.Transient<IModelValidatorProviderProvider, DefaultModelValidatorProviderProvider>();
|
||||
yield return describe.Scoped<ICompositeModelValidatorProvider, CompositeModelValidatorProvider>();
|
||||
yield return describe.Transient<IBodyModelValidator, DefaultBodyModelValidator>();
|
||||
yield return describe.Transient<IValidationExcludeFiltersProvider, DefaultValidationExcludeFiltersProvider>();
|
||||
yield return describe.Transient<IValidationExcludeFiltersProvider,
|
||||
DefaultValidationExcludeFiltersProvider>();
|
||||
|
||||
//
|
||||
// Razor, Views and runtime compilation
|
||||
//
|
||||
|
||||
// The provider is inexpensive to initialize and provides ViewEngines that may require request
|
||||
// specific services.
|
||||
|
|
@ -135,9 +133,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
// Virtual path view factory needs to stay scoped so views can get get scoped services.
|
||||
yield return describe.Scoped<IRazorPageFactory, VirtualPathRazorPageFactory>();
|
||||
|
||||
//
|
||||
// View and rendering helpers
|
||||
//
|
||||
|
||||
yield return describe.Transient<IHtmlHelper, HtmlHelper>();
|
||||
yield return describe.Transient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>));
|
||||
|
|
@ -157,9 +153,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
DefaultViewComponentInvokerProvider>();
|
||||
yield return describe.Transient<IViewComponentHelper, DefaultViewComponentHelper>();
|
||||
|
||||
//
|
||||
// Security and Authorization
|
||||
//
|
||||
|
||||
yield return describe.Transient<IAuthorizationService, DefaultAuthorizationService>();
|
||||
yield return describe.Singleton<IClaimUidExtractor, DefaultClaimUidExtractor>();
|
||||
|
|
@ -167,9 +161,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
yield return describe.Singleton<IAntiForgeryAdditionalDataProvider,
|
||||
DefaultAntiForgeryAdditionalDataProvider>();
|
||||
|
||||
//
|
||||
// Api Description
|
||||
//
|
||||
|
||||
yield return describe.Singleton<IApiDescriptionGroupCollectionProvider,
|
||||
ApiDescriptionGroupCollectionProvider>();
|
||||
|
|
|
|||
|
|
@ -48,7 +48,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
// TODO: KILL THIS
|
||||
private static IServiceProvider BuildFallbackServiceProvider(IEnumerable<IServiceDescriptor> services, IServiceProvider fallback)
|
||||
private static IServiceProvider BuildFallbackServiceProvider(
|
||||
IEnumerable<IServiceDescriptor> services,
|
||||
IServiceProvider fallback)
|
||||
{
|
||||
var sc = HostingServices.Create(fallback);
|
||||
sc.Add(services);
|
||||
|
|
@ -58,7 +60,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
&& t.ServiceType != typeof(IServiceManifest)
|
||||
&& t.ServiceType != typeof(IServiceProvider))
|
||||
.Select(t => t.ServiceType).Distinct();
|
||||
sc.AddInstance<IServiceManifest>(new ServiceManifest(manifestTypes, fallback.GetRequiredService<IServiceManifest>()));
|
||||
sc.AddInstance<IServiceManifest>(
|
||||
new ServiceManifest(manifestTypes, fallback.GetRequiredService<IServiceManifest>()));
|
||||
return sc.BuildServiceProvider();
|
||||
}
|
||||
|
||||
|
|
@ -77,22 +80,3 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Microsoft.Framework.Runtime
|
||||
{
|
||||
[AssemblyNeutral]
|
||||
public interface ICompileModule
|
||||
{
|
||||
void BeforeCompile(IBeforeCompileContext context);
|
||||
|
||||
void AfterCompile(IAfterCompileContext context);
|
||||
}
|
||||
|
||||
[AssemblyNeutral]
|
||||
public interface IAfterCompileContext
|
||||
{
|
||||
CSharpCompilation CSharpCompilation { get; set; }
|
||||
|
||||
IList<Diagnostic> Diagnostics { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -994,17 +994,16 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
// Assert
|
||||
binder.Verify();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task TryUpdateModel_PredicateOverload_UsesPassedArguments()
|
||||
{
|
||||
// Arrange
|
||||
var modelName = "mymodel";
|
||||
|
||||
Func<ModelBindingContext, string, bool> includePredicate =
|
||||
(context, propertyName) =>
|
||||
string.Equals(propertyName, "include1", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(propertyName, "include2", StringComparison.OrdinalIgnoreCase);
|
||||
Func<ModelBindingContext, string, bool> includePredicate = (context, propertyName) =>
|
||||
string.Equals(propertyName, "include1", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(propertyName, "include2", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
var binder = new Mock<IModelBinder>();
|
||||
var valueProvider = Mock.Of<IValueProvider>();
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var viewEngine = new Mock<IViewEngine>(MockBehavior.Strict);
|
||||
viewEngine.Setup(e => e.FindPartialView(It.IsAny<ActionContext>(), It.IsAny<string>()))
|
||||
.Returns(ViewEngineResult.NotFound(
|
||||
"Components/Object/some-view",
|
||||
"Components/Object/some-view",
|
||||
new[] { "view-location1", "view-location2" }))
|
||||
.Verifiable();
|
||||
|
||||
|
|
|
|||
|
|
@ -1056,7 +1056,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Assert
|
||||
var user = JsonConvert.DeserializeObject<User>(response);
|
||||
|
||||
// Should not update any not explicitly mentioned properties.
|
||||
// Should not update any not explicitly mentioned properties.
|
||||
Assert.NotEqual("SomeName", user.UserName);
|
||||
Assert.NotEqual(123, user.Key);
|
||||
|
||||
|
|
@ -1079,7 +1079,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Assert
|
||||
var user = JsonConvert.DeserializeObject<User>(response);
|
||||
|
||||
// Should not update any not explicitly mentioned properties.
|
||||
// Should not update any not explicitly mentioned properties.
|
||||
Assert.Equal("SomeName", user.UserName);
|
||||
Assert.Equal(123, user.Key);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,13 +10,20 @@ namespace System.Net.Http.Formatting
|
|||
/// </summary>
|
||||
internal static class MediaTypeConstants
|
||||
{
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationXmlMediaType = new MediaTypeHeaderValue("application/xml");
|
||||
private static readonly MediaTypeHeaderValue _defaultTextXmlMediaType = new MediaTypeHeaderValue("text/xml");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationJsonMediaType = new MediaTypeHeaderValue("application/json");
|
||||
private static readonly MediaTypeHeaderValue _defaultTextJsonMediaType = new MediaTypeHeaderValue("text/json");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationOctetStreamMediaType = new MediaTypeHeaderValue("application/octet-stream");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationFormUrlEncodedMediaType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationBsonMediaType = new MediaTypeHeaderValue("application/bson");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationXmlMediaType =
|
||||
new MediaTypeHeaderValue("application/xml");
|
||||
private static readonly MediaTypeHeaderValue _defaultTextXmlMediaType =
|
||||
new MediaTypeHeaderValue("text/xml");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationJsonMediaType =
|
||||
new MediaTypeHeaderValue("application/json");
|
||||
private static readonly MediaTypeHeaderValue _defaultTextJsonMediaType =
|
||||
new MediaTypeHeaderValue("text/json");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationOctetStreamMediaType =
|
||||
new MediaTypeHeaderValue("application/octet-stream");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationFormUrlEncodedMediaType =
|
||||
new MediaTypeHeaderValue("application/x-www-form-urlencoded");
|
||||
private static readonly MediaTypeHeaderValue _defaultApplicationBsonMediaType =
|
||||
new MediaTypeHeaderValue("application/bson");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="MediaTypeHeaderValue"/> instance representing <c>application/octet-stream</c>.
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace ModelBindingWebSite.Controllers
|
|||
}
|
||||
|
||||
// User_FromForm has a FromForm property.
|
||||
public User_FromForm MultipleFromFormParameterAndProperty(User_FromForm user,
|
||||
public User_FromForm MultipleFromFormParameterAndProperty(User_FromForm user,
|
||||
[FromForm] Address defaultAddress)
|
||||
{
|
||||
user.HomeAddress = defaultAddress;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace ModelBindingWebSite
|
|||
{
|
||||
public class Department
|
||||
{
|
||||
// A single property marked with a binder metadata attribute makes it a binder metadata poco.
|
||||
// A single property marked with a binder metadata attribute makes it a binder metadata poco.
|
||||
[FromTest]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace ModelBindingWebSite
|
|||
[FromQuery]
|
||||
public Address ShippingAddress { get; set; }
|
||||
|
||||
// Should get it from the first value provider which
|
||||
// Should get it from the first value provider which
|
||||
// can provide values for this.
|
||||
public Address DefaultAddress { get; set; }
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue