Add some reference docs for MVC (#7981)

This commit is contained in:
Pranav K 2019-02-28 09:56:55 -08:00 committed by GitHub
parent 3d2946060f
commit f79f2e3b12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 554 additions and 19 deletions

View File

@ -9,8 +9,14 @@ using Microsoft.AspNetCore.Mvc.Routing;
namespace Microsoft.AspNetCore.Mvc.Abstractions namespace Microsoft.AspNetCore.Mvc.Abstractions
{ {
/// <summary>
/// Describes a MVC action.
/// </summary>
public class ActionDescriptor public class ActionDescriptor
{ {
/// <summary>
/// Initializes a new instance of <see cref="ActionDescriptor"/>.
/// </summary>
public ActionDescriptor() public ActionDescriptor()
{ {
Id = Guid.NewGuid().ToString(); Id = Guid.NewGuid().ToString();
@ -29,6 +35,9 @@ namespace Microsoft.AspNetCore.Mvc.Abstractions
/// </summary> /// </summary>
public IDictionary<string, string> RouteValues { get; set; } public IDictionary<string, string> RouteValues { get; set; }
/// <summary>
/// Gets or sets the <see cref="Routing.AttributeRouteInfo"/>.
/// </summary>
public AttributeRouteInfo AttributeRouteInfo { get; set; } public AttributeRouteInfo AttributeRouteInfo { get; set; }
/// <summary> /// <summary>

View File

@ -5,8 +5,15 @@ using System.Collections.Generic;
namespace Microsoft.AspNetCore.Mvc.Abstractions namespace Microsoft.AspNetCore.Mvc.Abstractions
{ {
/// <summary>
/// A context for <see cref="IActionDescriptorProvider"/>.
/// </summary>
public class ActionDescriptorProviderContext public class ActionDescriptorProviderContext
{ {
/// <summary>
/// Gets the <see cref="IList{T}" /> of <see cref="ActionDescriptor"/> instances of <see cref="IActionDescriptorProvider"/>
/// can populate.
/// </summary>
public IList<ActionDescriptor> Results { get; } = new List<ActionDescriptor>(); public IList<ActionDescriptor> Results { get; } = new List<ActionDescriptor>();
} }
} }

View File

@ -5,8 +5,15 @@ using System;
namespace Microsoft.AspNetCore.Mvc.Abstractions namespace Microsoft.AspNetCore.Mvc.Abstractions
{ {
/// <summary>
/// A context for <see cref="IActionInvokerProvider"/>.
/// </summary>
public class ActionInvokerProviderContext public class ActionInvokerProviderContext
{ {
/// <summary>
/// Initializes a new instance of <see cref="ActionInvokerProviderContext"/>.
/// </summary>
/// <param name="actionContext">The <see cref="Mvc.ActionContext"/> to invoke.</param>
public ActionInvokerProviderContext(ActionContext actionContext) public ActionInvokerProviderContext(ActionContext actionContext)
{ {
if (actionContext == null) if (actionContext == null)
@ -17,8 +24,14 @@ namespace Microsoft.AspNetCore.Mvc.Abstractions
ActionContext = actionContext; ActionContext = actionContext;
} }
/// <summary>
/// Gets the <see cref="Mvc.ActionContext"/> to invoke.
/// </summary>
public ActionContext ActionContext { get; } public ActionContext ActionContext { get; }
/// <summary>
/// Gets or sets the <see cref="IActionInvoker"/> that will be used to invoke <see cref="ActionContext" />
/// </summary>
public IActionInvoker Result { get; set; } public IActionInvoker Result { get; set; }
} }
} }

View File

@ -3,6 +3,26 @@
namespace Microsoft.AspNetCore.Mvc.Abstractions namespace Microsoft.AspNetCore.Mvc.Abstractions
{ {
/// <summary>
/// Defines a contract for specifying <see cref="ActionDescriptor"/> instances.
/// </summary>
/// <remarks>
/// <para>
/// On application initialization, MVC invokes all registered instances of <see cref="IActionDescriptorProvider"/> to
/// perform <see cref="ActionDescriptor" /> discovery.
/// <see cref="IActionDescriptorProvider"/> instances are invoked in the ascending sort order of <see cref="Order"/>.
/// </para>
/// <para>
/// Each provider has its <see cref="OnProvidersExecuting"/> method
/// called in sequence and given the same instance of <see cref="ActionInvokerProviderContext"/>. Then each
/// provider has its <see cref="OnProvidersExecuted"/> method called in the reverse order. Each instance has
/// an opportunity to add or modify <see cref="ActionDescriptorProviderContext.Results"/>.
/// </para>
/// <para>
/// As providers are called in a predefined sequence, each provider has a chance to observe and decorate the
/// result of the providers that have already run.
/// </para>
/// </remarks>
public interface IActionDescriptorProvider public interface IActionDescriptorProvider
{ {
/// <summary> /// <summary>
@ -26,8 +46,19 @@ namespace Microsoft.AspNetCore.Mvc.Abstractions
/// </remarks> /// </remarks>
int Order { get; } int Order { get; }
/// <summary>
/// Called to execute the provider.
/// <see cref="Order"/> for details on the order of execution of <see cref="OnProvidersExecuting(ActionDescriptorProviderContext)"/>.
/// </summary>
/// <param name="context">The <see cref="ActionDescriptorProviderContext"/>.</param>
void OnProvidersExecuting(ActionDescriptorProviderContext context); void OnProvidersExecuting(ActionDescriptorProviderContext context);
/// <summary>
/// Called to execute the provider, after the <see cref="OnProvidersExecuting"/> methods of all providers,
/// have been called.
/// <see cref="Order"/> for details on the order of execution of <see cref="OnProvidersExecuted(ActionDescriptorProviderContext)"/>.
/// </summary>
/// <param name="context">The <see cref="ActionDescriptorProviderContext"/>.</param>
void OnProvidersExecuted(ActionDescriptorProviderContext context); void OnProvidersExecuted(ActionDescriptorProviderContext context);
} }
} }

View File

@ -6,12 +6,24 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace Microsoft.AspNetCore.Mvc.Abstractions namespace Microsoft.AspNetCore.Mvc.Abstractions
{ {
/// <summary>
/// Describes a parameter in an action.
/// </summary>
public class ParameterDescriptor public class ParameterDescriptor
{ {
/// <summary>
/// Gets or sets the parameter name.
/// </summary>
public string Name { get; set; } public string Name { get; set; }
/// <summary>
/// Gets or sets the type of the parameter.
/// </summary>
public Type ParameterType { get; set; } public Type ParameterType { get; set; }
/// <summary>
/// Gets or sets the <see cref="ModelBinding.BindingInfo"/> for the parameter.
/// </summary>
public BindingInfo BindingInfo { get; set; } public BindingInfo BindingInfo { get; set; }
} }
} }

View File

@ -3,6 +3,9 @@
namespace Microsoft.AspNetCore.Mvc.ActionConstraints namespace Microsoft.AspNetCore.Mvc.ActionConstraints
{ {
/// <summary>
/// Provider for <see cref="IActionConstraint"/>.
/// </summary>
public interface IActionConstraintProvider public interface IActionConstraintProvider
{ {
/// <summary> /// <summary>
@ -26,8 +29,19 @@ namespace Microsoft.AspNetCore.Mvc.ActionConstraints
/// </remarks> /// </remarks>
int Order { get; } int Order { get; }
/// <summary>
/// Called to execute the provider.
/// <see cref="Order"/> for details on the order of execution of <see cref="OnProvidersExecuting(ActionConstraintProviderContext)"/>.
/// </summary>
/// <param name="context">The <see cref="ActionConstraintProviderContext"/>.</param>
void OnProvidersExecuting(ActionConstraintProviderContext context); void OnProvidersExecuting(ActionConstraintProviderContext context);
/// <summary>
/// Called to execute the provider, after the <see cref="OnProvidersExecuting"/> methods of all providers,
/// have been called.
/// <see cref="Order"/> for details on the order of execution of <see cref="OnProvidersExecuted(ActionConstraintProviderContext)"/>.
/// </summary>
/// <param name="context">The <see cref="ActionConstraintProviderContext"/>.</param>
void OnProvidersExecuted(ActionConstraintProviderContext context); void OnProvidersExecuted(ActionConstraintProviderContext context);
} }
} }

View File

@ -1,8 +1,29 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Mvc.Abstractions;
namespace Microsoft.AspNetCore.Mvc.ApiExplorer namespace Microsoft.AspNetCore.Mvc.ApiExplorer
{ {
/// <summary>
/// Defines a contract for specifying <see cref="ApiDescription"/> instances.
/// </summary>
/// <remarks>
/// <para>
/// On the first query for <see cref="ActionDescriptor"/>, MVC invokes all registered instances of <see cref="IApiDescriptionProvider"/>
/// in the ascending sort order of <see cref="Order"/>.
/// </para>
/// <para>
/// Each provider has its <see cref="OnProvidersExecuting"/> method
/// called in sequence and given the same instance of <see cref="ApiDescriptionProviderContext"/>. Then each
/// provider has its <see cref="OnProvidersExecuted"/> method called in the reverse order. Each instance has
/// an opportunity to add or modify <see cref="ApiDescriptionProviderContext.Results"/>.
/// </para>
/// <para>
/// As providers are called in a predefined sequence, each provider has a chance to observe and decorate the
/// result of the providers that have already run.
/// </para>
/// </remarks>
public interface IApiDescriptionProvider public interface IApiDescriptionProvider
{ {
/// <summary> /// <summary>

View File

@ -10,15 +10,28 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
/// </summary> /// </summary>
public class InputFormatterException : Exception public class InputFormatterException : Exception
{ {
/// <summary>
/// Initializes a new instance of <see cref="InputFormatterException"/>.
/// </summary>
public InputFormatterException() public InputFormatterException()
{ {
} }
/// <summary>
/// Initializes a new instance of <see cref="InputFormatterException"/> with the specified <paramref name="message"/>.
/// </summary>
/// <param name="message">The exception message.</param>
public InputFormatterException(string message) public InputFormatterException(string message)
: base(message) : base(message)
{ {
} }
/// <summary>
/// Initializes a new instance of <see cref="InputFormatterException"/> with the specified <paramref name="message"/> and
/// inner exception that is the cause of this exception.
/// </summary>
/// <param name="message">The exception message.</param>
/// <param name="innerException">The exception that is the cause of the current exception.</param>
public InputFormatterException(string message, Exception innerException) public InputFormatterException(string message, Exception innerException)
: base(message, innerException) : base(message, innerException)
{ {

View File

@ -6,7 +6,6 @@ Commonly used types:
Microsoft.AspNetCore.Mvc.IActionResult</Description> Microsoft.AspNetCore.Mvc.IActionResult</Description>
<TargetFramework>netcoreapp3.0</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<IsAspNetCoreApp>true</IsAspNetCoreApp> <IsAspNetCoreApp>true</IsAspNetCoreApp>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;aspnetcoremvc</PackageTags> <PackageTags>aspnetcore;aspnetcoremvc</PackageTags>
</PropertyGroup> </PropertyGroup>

View File

@ -6,10 +6,26 @@ using System.Collections.Generic;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
/// <summary>
/// A provider that can supply instances of <see cref="ModelMetadata"/>.
/// </summary>
/// <remarks>
/// While not obsolete, implementing or using <see cref="ModelMetadataProvider" /> is preferred over <see cref="IModelMetadataProvider"/>.
/// </remarks>
public interface IModelMetadataProvider public interface IModelMetadataProvider
{ {
/// <summary>
/// Supplies metadata describing a <see cref="Type"/>.
/// </summary>
/// <param name="modelType">The <see cref="Type"/>.</param>
/// <returns>A <see cref="ModelMetadata"/> instance describing the <see cref="Type"/>.</returns>
ModelMetadata GetMetadataForType(Type modelType); ModelMetadata GetMetadataForType(Type modelType);
/// <summary>
/// Supplies metadata describing the properties of a <see cref="Type"/>.
/// </summary>
/// <param name="modelType">The <see cref="Type"/>.</param>
/// <returns>A set of <see cref="ModelMetadata"/> instances describing properties of the <see cref="Type"/>.</returns>
IEnumerable<ModelMetadata> GetMetadataForProperties(Type modelType); IEnumerable<ModelMetadata> GetMetadataForProperties(Type modelType);
} }
} }

View File

@ -5,35 +5,49 @@ using System;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
/// <summary>
/// An error that occured during model binding and validation.
/// </summary>
public class ModelError public class ModelError
{ {
/// <summary>
/// Intiializes a new instance of <see cref="ModelError"/> with the specified <paramref name="exception"/>.
/// </summary>
/// <param name="exception">The <see cref="System.Exception"/>.</param>
public ModelError(Exception exception) public ModelError(Exception exception)
: this(exception, errorMessage: null) : this(exception, errorMessage: null)
{ {
if (exception == null)
{
throw new ArgumentNullException(nameof(exception));
}
} }
/// <summary>
/// Intiializes a new instance of <see cref="ModelError"/> with the specified <paramref name="exception"/>
/// and specified <paramref name="errorMessage"/>.
/// </summary>
/// <param name="exception">The <see cref="System.Exception"/>.</param>
/// <param name="errorMessage">The error message.</param>
public ModelError(Exception exception, string errorMessage) public ModelError(Exception exception, string errorMessage)
: this(errorMessage) : this(errorMessage)
{ {
if (exception == null) Exception = exception ?? throw new ArgumentNullException(nameof(exception));
{
throw new ArgumentNullException(nameof(exception));
}
Exception = exception;
} }
/// <summary>
/// Initializes a new instance of <see cref="ModelError"/> with the specified <paramref name="errorMessage"/>.
/// </summary>
/// <param name="errorMessage">The error message.</param>
public ModelError(string errorMessage) public ModelError(string errorMessage)
{ {
ErrorMessage = errorMessage ?? string.Empty; ErrorMessage = errorMessage ?? string.Empty;
} }
/// <summary>
/// Gets the <see cref="System.Exception"/> associated with this <see cref="ModelError"/> instance.
/// </summary>
public Exception Exception { get; } public Exception Exception { get; }
/// <summary>
/// Gets the error message associated with this <see cref="ModelError"/> instance.
/// </summary>
public string ErrorMessage { get; } public string ErrorMessage { get; }
} }
} }

View File

@ -6,8 +6,15 @@ using System.Collections.ObjectModel;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
/// <summary>
/// A collection of <see cref="ModelError"/> instances.
/// </summary>
public class ModelErrorCollection : Collection<ModelError> public class ModelErrorCollection : Collection<ModelError>
{ {
/// <summary>
/// Adds the specified <paramref name="exception"/> instance.
/// </summary>
/// <param name="exception">The <see cref="Exception"/></param>
public void Add(Exception exception) public void Add(Exception exception)
{ {
if (exception == null) if (exception == null)
@ -18,6 +25,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
Add(new ModelError(exception)); Add(new ModelError(exception));
} }
/// <summary>
/// Adds the specified error message.
/// </summary>
/// <param name="errorMessage">The error message.</param>
public void Add(string errorMessage) public void Add(string errorMessage)
{ {
if (errorMessage == null) if (errorMessage == null)

View File

@ -797,6 +797,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
/// <inheritdoc /> /// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
/// <summary>
/// <para>
/// This API supports the MVC's infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </para>
/// </summary>
public static bool StartsWithPrefix(string prefix, string key) public static bool StartsWithPrefix(string prefix, string key)
{ {
if (prefix == null) if (prefix == null)
@ -840,6 +846,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
return false; return false;
} }
/// <summary>
/// Gets a <see cref="PrefixEnumerable"/> that iterates over this instance of <see cref="ModelStateDictionary"/>
/// using the specified <paramref name="prefix"/>.
/// </summary>
/// <param name="prefix">The prefix.</param>
/// <returns>The <see cref="PrefixEnumerable"/>.</returns>
public PrefixEnumerable FindKeysWithPrefix(string prefix) public PrefixEnumerable FindKeysWithPrefix(string prefix)
{ {
if (prefix == null) if (prefix == null)
@ -1004,11 +1016,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
} }
} }
/// <summary>
/// Enumerates over <see cref="ModelStateDictionary"/> to provide entries that start with the
/// specified prefix.
/// </summary>
public readonly struct PrefixEnumerable : IEnumerable<KeyValuePair<string, ModelStateEntry>> public readonly struct PrefixEnumerable : IEnumerable<KeyValuePair<string, ModelStateEntry>>
{ {
private readonly ModelStateDictionary _dictionary; private readonly ModelStateDictionary _dictionary;
private readonly string _prefix; private readonly string _prefix;
/// <summary>
/// Initializes a new instance of <see cref="PrefixEnumerable"/>.
/// </summary>
/// <param name="dictionary">The <see cref="ModelStateDictionary"/>.</param>
/// <param name="prefix">The prefix.</param>
public PrefixEnumerable(ModelStateDictionary dictionary, string prefix) public PrefixEnumerable(ModelStateDictionary dictionary, string prefix)
{ {
if (dictionary == null) if (dictionary == null)
@ -1025,6 +1046,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
_prefix = prefix; _prefix = prefix;
} }
/// <inheritdoc />
public Enumerator GetEnumerator() => new Enumerator(_dictionary, _prefix); public Enumerator GetEnumerator() => new Enumerator(_dictionary, _prefix);
IEnumerator<KeyValuePair<string, ModelStateEntry>> IEnumerator<KeyValuePair<string, ModelStateEntry>>
@ -1033,6 +1055,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
} }
/// <summary>
/// An <see cref="IEnumerator{T}"/> for <see cref="PrefixEnumerable"/>.
/// </summary>
public struct Enumerator : IEnumerator<KeyValuePair<string, ModelStateEntry>> public struct Enumerator : IEnumerator<KeyValuePair<string, ModelStateEntry>>
{ {
private readonly ModelStateNode _rootNode; private readonly ModelStateNode _rootNode;
@ -1041,6 +1066,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
private int _index; private int _index;
private bool _visitedRoot; private bool _visitedRoot;
/// <summary>
/// Intializes a new instance of <see cref="Enumerator"/>.
/// </summary>
/// <param name="dictionary">The <see cref="ModelStateDictionary"/>.</param>
/// <param name="prefix">The prefix.</param>
public Enumerator(ModelStateDictionary dictionary, string prefix) public Enumerator(ModelStateDictionary dictionary, string prefix)
{ {
if (dictionary == null) if (dictionary == null)
@ -1060,15 +1090,18 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
_visitedRoot = false; _visitedRoot = false;
} }
/// <inheritdoc />
public KeyValuePair<string, ModelStateEntry> Current => public KeyValuePair<string, ModelStateEntry> Current =>
new KeyValuePair<string, ModelStateEntry>(_modelStateNode.Key, _modelStateNode); new KeyValuePair<string, ModelStateEntry>(_modelStateNode.Key, _modelStateNode);
object IEnumerator.Current => Current; object IEnumerator.Current => Current;
/// <inheritdoc />
public void Dispose() public void Dispose()
{ {
} }
/// <inheritdoc />
public bool MoveNext() public bool MoveNext()
{ {
if (_rootNode == null) if (_rootNode == null)
@ -1128,6 +1161,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
return false; return false;
} }
/// <inheritdoc />
public void Reset() public void Reset()
{ {
_index = -1; _index = -1;
@ -1137,15 +1171,23 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
} }
} }
/// <summary>
/// A <see cref="IEnumerable{T}"/> for keys in <see cref="ModelStateDictionary"/>.
/// </summary>
public readonly struct KeyEnumerable : IEnumerable<string> public readonly struct KeyEnumerable : IEnumerable<string>
{ {
private readonly ModelStateDictionary _dictionary; private readonly ModelStateDictionary _dictionary;
/// <summary>
/// Initializes a new instance of <see cref="KeyEnumerable"/>.
/// </summary>
/// <param name="dictionary">The <see cref="ModelStateDictionary"/>.</param>
public KeyEnumerable(ModelStateDictionary dictionary) public KeyEnumerable(ModelStateDictionary dictionary)
{ {
_dictionary = dictionary; _dictionary = dictionary;
} }
/// <inheritdoc />
public KeyEnumerator GetEnumerator() => new KeyEnumerator(_dictionary, prefix: string.Empty); public KeyEnumerator GetEnumerator() => new KeyEnumerator(_dictionary, prefix: string.Empty);
IEnumerator<string> IEnumerable<string>.GetEnumerator() => GetEnumerator(); IEnumerator<string> IEnumerable<string>.GetEnumerator() => GetEnumerator();
@ -1153,22 +1195,33 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
} }
/// <summary>
/// An <see cref="IEnumerator{T}"/> for keys in <see cref="ModelStateDictionary"/>.
/// </summary>
public struct KeyEnumerator : IEnumerator<string> public struct KeyEnumerator : IEnumerator<string>
{ {
private Enumerator _prefixEnumerator; private Enumerator _prefixEnumerator;
/// <summary>
/// Initializes a new instance of <see cref="KeyEnumerable"/>.
/// </summary>
/// <param name="dictionary">The <see cref="ModelStateDictionary"/>.</param>
/// <param name="prefix">The prefix.</param>
public KeyEnumerator(ModelStateDictionary dictionary, string prefix) public KeyEnumerator(ModelStateDictionary dictionary, string prefix)
{ {
_prefixEnumerator = new Enumerator(dictionary, prefix); _prefixEnumerator = new Enumerator(dictionary, prefix);
Current = null; Current = null;
} }
/// <inheritdoc />
public string Current { get; private set; } public string Current { get; private set; }
object IEnumerator.Current => Current; object IEnumerator.Current => Current;
/// <inheritdoc />
public void Dispose() => _prefixEnumerator.Dispose(); public void Dispose() => _prefixEnumerator.Dispose();
/// <inheritdoc />
public bool MoveNext() public bool MoveNext()
{ {
var result = _prefixEnumerator.MoveNext(); var result = _prefixEnumerator.MoveNext();
@ -1185,6 +1238,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
return result; return result;
} }
/// <inheritdoc />
public void Reset() public void Reset()
{ {
_prefixEnumerator.Reset(); _prefixEnumerator.Reset();
@ -1192,15 +1246,23 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
} }
} }
/// <summary>
/// An <see cref="IEnumerable"/> for <see cref="ModelStateEntry"/>.
/// </summary>
public readonly struct ValueEnumerable : IEnumerable<ModelStateEntry> public readonly struct ValueEnumerable : IEnumerable<ModelStateEntry>
{ {
private readonly ModelStateDictionary _dictionary; private readonly ModelStateDictionary _dictionary;
/// <summary>
/// Initializes a new instance of <see cref="ValueEnumerable"/>.
/// </summary>
/// <param name="dictionary">The <see cref="ModelStateDictionary"/>.</param>
public ValueEnumerable(ModelStateDictionary dictionary) public ValueEnumerable(ModelStateDictionary dictionary)
{ {
_dictionary = dictionary; _dictionary = dictionary;
} }
/// <inheritdoc />
public ValueEnumerator GetEnumerator() => new ValueEnumerator(_dictionary, prefix: string.Empty); public ValueEnumerator GetEnumerator() => new ValueEnumerator(_dictionary, prefix: string.Empty);
IEnumerator<ModelStateEntry> IEnumerable<ModelStateEntry>.GetEnumerator() => GetEnumerator(); IEnumerator<ModelStateEntry> IEnumerable<ModelStateEntry>.GetEnumerator() => GetEnumerator();
@ -1208,22 +1270,33 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
} }
/// <summary>
/// An enumerator for <see cref="ModelStateEntry"/>.
/// </summary>
public struct ValueEnumerator : IEnumerator<ModelStateEntry> public struct ValueEnumerator : IEnumerator<ModelStateEntry>
{ {
private Enumerator _prefixEnumerator; private Enumerator _prefixEnumerator;
/// <summary>
/// Initializes a new instance of <see cref="ValueEnumerator"/>.
/// </summary>
/// <param name="dictionary">The <see cref="ModelStateDictionary"/>.</param>
/// <param name="prefix">The prefix to enumerate.</param>
public ValueEnumerator(ModelStateDictionary dictionary, string prefix) public ValueEnumerator(ModelStateDictionary dictionary, string prefix)
{ {
_prefixEnumerator = new Enumerator(dictionary, prefix); _prefixEnumerator = new Enumerator(dictionary, prefix);
Current = null; Current = null;
} }
/// <inheritdoc />
public ModelStateEntry Current { get; private set; } public ModelStateEntry Current { get; private set; }
object IEnumerator.Current => Current; object IEnumerator.Current => Current;
/// <inheritdoc />
public void Dispose() => _prefixEnumerator.Dispose(); public void Dispose() => _prefixEnumerator.Dispose();
/// <inheritdoc />
public bool MoveNext() public bool MoveNext()
{ {
var result = _prefixEnumerator.MoveNext(); var result = _prefixEnumerator.MoveNext();
@ -1240,6 +1313,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
return result; return result;
} }
/// <inheritdoc />
public void Reset() public void Reset()
{ {
_prefixEnumerator.Reset(); _prefixEnumerator.Reset();

View File

@ -3,11 +3,50 @@
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
/// <summary>
/// The validation state of a <see cref="ModelStateEntry"/> instance.
/// <para>
/// <see cref="ModelValidationState"/> of <see cref="ModelStateDictionary.Root"/> is used to determine the validity
/// of <see cref="ModelStateDictionary"/>. <see cref="ModelStateDictionary.IsValid"/> is <see langword="true" />, when
/// the aggregate validity (<see cref="ModelStateDictionary.GetFieldValidationState(string)"/>)
/// of the root node is <see cref="Valid"/>.
/// </para>
/// </summary>
public enum ModelValidationState public enum ModelValidationState
{ {
/// <summary>
/// Validation has not been performed on the <see cref="ModelStateEntry"/>.
/// <para>
/// For aggregate validity, the validation of a <see cref="ModelStateEntry"/> is <see cref="Unvalidated"/>
/// if either the entry or one of thedescendants is <see cref="Unvalidated"/>.
/// </para>
/// </summary>
Unvalidated, Unvalidated,
/// <summary>
/// Validation was performed on the <see cref="ModelStateEntry"/> and was found to be invalid.
/// <para>
/// For aggregate validity, the validation of a <see cref="ModelStateEntry"/> is <see cref="Invalid"/>
/// if either the entry or one of the descendants is <see cref="Invalid"/> and none are <see cref="Unvalidated"/>.
/// </para>
/// </summary>
Invalid, Invalid,
/// <summary>
/// Validation was performed on the <see cref="ModelStateEntry"/>
/// <para>
/// For aggregate validity, the validation of a <see cref="ModelStateEntry"/> is <see cref="Valid"/>
/// if the validity of the entry and all descendants is either <see cref="Valid"/> or <see cref="Skipped"/>.
/// </para>
/// </summary>
Valid, Valid,
/// <summary>
/// Validation was skipped for the <see cref="ModelStateEntry"/>.
/// <para>
/// The aggregate validity of an entry is never <see cref="Skipped"/>.
/// </para>
/// </summary>
Skipped Skipped
} }
} }

View File

@ -3,8 +3,20 @@
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation
{ {
/// <summary>
/// Specifies the contract for performing validation in the browser.
/// <para>
/// MVC's validation system invokes <see cref="IClientModelValidator"/> to gather attributes that apply to the
/// rendered HTML. The rendered view may have to reference JavaScript libraries, such as jQuery Unobtrusive Validation,
/// to provide client validation based on the presence of these attributes.
/// </para>
/// </summary>
public interface IClientModelValidator public interface IClientModelValidator
{ {
/// <summary>
/// Called to add client-side model validation.
/// </summary>
/// <param name="context">The <see cref="ClientModelValidationContext"/>.</param>
void AddValidation(ClientModelValidationContext context); void AddValidation(ClientModelValidationContext context);
} }
} }

View File

@ -3,16 +3,30 @@
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation
{ {
/// <summary>
/// The result of model validation.
/// </summary>
public class ModelValidationResult public class ModelValidationResult
{ {
/// <summary>
/// Initializes a new instance of <see cref="ModelValidationResult"/>.
/// </summary>
/// <param name="memberName">The name of the entry on which validation was performed.</param>
/// <param name="message">The validation message.</param>
public ModelValidationResult(string memberName, string message) public ModelValidationResult(string memberName, string message)
{ {
MemberName = memberName ?? string.Empty; MemberName = memberName ?? string.Empty;
Message = message ?? string.Empty; Message = message ?? string.Empty;
} }
/// <summary>
/// Gets the name of the entry on which validation was performed.
/// </summary>
public string MemberName { get; } public string MemberName { get; }
/// <summary>
/// Gets the validation message.
/// </summary>
public string Message { get; } public string Message { get; }
} }
} }

View File

@ -483,6 +483,52 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
Assert.Equal(ModelValidationState.Valid, validationState); Assert.Equal(ModelValidationState.Valid, validationState);
} }
[Fact]
public void GetFieldValidationState_OfSkippedEntry()
{
// Arrange
var modelState = new ModelStateDictionary();
modelState.MarkFieldSkipped("foo");
// Act
var validationState = modelState.GetValidationState("foo");
var fieldValidationState = modelState.GetFieldValidationState("foo");
// Assert
Assert.Equal(ModelValidationState.Skipped, validationState);
Assert.Equal(ModelValidationState.Valid, fieldValidationState);
}
[Fact]
public void GetFieldValidationState_WithSkippedProperty()
{
// Arrange
var modelState = new ModelStateDictionary();
modelState.MarkFieldSkipped("foo.bar.prop1");
modelState.MarkFieldValid("foo.bar.prop2");
// Act
var validationState = modelState.GetFieldValidationState("foo.bar");
// Assert
Assert.Equal(ModelValidationState.Valid, validationState);
}
[Fact]
public void GetFieldValidationState_WithAllSkippedProperties()
{
// Arrange
var modelState = new ModelStateDictionary();
modelState.MarkFieldSkipped("foo.bar.prop1");
modelState.MarkFieldSkipped("foo.bar.prop2");
// Act
var validationState = modelState.GetFieldValidationState("foo.bar");
// Assert
Assert.Equal(ModelValidationState.Valid, validationState);
}
[Fact] [Fact]
public void IsValidPropertyReturnsFalse_IfSomeFieldsAreNotValidated() public void IsValidPropertyReturnsFalse_IfSomeFieldsAreNotValidated()
{ {

View File

@ -83,6 +83,7 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer
} }
} }
/// <inheritdoc />
public void OnProvidersExecuted(ApiDescriptionProviderContext context) public void OnProvidersExecuted(ApiDescriptionProviderContext context)
{ {
} }

View File

@ -7,8 +7,16 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Microsoft.Extensions.DependencyInjection namespace Microsoft.Extensions.DependencyInjection
{ {
/// <summary>
/// Extensions for configuring ApiExplorer using an <see cref="IMvcCoreBuilder"/>.
/// </summary>
public static class MvcApiExplorerMvcCoreBuilderExtensions public static class MvcApiExplorerMvcCoreBuilderExtensions
{ {
/// <summary>
/// Configures <see cref="IMvcCoreBuilder"/> to use ApiExplorer.
/// </summary>
/// <param name="builder">The <see cref="IMvcCoreBuilder"/>.</param>
/// <returns>The <see cref="IMvcCoreBuilder"/>.</returns>
public static IMvcCoreBuilder AddApiExplorer(this IMvcCoreBuilder builder) public static IMvcCoreBuilder AddApiExplorer(this IMvcCoreBuilder builder)
{ {
if (builder == null) if (builder == null)

View File

@ -4,7 +4,6 @@
<Description>ASP.NET Core MVC API explorer functionality for discovering metadata such as the list of controllers and actions, and their URLs and allowed HTTP methods.</Description> <Description>ASP.NET Core MVC API explorer functionality for discovering metadata such as the list of controllers and actions, and their URLs and allowed HTTP methods.</Description>
<TargetFramework>netcoreapp3.0</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<IsAspNetCoreApp>true</IsAspNetCoreApp> <IsAspNetCoreApp>true</IsAspNetCoreApp>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;aspnetcoremvc</PackageTags> <PackageTags>aspnetcore;aspnetcoremvc</PackageTags>
</PropertyGroup> </PropertyGroup>

View File

@ -53,11 +53,19 @@ namespace Microsoft.AspNetCore.Mvc
/// </summary> /// </summary>
public TValue Value { get; } public TValue Value { get; }
/// <summary>
/// Implictly converts the specified <paramref name="value"/> to an <see cref="ActionResult{TValue}"/>.
/// </summary>
/// <param name="value">The value to convert.</param>
public static implicit operator ActionResult<TValue>(TValue value) public static implicit operator ActionResult<TValue>(TValue value)
{ {
return new ActionResult<TValue>(value); return new ActionResult<TValue>(value);
} }
/// <summary>
/// Implictly converts the specified <paramref name="result"/> to an <see cref="ActionResult{TValue}"/>.
/// </summary>
/// <param name="result">The <see cref="ActionResult"/>.</param>
public static implicit operator ActionResult<TValue>(ActionResult result) public static implicit operator ActionResult<TValue>(ActionResult result)
{ {
return new ActionResult<TValue>(result); return new ActionResult<TValue>(result);

View File

@ -13,12 +13,19 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer
/// </summary> /// </summary>
public sealed class ApiConventionResult public sealed class ApiConventionResult
{ {
/// <summary>
/// Initializes a new instance of <see cref="ApiConventionResult"/>.
/// </summary>
/// <param name="responseMetadataProviders">The sequence of <see cref="IApiResponseMetadataProvider"/> that are associated with the action.</param>
public ApiConventionResult(IReadOnlyList<IApiResponseMetadataProvider> responseMetadataProviders) public ApiConventionResult(IReadOnlyList<IApiResponseMetadataProvider> responseMetadataProviders)
{ {
ResponseMetadataProviders = responseMetadataProviders ?? ResponseMetadataProviders = responseMetadataProviders ??
throw new ArgumentNullException(nameof(responseMetadataProviders)); throw new ArgumentNullException(nameof(responseMetadataProviders));
} }
/// <summary>
/// Gets the sequence of <see cref="IApiResponseMetadataProvider"/> that are associated with the action.
/// </summary>
public IReadOnlyList<IApiResponseMetadataProvider> ResponseMetadataProviders { get; } public IReadOnlyList<IApiResponseMetadataProvider> ResponseMetadataProviders { get; }
internal static bool TryGetApiConvention( internal static bool TryGetApiConvention(

View File

@ -17,11 +17,18 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
public sealed class ApiConventionTypeMatchAttribute : Attribute public sealed class ApiConventionTypeMatchAttribute : Attribute
{ {
/// <summary>
/// Initialzes a new instance of <see cref="ApiConventionTypeMatchAttribute"/> with the specified <paramref name="matchBehavior"/>.
/// </summary>
/// <param name="matchBehavior">The <see cref="ApiConventionTypeMatchBehavior"/>.</param>
public ApiConventionTypeMatchAttribute(ApiConventionTypeMatchBehavior matchBehavior) public ApiConventionTypeMatchAttribute(ApiConventionTypeMatchBehavior matchBehavior)
{ {
MatchBehavior = matchBehavior; MatchBehavior = matchBehavior;
} }
/// <summary>
/// Gets the <see cref="ApiConventionTypeMatchBehavior"/>.
/// </summary>
public ApiConventionTypeMatchBehavior MatchBehavior { get; } public ApiConventionTypeMatchBehavior MatchBehavior { get; }
} }
} }

View File

@ -13,9 +13,17 @@ using Microsoft.Extensions.Internal;
namespace Microsoft.AspNetCore.Mvc.ApplicationModels namespace Microsoft.AspNetCore.Mvc.ApplicationModels
{ {
/// <summary>
/// An application model for controller actions.
/// </summary>
[DebuggerDisplay("{DisplayName}")] [DebuggerDisplay("{DisplayName}")]
public class ActionModel : ICommonModel, IFilterModel, IApiExplorerModel public class ActionModel : ICommonModel, IFilterModel, IApiExplorerModel
{ {
/// <summary>
/// Initializes a new instance of <see cref="ActionModel"/>.
/// </summary>
/// <param name="actionMethod">The action <see cref="MethodInfo"/>.</param>
/// <param name="attributes">The attributes associated with the action.</param>
public ActionModel( public ActionModel(
MethodInfo actionMethod, MethodInfo actionMethod,
IReadOnlyList<object> attributes) IReadOnlyList<object> attributes)
@ -41,6 +49,10 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
Selectors = new List<SelectorModel>(); Selectors = new List<SelectorModel>();
} }
/// <summary>
/// Copy constructor for <see cref="ActionModel"/>.
/// </summary>
/// <param name="other">The <see cref="ActionModel"/> to copy.</param>
public ActionModel(ActionModel other) public ActionModel(ActionModel other)
{ {
if (other == null) if (other == null)
@ -67,8 +79,14 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
Selectors = new List<SelectorModel>(other.Selectors.Select(s => new SelectorModel(s))); Selectors = new List<SelectorModel>(other.Selectors.Select(s => new SelectorModel(s)));
} }
/// <summary>
/// Gets the action <see cref="MethodInfo"/>.
/// </summary>
public MethodInfo ActionMethod { get; } public MethodInfo ActionMethod { get; }
/// <summary>
/// Gets the action name.
/// </summary>
public string ActionName { get; set; } public string ActionName { get; set; }
/// <summary> /// <summary>
@ -83,6 +101,9 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
/// </remarks> /// </remarks>
public ApiExplorerModel ApiExplorer { get; set; } public ApiExplorerModel ApiExplorer { get; set; }
/// <summary>
/// Gets the attributes associated with the action.
/// </summary>
public IReadOnlyList<object> Attributes { get; } public IReadOnlyList<object> Attributes { get; }
/// <summary> /// <summary>
@ -90,8 +111,14 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
/// </summary> /// </summary>
public ControllerModel Controller { get; set; } public ControllerModel Controller { get; set; }
/// <summary>
/// Gets the <see cref="IFilterMetadata"/> instances associated with the action.
/// </summary>
public IList<IFilterMetadata> Filters { get; } public IList<IFilterMetadata> Filters { get; }
/// <summary>
/// Gets the parameters associated with this action.
/// </summary>
public IList<ParameterModel> Parameters { get; } public IList<ParameterModel> Parameters { get; }
/// <summary> /// <summary>
@ -144,6 +171,9 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
/// </summary> /// </summary>
public IList<SelectorModel> Selectors { get; } public IList<SelectorModel> Selectors { get; }
/// <summary>
/// Gets the action display name.
/// </summary>
public string DisplayName public string DisplayName
{ {
get get

View File

@ -34,6 +34,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
/// </summary> /// </summary>
public ProducesErrorResponseTypeAttribute DefaultErrorResponseType { get; } public ProducesErrorResponseTypeAttribute DefaultErrorResponseType { get; }
/// <inheritdoc />
public void Apply(ActionModel action) public void Apply(ActionModel action)
{ {
if (action == null) if (action == null)
@ -50,6 +51,14 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
DiscoverErrorResponseType(action); DiscoverErrorResponseType(action);
} }
/// <summary>
/// Determines if this instance of <see cref="IActionModelConvention"/> applies to a specified <paramref name="action"/>.
/// </summary>
/// <param name="action">The <see cref="ActionModel"/>.</param>
/// <returns>
/// <see langword="true"/> if the convention applies, otherwise <see langword="false"/>.
/// Derived types may override this method to selectively apply this convention.
/// </returns>
protected virtual bool ShouldApply(ActionModel action) => true; protected virtual bool ShouldApply(ActionModel action) => true;
private static void DiscoverApiConvention(ActionModel action) private static void DiscoverApiConvention(ActionModel action)

View File

@ -8,6 +8,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
/// </summary> /// </summary>
public class ApiVisibilityConvention : IActionModelConvention public class ApiVisibilityConvention : IActionModelConvention
{ {
/// <inheritdoc />
public void Apply(ActionModel action) public void Apply(ActionModel action)
{ {
if (!ShouldApply(action)) if (!ShouldApply(action))
@ -22,6 +23,14 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
} }
} }
/// <summary>
/// Determines if this instance of <see cref="IActionModelConvention"/> applies to a specified <paramref name="action"/>.
/// </summary>
/// <param name="action">The <see cref="ActionModel"/>.</param>
/// <returns>
/// <see langword="true"/> if the convention applies, otherwise <see langword="false"/>.
/// Derived types may override this method to selectively apply this convention.
/// </returns>
protected virtual bool ShouldApply(ActionModel action) => true; protected virtual bool ShouldApply(ActionModel action) => true;
} }
} }

View File

@ -7,9 +7,15 @@ using Microsoft.AspNetCore.Mvc.Filters;
namespace Microsoft.AspNetCore.Mvc.ApplicationModels namespace Microsoft.AspNetCore.Mvc.ApplicationModels
{ {
/// <summary>
/// A model for configuring controllers in an MVC application.
/// </summary>
[DebuggerDisplay("ApplicationModel: Controllers: {Controllers.Count}, Filters: {Filters.Count}")] [DebuggerDisplay("ApplicationModel: Controllers: {Controllers.Count}, Filters: {Filters.Count}")]
public class ApplicationModel : IPropertyModel, IFilterModel, IApiExplorerModel public class ApplicationModel : IPropertyModel, IFilterModel, IApiExplorerModel
{ {
/// <summary>
/// Initializes a new instance of <see cref="ApplicationModel"/>.
/// </summary>
public ApplicationModel() public ApplicationModel()
{ {
ApiExplorer = new ApiExplorerModel(); ApiExplorer = new ApiExplorerModel();
@ -31,8 +37,14 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
/// </remarks> /// </remarks>
public ApiExplorerModel ApiExplorer { get; set; } public ApiExplorerModel ApiExplorer { get; set; }
/// <summary>
/// Gets the <see cref="ControllerModel"/> instances.
/// </summary>
public IList<ControllerModel> Controllers { get; } public IList<ControllerModel> Controllers { get; }
/// <summary>
/// Gets the global <see cref="IFilterMetadata"/> instances.
/// </summary>
public IList<IFilterMetadata> Filters { get; } public IList<IFilterMetadata> Filters { get; }
/// <summary> /// <summary>

View File

@ -12,6 +12,10 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
/// </summary> /// </summary>
public class ApplicationModelProviderContext public class ApplicationModelProviderContext
{ {
/// <summary>
/// Initializes a new instance of <see cref="ApplicationModelProviderContext"/>.
/// </summary>
/// <param name="controllerTypes">The discovered controller <see cref="TypeInfo"/> instances.</param>
public ApplicationModelProviderContext(IEnumerable<TypeInfo> controllerTypes) public ApplicationModelProviderContext(IEnumerable<TypeInfo> controllerTypes)
{ {
if (controllerTypes == null) if (controllerTypes == null)
@ -22,6 +26,9 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
ControllerTypes = controllerTypes; ControllerTypes = controllerTypes;
} }
/// <summary>
/// Gets the discovered controller <see cref="TypeInfo"/> instances.
/// </summary>
public IEnumerable<TypeInfo> ControllerTypes { get; } public IEnumerable<TypeInfo> ControllerTypes { get; }
/// <summary> /// <summary>

View File

@ -11,14 +11,24 @@ using Microsoft.AspNetCore.Routing;
namespace Microsoft.AspNetCore.Mvc.ApplicationModels namespace Microsoft.AspNetCore.Mvc.ApplicationModels
{ {
/// <summary>
/// A model for attribute routes.
/// </summary>
public class AttributeRouteModel public class AttributeRouteModel
{ {
private static readonly AttributeRouteModel _default = new AttributeRouteModel(); private static readonly AttributeRouteModel _default = new AttributeRouteModel();
/// <summary>
/// Initializes a new instance of <see cref="AttributeRoute"/>.
/// </summary>
public AttributeRouteModel() public AttributeRouteModel()
{ {
} }
/// <summary>
/// Initializes a new instance of <see cref="AttributeRoute"/> using the specified <paramref name="templateProvider"/>.
/// </summary>
/// <param name="templateProvider">The <see cref="IRouteTemplateProvider"/>.</param>
public AttributeRouteModel(IRouteTemplateProvider templateProvider) public AttributeRouteModel(IRouteTemplateProvider templateProvider)
{ {
if (templateProvider == null) if (templateProvider == null)
@ -32,6 +42,10 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
Name = templateProvider.Name; Name = templateProvider.Name;
} }
/// <summary>
/// Copy constructor for <see cref="AttributeRoute"/>.
/// </summary>
/// <param name="other">The <see cref="AttributeRouteModel"/> to copy.</param>
public AttributeRouteModel(AttributeRouteModel other) public AttributeRouteModel(AttributeRouteModel other)
{ {
if (other == null) if (other == null)
@ -47,12 +61,24 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
SuppressPathMatching = other.SuppressPathMatching; SuppressPathMatching = other.SuppressPathMatching;
} }
public IRouteTemplateProvider Attribute { get;} /// <summary>
/// Gets the <see cref="IRouteTemplateProvider"/>.
/// </summary>
public IRouteTemplateProvider Attribute { get; }
/// <summary>
/// Gets or sets the attribute route template.
/// </summary>
public string Template { get; set; } public string Template { get; set; }
/// <summary>
/// Gets or sets the route order.
/// </summary>
public int? Order { get; set; } public int? Order { get; set; }
/// <summary>
/// Gets or sets the route name.
/// </summary>
public string Name { get; set; } public string Name { get; set; }
/// <summary> /// <summary>
@ -65,6 +91,9 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
/// </summary> /// </summary>
public bool SuppressPathMatching { get; set; } public bool SuppressPathMatching { get; set; }
/// <summary>
/// Gets or sets a value that determines if this route template for this model overrides the route template at the parent scope.
/// </summary>
public bool IsAbsoluteTemplate => Template != null && IsOverridePattern(Template); public bool IsAbsoluteTemplate => Template != null && IsOverridePattern(Template);
/// <summary> /// <summary>

View File

@ -15,6 +15,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
{ {
private readonly ClientErrorResultFilterFactory _filterFactory = new ClientErrorResultFilterFactory(); private readonly ClientErrorResultFilterFactory _filterFactory = new ClientErrorResultFilterFactory();
/// <inheritdoc />
public void Apply(ActionModel action) public void Apply(ActionModel action)
{ {
if (action == null) if (action == null)
@ -31,6 +32,14 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
action.Filters.Add(_filterFactory); action.Filters.Add(_filterFactory);
} }
/// <summary>
/// Determines if this instance of <see cref="IActionModelConvention"/> applies to a specified <paramref name="action"/>.
/// </summary>
/// <param name="action">The <see cref="ActionModel"/>.</param>
/// <returns>
/// <see langword="true"/> if the convention applies, otherwise <see langword="false"/>.
/// Derived types may override this method to selectively apply this convention.
/// </returns>
protected virtual bool ShouldApply(ActionModel action) => true; protected virtual bool ShouldApply(ActionModel action) => true;
} }
} }

View File

@ -14,6 +14,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
/// </summary> /// </summary>
public class ConsumesConstraintForFormFileParameterConvention : IActionModelConvention public class ConsumesConstraintForFormFileParameterConvention : IActionModelConvention
{ {
/// <inheritdoc />
public void Apply(ActionModel action) public void Apply(ActionModel action)
{ {
if (action == null) if (action == null)
@ -29,6 +30,14 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
AddMultipartFormDataConsumesAttribute(action); AddMultipartFormDataConsumesAttribute(action);
} }
/// <summary>
/// Determines if this instance of <see cref="IActionModelConvention"/> applies to a specified <paramref name="action"/>.
/// </summary>
/// <param name="action">The <see cref="ActionModel"/>.</param>
/// <returns>
/// <see langword="true"/> if the convention applies, otherwise <see langword="false"/>.
/// Derived types may override this method to selectively apply this convention.
/// </returns>
protected virtual bool ShouldApply(ActionModel action) => true; protected virtual bool ShouldApply(ActionModel action) => true;
// Internal for unit testing // Internal for unit testing

View File

@ -42,6 +42,12 @@ namespace Microsoft.Extensions.DependencyInjection
return builder; return builder;
} }
/// <summary>
/// Configures <see cref="FormatterMappings"/> for the specified <paramref name="builder"/>.
/// </summary>
/// <param name="builder">The <see cref="IMvcBuilder"/>.</param>
/// <param name="setupAction">An <see cref="Action"/> to configure the <see cref="FormatterMappings"/>.</param>
/// <returns>The <see cref="IMvcBuilder"/>.</returns>
public static IMvcBuilder AddFormatterMappings( public static IMvcBuilder AddFormatterMappings(
this IMvcBuilder builder, this IMvcBuilder builder,
Action<FormatterMappings> setupAction) Action<FormatterMappings> setupAction)

View File

@ -15,6 +15,9 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Microsoft.Extensions.DependencyInjection namespace Microsoft.Extensions.DependencyInjection
{ {
/// <summary>
/// Extensions for configuring MVC using an <see cref="IMvcCoreBuilder"/>.
/// </summary>
public static class MvcCoreMvcCoreBuilderExtensions public static class MvcCoreMvcCoreBuilderExtensions
{ {
/// <summary> /// <summary>
@ -41,12 +44,23 @@ namespace Microsoft.Extensions.DependencyInjection
return builder; return builder;
} }
/// <summary>
/// Adds services to support <see cref="FormatterMappings"/>.
/// </summary>
/// <param name="builder">The <see cref="IMvcBuilder"/>.</param>
/// <returns>The <see cref="IMvcBuilder"/>.</returns>
public static IMvcCoreBuilder AddFormatterMappings(this IMvcCoreBuilder builder) public static IMvcCoreBuilder AddFormatterMappings(this IMvcCoreBuilder builder)
{ {
AddFormatterMappingsServices(builder.Services); AddFormatterMappingsServices(builder.Services);
return builder; return builder;
} }
/// <summary>
/// Configures <see cref="FormatterMappings"/> for the specified <paramref name="setupAction"/>.
/// </summary>
/// <param name="builder">The <see cref="IMvcCoreBuilder"/>.</param>
/// <param name="setupAction">An <see cref="Action"/> to configure the <see cref="FormatterMappings"/>.</param>
/// <returns>The <see cref="IMvcBuilder"/>.</returns>
public static IMvcCoreBuilder AddFormatterMappings( public static IMvcCoreBuilder AddFormatterMappings(
this IMvcCoreBuilder builder, this IMvcCoreBuilder builder,
Action<FormatterMappings> setupAction) Action<FormatterMappings> setupAction)
@ -67,12 +81,23 @@ namespace Microsoft.Extensions.DependencyInjection
services.TryAddSingleton<FormatFilter, FormatFilter>(); services.TryAddSingleton<FormatFilter, FormatFilter>();
} }
/// <summary>
/// Configures authentication and authorization services for <paramref name="builder"/>.
/// </summary>
/// <param name="builder">The <see cref="IMvcCoreBuilder"/>.</param>
/// <returns>The <see cref="IMvcCoreBuilder"/>.</returns>
public static IMvcCoreBuilder AddAuthorization(this IMvcCoreBuilder builder) public static IMvcCoreBuilder AddAuthorization(this IMvcCoreBuilder builder)
{ {
AddAuthorizationServices(builder.Services); AddAuthorizationServices(builder.Services);
return builder; return builder;
} }
/// <summary>
/// Configures authentication and authorization services for <paramref name="builder"/>.
/// </summary>
/// <param name="builder">The <see cref="IMvcCoreBuilder"/>.</param>
/// <param name="setupAction">An <see cref="Action"/> to configure the <see cref="AuthorizationOptions"/>.</param>
/// <returns>The <see cref="IMvcCoreBuilder"/>.</returns>
public static IMvcCoreBuilder AddAuthorization( public static IMvcCoreBuilder AddAuthorization(
this IMvcCoreBuilder builder, this IMvcCoreBuilder builder,
Action<AuthorizationOptions> setupAction) Action<AuthorizationOptions> setupAction)

View File

@ -9,8 +9,16 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Microsoft.Extensions.DependencyInjection namespace Microsoft.Extensions.DependencyInjection
{ {
/// <summary>
/// Extensions for configuring CORS using an <see cref="IMvcCoreBuilder"/>.
/// </summary>
public static class MvcCorsMvcCoreBuilderExtensions public static class MvcCorsMvcCoreBuilderExtensions
{ {
/// <summary>
/// Configures <see cref="IMvcCoreBuilder"/> to use CORS.
/// </summary>
/// <param name="builder">The <see cref="IMvcCoreBuilder"/>.</param>
/// <returns>The <see cref="IMvcCoreBuilder"/>.</returns>
public static IMvcCoreBuilder AddCors(this IMvcCoreBuilder builder) public static IMvcCoreBuilder AddCors(this IMvcCoreBuilder builder)
{ {
if (builder == null) if (builder == null)
@ -22,6 +30,12 @@ namespace Microsoft.Extensions.DependencyInjection
return builder; return builder;
} }
/// <summary>
/// Configures <see cref="IMvcCoreBuilder"/> to use CORS.
/// </summary>
/// <param name="builder">The <see cref="IMvcCoreBuilder"/>.</param>
/// <param name="setupAction">An <see cref="Action{MvcOptions}"/> to configure the provided <see cref="CorsOptions"/>.</param>
/// <returns>The <see cref="IMvcCoreBuilder"/>.</returns>
public static IMvcCoreBuilder AddCors( public static IMvcCoreBuilder AddCors(
this IMvcCoreBuilder builder, this IMvcCoreBuilder builder,
Action<CorsOptions> setupAction) Action<CorsOptions> setupAction)
@ -42,6 +56,12 @@ namespace Microsoft.Extensions.DependencyInjection
return builder; return builder;
} }
/// <summary>
/// Configures <see cref="CorsOptions"/>.
/// </summary>
/// <param name="builder">The <see cref="IMvcCoreBuilder"/>.</param>
/// <param name="setupAction">The configure action.</param>
/// <returns>The <see cref="IMvcCoreBuilder"/>.</returns>
public static IMvcCoreBuilder ConfigureCors( public static IMvcCoreBuilder ConfigureCors(
this IMvcCoreBuilder builder, this IMvcCoreBuilder builder,
Action<CorsOptions> setupAction) Action<CorsOptions> setupAction)

View File

@ -4,7 +4,6 @@
<Description>ASP.NET Core MVC cross-origin resource sharing (CORS) features.</Description> <Description>ASP.NET Core MVC cross-origin resource sharing (CORS) features.</Description>
<TargetFramework>netcoreapp3.0</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<IsAspNetCoreApp>true</IsAspNetCoreApp> <IsAspNetCoreApp>true</IsAspNetCoreApp>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;aspnetcoremvc;cors</PackageTags> <PackageTags>aspnetcore;aspnetcoremvc;cors</PackageTags>
</PropertyGroup> </PropertyGroup>

View File

@ -4,7 +4,6 @@
<Description>ASP.NET Core MVC metadata and validation system using System.ComponentModel.DataAnnotations.</Description> <Description>ASP.NET Core MVC metadata and validation system using System.ComponentModel.DataAnnotations.</Description>
<TargetFramework>netcoreapp3.0</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<IsAspNetCoreApp>true</IsAspNetCoreApp> <IsAspNetCoreApp>true</IsAspNetCoreApp>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;aspnetcoremvc</PackageTags> <PackageTags>aspnetcore;aspnetcoremvc</PackageTags>
</PropertyGroup> </PropertyGroup>

View File

@ -7,7 +7,6 @@ Microsoft.AspNetCore.Mvc.Localization.IHtmlLocalizer&lt;TResource&gt;
Microsoft.AspNetCore.Mvc.Localization.IViewLocalizer</Description> Microsoft.AspNetCore.Mvc.Localization.IViewLocalizer</Description>
<TargetFramework>netcoreapp3.0</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<IsAspNetCoreApp>true</IsAspNetCoreApp> <IsAspNetCoreApp>true</IsAspNetCoreApp>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;aspnetcoremvc;localization</PackageTags> <PackageTags>aspnetcore;aspnetcoremvc;localization</PackageTags>
</PropertyGroup> </PropertyGroup>

View File

@ -3,7 +3,6 @@
<PropertyGroup> <PropertyGroup>
<Description>ASP.NET Core MVC features that use Newtonsoft.Json. Includes input and output formatters for JSON and JSON PATCH.</Description> <Description>ASP.NET Core MVC features that use Newtonsoft.Json. Includes input and output formatters for JSON and JSON PATCH.</Description>
<TargetFramework>netcoreapp3.0</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;aspnetcoremvc;json</PackageTags> <PackageTags>aspnetcore;aspnetcoremvc;json</PackageTags>
<IsShippingPackage>true</IsShippingPackage> <IsShippingPackage>true</IsShippingPackage>

View File

@ -3,7 +3,6 @@
<PropertyGroup> <PropertyGroup>
<Description>ASP.NET Core MVC is a web framework that gives you a powerful, patterns-based way to build dynamic websites and web APIs. ASP.NET Core MVC enables a clean separation of concerns and gives you full control over markup.</Description> <Description>ASP.NET Core MVC is a web framework that gives you a powerful, patterns-based way to build dynamic websites and web APIs. ASP.NET Core MVC enables a clean separation of concerns and gives you full control over markup.</Description>
<TargetFramework>netcoreapp3.0</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;aspnetcoremvc</PackageTags> <PackageTags>aspnetcore;aspnetcoremvc</PackageTags>
<IsAspNetCoreApp>true</IsAspNetCoreApp> <IsAspNetCoreApp>true</IsAspNetCoreApp>