Clean up trailing whitespace in Core project

- checked and found no tabs in this project 😄
This commit is contained in:
dougbu 2014-04-30 21:30:00 -07:00 committed by Ryan Nowak
parent 822d84a2b4
commit 84396ad875
73 changed files with 423 additions and 266 deletions

View File

@ -46,9 +46,10 @@ namespace Microsoft.AspNet.Mvc
public static Type ExtractGenericInterface([NotNull] this Type queryType, Type interfaceType) public static Type ExtractGenericInterface([NotNull] this Type queryType, Type interfaceType)
{ {
Func<Type, bool> matchesInterface = t => t.IsGenericType() && t.GetGenericTypeDefinition() == interfaceType; Func<Type, bool> matchesInterface =
return (matchesInterface(queryType)) ? t => t.IsGenericType() && t.GetGenericTypeDefinition() == interfaceType;
queryType : return (matchesInterface(queryType)) ?
queryType :
queryType.GetInterfaces().FirstOrDefault(matchesInterface); queryType.GetInterfaces().FirstOrDefault(matchesInterface);
} }

View File

@ -34,7 +34,7 @@ namespace Microsoft.AspNet.Mvc
// The Http Abstractions should take care of these. // The Http Abstractions should take care of these.
_httpMethods = methods.Select(method => method.ToUpperInvariant()); _httpMethods = methods.Select(method => method.ToUpperInvariant());
} }
/// <summary> /// <summary>
/// Gets the HTTP methods the action supports. /// Gets the HTTP methods the action supports.
/// </summary> /// </summary>

View File

@ -22,7 +22,9 @@ namespace Microsoft.AspNet.Mvc
{ {
} }
public ActionContext([NotNull] HttpContext httpContext, [NotNull] RouteData routeData, [NotNull] ActionDescriptor actionDescriptor) public ActionContext([NotNull] HttpContext httpContext,
[NotNull] RouteData routeData,
[NotNull] ActionDescriptor actionDescriptor)
{ {
HttpContext = httpContext; HttpContext = httpContext;
RouteData = routeData; RouteData = routeData;

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Mvc
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly IViewEngine _viewEngine; private readonly IViewEngine _viewEngine;
public ActionResultHelper(IServiceProvider serviceProvider, IViewEngine viewEngine) public ActionResultHelper(IServiceProvider serviceProvider, IViewEngine viewEngine)
{ {
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;

View File

@ -18,13 +18,13 @@ namespace Microsoft.AspNet.Mvc
public override async Task ExecuteResultAsync([NotNull] ActionContext context) public override async Task ExecuteResultAsync([NotNull] ActionContext context)
{ {
HttpResponse response = context.HttpContext.Response; var response = context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType)) if (!string.IsNullOrEmpty(ContentType))
{ {
response.ContentType = ContentType; response.ContentType = ContentType;
} }
if (Content != null) if (Content != null)
{ {
await response.WriteAsync(Content); await response.WriteAsync(Content);

View File

@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc
} }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether to indent elements when writing data. /// Gets or sets a value indicating whether to indent elements when writing data.
/// </summary> /// </summary>
public bool Indent { get; set; } public bool Indent { get; set; }

View File

@ -1,10 +1,7 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Net; using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
@ -12,7 +9,7 @@ namespace Microsoft.AspNet.Mvc
{ {
public override void ExecuteResult([NotNull] ActionContext context) public override void ExecuteResult([NotNull] ActionContext context)
{ {
HttpResponse response = context.HttpContext.Response; var response = context.HttpContext.Response;
#if NET45 #if NET45
response.StatusCode = (int)HttpStatusCode.NoContent; response.StatusCode = (int)HttpStatusCode.NoContent;

View File

@ -46,9 +46,9 @@ namespace Microsoft.AspNet.Mvc
} }
catch catch
{ {
// Need to prevent writes/flushes on dispose because the StreamWriter will flush even if nothing // Need to prevent writes/flushes on dispose because the StreamWriter will flush even if
// got written. This leads to a response going out on the wire prematurely in case an exception // nothing got written. This leads to a response going out on the wire prematurely in case an
// is being thrown inside the try catch block. // exception is being thrown inside the try catch block.
wrappedStream.BlockWrites = true; wrappedStream.BlockWrites = true;
throw; throw;
} }

View File

@ -38,12 +38,12 @@ namespace Microsoft.AspNet.Mvc
/// <returns>An HTML string corresponding to an &lt;input type="hidden"&gt; /// <returns>An HTML string corresponding to an &lt;input type="hidden"&gt;
/// element. This element should be put inside a &lt;form&gt;.</returns> /// element. This element should be put inside a &lt;form&gt;.</returns>
/// <remarks> /// <remarks>
/// This method has a side effect: /// This method has a side effect:
/// A response cookie is set if there is no valid cookie associated with the request. /// A response cookie is set if there is no valid cookie associated with the request.
/// </remarks> /// </remarks>
public HtmlString GetHtml([NotNull] HttpContext context) public HtmlString GetHtml([NotNull] HttpContext context)
{ {
TagBuilder builder = _worker.GetFormInputElement(context); var builder = _worker.GetFormInputElement(context);
return builder.ToHtmlString(TagRenderMode.SelfClosing); return builder.ToHtmlString(TagRenderMode.SelfClosing);
} }

View File

@ -58,7 +58,7 @@ namespace Microsoft.AspNet.Mvc
set; set;
} }
// TODO: Replace the stub. // TODO: Replace the stub.
private static string GetAntiForgeryCookieName() private static string GetAntiForgeryCookieName()
{ {
return AntiForgeryTokenFieldName; return AntiForgeryTokenFieldName;

View File

@ -70,12 +70,13 @@ namespace Microsoft.AspNet.Mvc
var deserializedToken = new AntiForgeryToken(); var deserializedToken = new AntiForgeryToken();
var securityTokenBytes = reader.ReadBytes(AntiForgeryToken.SecurityTokenBitLength / 8); var securityTokenBytes = reader.ReadBytes(AntiForgeryToken.SecurityTokenBitLength / 8);
deserializedToken.SecurityToken = new BinaryBlob(AntiForgeryToken.SecurityTokenBitLength, securityTokenBytes); deserializedToken.SecurityToken =
new BinaryBlob(AntiForgeryToken.SecurityTokenBitLength, securityTokenBytes);
deserializedToken.IsSessionToken = reader.ReadBoolean(); deserializedToken.IsSessionToken = reader.ReadBoolean();
if (!deserializedToken.IsSessionToken) if (!deserializedToken.IsSessionToken)
{ {
bool isClaimsBased = reader.ReadBoolean(); var isClaimsBased = reader.ReadBoolean();
if (isClaimsBased) if (isClaimsBased)
{ {
var claimUidBytes = reader.ReadBytes(AntiForgeryToken.ClaimUidBitLength / 8); var claimUidBytes = reader.ReadBytes(AntiForgeryToken.ClaimUidBitLength / 8);
@ -140,7 +141,7 @@ namespace Microsoft.AspNet.Mvc
} }
var sb = new StringBuilder(); var sb = new StringBuilder();
for (int i = 0; i < base64String.Length; i++) for (var i = 0; i < base64String.Length; i++)
{ {
switch (base64String[i]) switch (base64String[i])
{ {
@ -165,7 +166,7 @@ namespace Microsoft.AspNet.Mvc
private byte[] UrlTokenDecode(string input) private byte[] UrlTokenDecode(string input)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
for (int i = 0; i < input.Length; i++) for (var i = 0; i < input.Length; i++)
{ {
switch (input[i]) switch (input[i])
{ {

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Mvc
public string FormToken { get; private set; } public string FormToken { get; private set; }
// The cookie token is allowed to be null. // The cookie token is allowed to be null.
// This would be the case when the old cookie token is still valid. // This would be the case when the old cookie token is still valid.
// In such cases a call to GetTokens would return a token set with null cookie token. // In such cases a call to GetTokens would return a token set with null cookie token.
public string CookieToken { get; private set; } public string CookieToken { get; private set; }

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Mvc
private readonly IAntiForgeryConfig _config; private readonly IAntiForgeryConfig _config;
private readonly IAntiForgeryTokenSerializer _serializer; private readonly IAntiForgeryTokenSerializer _serializer;
internal AntiForgeryTokenStore([NotNull] IAntiForgeryConfig config, internal AntiForgeryTokenStore([NotNull] IAntiForgeryConfig config,
[NotNull] IAntiForgeryTokenSerializer serializer) [NotNull] IAntiForgeryTokenSerializer serializer)
{ {
_config = config; _config = config;
@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Mvc
public AntiForgeryToken GetCookieToken(HttpContext httpContext) public AntiForgeryToken GetCookieToken(HttpContext httpContext)
{ {
var cookie = httpContext.Request.Cookies[_config.CookieName]; var cookie = httpContext.Request.Cookies[_config.CookieName];
if (String.IsNullOrEmpty(cookie)) if (string.IsNullOrEmpty(cookie))
{ {
// did not exist // did not exist
return null; return null;
@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Mvc
public async Task<AntiForgeryToken> GetFormTokenAsync(HttpContext httpContext) public async Task<AntiForgeryToken> GetFormTokenAsync(HttpContext httpContext)
{ {
var form = await httpContext.Request.GetFormAsync(); var form = await httpContext.Request.GetFormAsync();
string value = form[_config.FormFieldName]; var value = form[_config.FormFieldName];
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))
{ {
// did not exist // did not exist
@ -47,7 +47,7 @@ namespace Microsoft.AspNet.Mvc
public void SaveCookieToken(HttpContext httpContext, AntiForgeryToken token) public void SaveCookieToken(HttpContext httpContext, AntiForgeryToken token)
{ {
string serializedToken = _serializer.Serialize(token); var serializedToken = _serializer.Serialize(token);
var options = new CookieOptions() { HttpOnly = true }; var options = new CookieOptions() { HttpOnly = true };
// Note: don't use "newCookie.Secure = _config.RequireSSL;" since the default // Note: don't use "newCookie.Secure = _config.RequireSSL;" since the default

View File

@ -48,7 +48,6 @@ namespace Microsoft.AspNet.Mvc
: null; : null;
} }
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Caller will just regenerate token in case of failure.")]
private AntiForgeryToken DeserializeTokenNoThrow(string serializedToken) private AntiForgeryToken DeserializeTokenNoThrow(string serializedToken)
{ {
try try
@ -66,7 +65,7 @@ namespace Microsoft.AspNet.Mvc
{ {
if (httpContext != null) if (httpContext != null)
{ {
ClaimsPrincipal user = httpContext.User; var user = httpContext.User;
if (user != null) if (user != null)
{ {
@ -79,7 +78,6 @@ namespace Microsoft.AspNet.Mvc
return null; return null;
} }
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Caller will just regenerate token in case of failure.")]
private AntiForgeryToken GetCookieTokenNoThrow(HttpContext httpContext) private AntiForgeryToken GetCookieTokenNoThrow(HttpContext httpContext)
{ {
try try
@ -137,7 +135,7 @@ namespace Microsoft.AspNet.Mvc
public AntiForgeryTokenSet GetTokens([NotNull] HttpContext httpContext, string serializedOldCookieToken) public AntiForgeryTokenSet GetTokens([NotNull] HttpContext httpContext, string serializedOldCookieToken)
{ {
CheckSSLConfig(httpContext); CheckSSLConfig(httpContext);
AntiForgeryToken oldCookieToken = DeserializeTokenNoThrow(serializedOldCookieToken); var oldCookieToken = DeserializeTokenNoThrow(serializedOldCookieToken);
var tokenSet = GetTokens(httpContext, oldCookieToken); var tokenSet = GetTokens(httpContext, oldCookieToken);
var serializedNewCookieToken = Serialize(tokenSet.CookieToken); var serializedNewCookieToken = Serialize(tokenSet.CookieToken);
@ -156,7 +154,7 @@ namespace Microsoft.AspNet.Mvc
Contract.Assert(_validator.IsCookieTokenValid(oldCookieToken)); Contract.Assert(_validator.IsCookieTokenValid(oldCookieToken));
AntiForgeryToken formToken = _generator.GenerateFormToken( var formToken = _generator.GenerateFormToken(
httpContext, httpContext,
ExtractIdentity(httpContext), ExtractIdentity(httpContext),
oldCookieToken); oldCookieToken);
@ -201,7 +199,11 @@ namespace Microsoft.AspNet.Mvc
var deserializedFormToken = DeserializeToken(formToken); var deserializedFormToken = DeserializeToken(formToken);
// Validate // Validate
_validator.ValidateTokens(httpContext, ExtractIdentity(httpContext), deserializedCookieToken, deserializedFormToken); _validator.ValidateTokens(
httpContext,
ExtractIdentity(httpContext),
deserializedCookieToken,
deserializedFormToken);
} }
private class AntiForgeryTokenSetInternal private class AntiForgeryTokenSetInternal

View File

@ -48,13 +48,12 @@ namespace Microsoft.AspNet.Mvc
} }
} }
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by debugger.")]
private string DebuggerString private string DebuggerString
{ {
get get
{ {
StringBuilder sb = new StringBuilder("0x", 2 + (_data.Length * 2)); var sb = new StringBuilder("0x", 2 + (_data.Length * 2));
for (int i = 0; i < _data.Length; i++) for (var i = 0; i < _data.Length; i++)
{ {
sb.AppendFormat(CultureInfo.InvariantCulture, "{0:x2}", _data[i]); sb.AppendFormat(CultureInfo.InvariantCulture, "{0:x2}", _data[i]);
} }
@ -93,14 +92,14 @@ namespace Microsoft.AspNet.Mvc
private static byte[] GenerateNewToken(int bitLength) private static byte[] GenerateNewToken(int bitLength)
{ {
byte[] data = new byte[bitLength / 8]; var data = new byte[bitLength / 8];
CryptRand.FillBuffer(new ArraySegment<byte>(data)); CryptRand.FillBuffer(new ArraySegment<byte>(data));
return data; return data;
} }
// Need to mark it with NoInlining and NoOptimization attributes to ensure that the // Need to mark it with NoInlining and NoOptimization attributes to ensure that the
// operation runs in constant time. // operation runs in constant time.
[MethodImplAttribute(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] [MethodImplAttribute(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private static bool AreByteArraysEqual(byte[] a, byte[] b) private static bool AreByteArraysEqual(byte[] a, byte[] b)
{ {
if (a == null || b == null || a.Length != b.Length) if (a == null || b == null || a.Length != b.Length)
@ -108,8 +107,8 @@ namespace Microsoft.AspNet.Mvc
return false; return false;
} }
bool areEqual = true; var areEqual = true;
for (int i = 0; i < a.Length; i++) for (var i = 0; i < a.Length; i++)
{ {
areEqual &= (a[i] == b[i]); areEqual &= (a[i] == b[i]);
} }

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc
} }
var uniqueIdentifierParameters = GetUniqueIdentifierParameters(claimsIdentity); var uniqueIdentifierParameters = GetUniqueIdentifierParameters(claimsIdentity);
byte[] claimUidBytes = ComputeSHA256(uniqueIdentifierParameters); var claimUidBytes = ComputeSHA256(uniqueIdentifierParameters);
return Convert.ToBase64String(claimUidBytes); return Convert.ToBase64String(claimUidBytes);
} }
@ -69,7 +69,7 @@ namespace Microsoft.AspNet.Mvc
using (var sha256 = SHA256.Create()) using (var sha256 = SHA256.Create())
{ {
byte[] retVal = sha256.ComputeHash(ms.ToArray(), 0, checked((int)ms.Length)); var retVal = sha256.ComputeHash(ms.ToArray(), 0, checked((int)ms.Length));
return retVal; return retVal;
} }
} }

View File

@ -15,6 +15,9 @@ namespace Microsoft.AspNet.Mvc
// Given a cookie token, generates a corresponding form token. // Given a cookie token, generates a corresponding form token.
// The incoming cookie token must be valid. // The incoming cookie token must be valid.
AntiForgeryToken GenerateFormToken(HttpContext httpContext, ClaimsIdentity identity, AntiForgeryToken cookieToken); AntiForgeryToken GenerateFormToken(
HttpContext httpContext,
ClaimsIdentity identity,
AntiForgeryToken cookieToken);
} }
} }

View File

@ -15,6 +15,10 @@ namespace Microsoft.AspNet.Mvc
bool IsCookieTokenValid(AntiForgeryToken cookieToken); bool IsCookieTokenValid(AntiForgeryToken cookieToken);
// Validates a (cookie, form) token pair. // Validates a (cookie, form) token pair.
void ValidateTokens(HttpContext httpContext, ClaimsIdentity identity, AntiForgeryToken cookieToken, AntiForgeryToken formToken); void ValidateTokens(
HttpContext httpContext,
ClaimsIdentity identity,
AntiForgeryToken cookieToken,
AntiForgeryToken formToken);
} }
} }

View File

@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Mvc
private readonly IAntiForgeryConfig _config; private readonly IAntiForgeryConfig _config;
private readonly IAntiForgeryAdditionalDataProvider _additionalDataProvider; private readonly IAntiForgeryAdditionalDataProvider _additionalDataProvider;
internal TokenProvider(IAntiForgeryConfig config, internal TokenProvider(IAntiForgeryConfig config,
IClaimUidExtractor claimUidExtractor, IClaimUidExtractor claimUidExtractor,
IAntiForgeryAdditionalDataProvider additionalDataProvider) IAntiForgeryAdditionalDataProvider additionalDataProvider)
{ {
@ -33,7 +33,7 @@ namespace Microsoft.AspNet.Mvc
}; };
} }
public AntiForgeryToken GenerateFormToken(HttpContext httpContext, public AntiForgeryToken GenerateFormToken(HttpContext httpContext,
ClaimsIdentity identity, ClaimsIdentity identity,
AntiForgeryToken cookieToken) AntiForgeryToken cookieToken)
{ {
@ -45,7 +45,7 @@ namespace Microsoft.AspNet.Mvc
IsSessionToken = false IsSessionToken = false
}; };
bool isIdentityAuthenticated = false; var isIdentityAuthenticated = false;
// populate Username and ClaimUid // populate Username and ClaimUid
if (identity != null && identity.IsAuthenticated) if (identity != null && identity.IsAuthenticated)
@ -82,22 +82,29 @@ namespace Microsoft.AspNet.Mvc
return (cookieToken != null && cookieToken.IsSessionToken); return (cookieToken != null && cookieToken.IsSessionToken);
} }
public void ValidateTokens(HttpContext httpContext, ClaimsIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken) public void ValidateTokens(
HttpContext httpContext,
ClaimsIdentity identity,
AntiForgeryToken sessionToken,
AntiForgeryToken fieldToken)
{ {
// Were the tokens even present at all? // Were the tokens even present at all?
if (sessionToken == null) if (sessionToken == null)
{ {
throw new InvalidOperationException(Resources.FormatAntiForgeryToken_CookieMissing(_config.CookieName)); throw new InvalidOperationException(
Resources.FormatAntiForgeryToken_CookieMissing(_config.CookieName));
} }
if (fieldToken == null) if (fieldToken == null)
{ {
throw new InvalidOperationException(Resources.FormatAntiForgeryToken_FormFieldMissing(_config.FormFieldName)); throw new InvalidOperationException(
Resources.FormatAntiForgeryToken_FormFieldMissing(_config.FormFieldName));
} }
// Do the tokens have the correct format? // Do the tokens have the correct format?
if (!sessionToken.IsSessionToken || fieldToken.IsSessionToken) if (!sessionToken.IsSessionToken || fieldToken.IsSessionToken)
{ {
throw new InvalidOperationException(Resources.FormatAntiForgeryToken_TokensSwapped(_config.CookieName, _config.FormFieldName)); throw new InvalidOperationException(
Resources.FormatAntiForgeryToken_TokensSwapped(_config.CookieName, _config.FormFieldName));
} }
// Are the security tokens embedded in each incoming token identical? // Are the security tokens embedded in each incoming token identical?
@ -107,7 +114,7 @@ namespace Microsoft.AspNet.Mvc
} }
// Is the incoming token meant for the current user? // Is the incoming token meant for the current user?
string currentUsername = string.Empty; var currentUsername = string.Empty;
BinaryBlob currentClaimUid = null; BinaryBlob currentClaimUid = null;
if (identity != null && identity.IsAuthenticated) if (identity != null && identity.IsAuthenticated)
@ -121,13 +128,14 @@ namespace Microsoft.AspNet.Mvc
// OpenID and other similar authentication schemes use URIs for the username. // OpenID and other similar authentication schemes use URIs for the username.
// These should be treated as case-sensitive. // These should be treated as case-sensitive.
bool useCaseSensitiveUsernameComparison = currentUsername.StartsWith("http://", StringComparison.OrdinalIgnoreCase) var useCaseSensitiveUsernameComparison =
|| currentUsername.StartsWith("https://", StringComparison.OrdinalIgnoreCase); currentUsername.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
currentUsername.StartsWith("https://", StringComparison.OrdinalIgnoreCase);
if (!String.Equals(fieldToken.Username, if (!String.Equals(fieldToken.Username,
currentUsername, currentUsername,
(useCaseSensitiveUsernameComparison) ? (useCaseSensitiveUsernameComparison) ?
StringComparison.Ordinal : StringComparison.Ordinal :
StringComparison.OrdinalIgnoreCase)) StringComparison.OrdinalIgnoreCase))
{ {
throw new InvalidOperationException( throw new InvalidOperationException(
@ -140,7 +148,8 @@ namespace Microsoft.AspNet.Mvc
} }
// Is the AdditionalData valid? // Is the AdditionalData valid?
if (_additionalDataProvider != null && !_additionalDataProvider.ValidateAdditionalData(httpContext, fieldToken.AdditionalData)) if (_additionalDataProvider != null &&
!_additionalDataProvider.ValidateAdditionalData(httpContext, fieldToken.AdditionalData))
{ {
throw new InvalidOperationException(Resources.AntiForgeryToken_AdditionalDataCheckFailed); throw new InvalidOperationException(Resources.AntiForgeryToken_AdditionalDataCheckFailed);
} }

View File

@ -50,7 +50,8 @@ namespace Microsoft.AspNet.Mvc
{ {
if (!HasConstraint(actionDescriptor, key)) if (!HasConstraint(actionDescriptor, key))
{ {
actionDescriptor.RouteConstraints.Add(new RouteDataActionConstraint(key, RouteKeyHandling.DenyKey)); actionDescriptor.RouteConstraints.Add(
new RouteDataActionConstraint(key, RouteKeyHandling.DenyKey));
} }
} }
} }
@ -60,7 +61,8 @@ namespace Microsoft.AspNet.Mvc
private bool HasConstraint(ActionDescriptor actionDescript, string routeKey) private bool HasConstraint(ActionDescriptor actionDescript, string routeKey)
{ {
return actionDescript.RouteConstraints.Any(rc => string.Equals(rc.RouteKey, routeKey, StringComparison.OrdinalIgnoreCase)); return actionDescript.RouteConstraints.Any(
rc => string.Equals(rc.RouteKey, routeKey, StringComparison.OrdinalIgnoreCase));
} }
} }
} }

View File

@ -42,7 +42,8 @@ namespace Microsoft.AspNet.Mvc
private ActionDescriptorsCollection GetCollection() private ActionDescriptorsCollection GetCollection()
{ {
var actionDescriptorProvider = _serviceProvider.GetService<INestedProviderManager<ActionDescriptorProviderContext>>(); var actionDescriptorProvider =
_serviceProvider.GetService<INestedProviderManager<ActionDescriptorProviderContext>>();
var actionDescriptorProviderContext = new ActionDescriptorProviderContext(); var actionDescriptorProviderContext = new ActionDescriptorProviderContext();
actionDescriptorProvider.Invoke(actionDescriptorProviderContext); actionDescriptorProvider.Invoke(actionDescriptorProviderContext);

View File

@ -87,7 +87,7 @@ namespace Microsoft.AspNet.Mvc
!method.IsConstructor && !method.IsConstructor &&
!method.IsGenericMethod && !method.IsGenericMethod &&
// The SpecialName bit is set to flag members that are treated in a special way by some compilers // The SpecialName bit is set to flag members that are treated in a special way by some compilers
// (such as property accessors and operator overloading methods). // (such as property accessors and operator overloading methods).
!method.IsSpecialName && !method.IsSpecialName &&
!method.IsDefined(typeof(NonActionAttribute)); !method.IsDefined(typeof(NonActionAttribute));
@ -98,7 +98,7 @@ namespace Microsoft.AspNet.Mvc
var supportedHttpMethods = var supportedHttpMethods =
_supportedHttpMethodsByConvention.FirstOrDefault( _supportedHttpMethodsByConvention.FirstOrDefault(
httpMethod => methodInfo.Name.Equals(httpMethod, StringComparison.OrdinalIgnoreCase)); httpMethod => methodInfo.Name.Equals(httpMethod, StringComparison.OrdinalIgnoreCase));
if (supportedHttpMethods != null) if (supportedHttpMethods != null)
{ {
yield return supportedHttpMethods; yield return supportedHttpMethods;
@ -128,7 +128,7 @@ namespace Microsoft.AspNet.Mvc
var actionAttributes = GetActionCustomAttributes(methodInfo); var actionAttributes = GetActionCustomAttributes(methodInfo);
if (!actionAttributes.Any()) if (!actionAttributes.Any())
{ {
// If the action is not decorated with any of the attributes, // If the action is not decorated with any of the attributes,
// it would be handled by convention. // it would be handled by convention.
yield break; yield break;
} }
@ -147,7 +147,9 @@ namespace Microsoft.AspNet.Mvc
}; };
} }
private IEnumerable<ActionInfo> GetActionsForMethodsWithoutCustomAttributes(MethodInfo methodInfo, TypeInfo controllerTypeInfo) private IEnumerable<ActionInfo> GetActionsForMethodsWithoutCustomAttributes(
MethodInfo methodInfo,
TypeInfo controllerTypeInfo)
{ {
var actionInfos = new List<ActionInfo>(); var actionInfos = new List<ActionInfo>();
var httpMethods = GetSupportedHttpMethods(methodInfo); var httpMethods = GetSupportedHttpMethods(methodInfo);
@ -165,8 +167,9 @@ namespace Microsoft.AspNet.Mvc
} }
// For Default Method add an action Info with GET, POST Http Method constraints. // For Default Method add an action Info with GET, POST Http Method constraints.
// Only constraints (out of GET and POST) for which there are no convention based actions available are added. // Only constraints (out of GET and POST) for which there are no convention based actions available are
// If there are existing action infos with http constraints for GET and POST, this action info is not added for default method. // added. If there are existing action infos with http constraints for GET and POST, this action info is
// not added for default method.
if (IsDefaultActionMethod(methodInfo)) if (IsDefaultActionMethod(methodInfo))
{ {
var existingHttpMethods = new HashSet<string>(); var existingHttpMethods = new HashSet<string>();

View File

@ -64,12 +64,17 @@ namespace Microsoft.AspNet.Mvc
throw new ArgumentNullException("descriptor"); throw new ArgumentNullException("descriptor");
} }
return (descriptor.RouteConstraints == null || descriptor.RouteConstraints.All(c => c.Accept(context))) && return (descriptor.RouteConstraints == null ||
(descriptor.MethodConstraints == null || descriptor.MethodConstraints.All(c => c.Accept(context))) && descriptor.RouteConstraints.All(c => c.Accept(context))) &&
(descriptor.DynamicConstraints == null || descriptor.DynamicConstraints.All(c => c.Accept(context))); (descriptor.MethodConstraints == null ||
descriptor.MethodConstraints.All(c => c.Accept(context))) &&
(descriptor.DynamicConstraints == null ||
descriptor.DynamicConstraints.All(c => c.Accept(context)));
} }
protected virtual async Task<ActionDescriptor> SelectBestCandidate(RouteContext context, List<ActionDescriptor> candidates) protected virtual async Task<ActionDescriptor> SelectBestCandidate(
RouteContext context,
List<ActionDescriptor> candidates)
{ {
var applicableCandiates = new List<ActionDescriptorCandidate>(); var applicableCandiates = new List<ActionDescriptorCandidate>();
foreach (var action in candidates) foreach (var action in candidates)
@ -90,7 +95,8 @@ namespace Microsoft.AspNet.Mvc
continue; continue;
} }
if (await actionBindingContext.ValueProvider.ContainsPrefixAsync(parameter.ParameterBindingInfo.Prefix)) if (await actionBindingContext.ValueProvider.ContainsPrefixAsync(
parameter.ParameterBindingInfo.Prefix))
{ {
candidate.FoundParameters++; candidate.FoundParameters++;
if (parameter.IsOptional) if (parameter.IsOptional)
@ -122,7 +128,7 @@ namespace Microsoft.AspNet.Mvc
.OrderByDescending(g => g.Key) .OrderByDescending(g => g.Key)
.First(); .First();
var fewestOptionalParameters = var fewestOptionalParameters =
mostParametersSatisfied mostParametersSatisfied
.GroupBy(c => c.FoundOptionalParameters) .GroupBy(c => c.FoundOptionalParameters)
.OrderBy(g => g.Key).First() .OrderBy(g => g.Key).First()
@ -151,7 +157,7 @@ namespace Microsoft.AspNet.Mvc
var actions = var actions =
GetActions().Where( GetActions().Where(
action => action =>
action.RouteConstraints == null || action.RouteConstraints == null ||
action.RouteConstraints.All(constraint => constraint.Accept(context.ProvidedValues))); action.RouteConstraints.All(constraint => constraint.Accept(context.ProvidedValues)));
@ -166,9 +172,9 @@ namespace Microsoft.AspNet.Mvc
// This method attempts to find a unique 'best' candidate set of actions from the provided route // This method attempts to find a unique 'best' candidate set of actions from the provided route
// values and ambient route values. // values and ambient route values.
// //
// The purpose of this process is to avoid allowing certain routes to be too greedy. When a route uses // The purpose of this process is to avoid allowing certain routes to be too greedy. When a route uses
// a default value as a filter, it can generate links to actions it will never hit. The actions returned // a default value as a filter, it can generate links to actions it will never hit. The actions returned
// by this method are used by the link generation code to manipulate the route values so that routes that // by this method are used by the link generation code to manipulate the route values so that routes that
// are are greedy can't generate a link. // are are greedy can't generate a link.
// //
// The best example of this greediness is the canonical 'area' route from MVC. // The best example of this greediness is the canonical 'area' route from MVC.
@ -178,11 +184,12 @@ namespace Microsoft.AspNet.Mvc
// This route can generate a link even when the 'area' token is not provided. // This route can generate a link even when the 'area' token is not provided.
// //
// //
// We define 'best' based on the combination of Values and AmbientValues. This set can be used to select a // We define 'best' based on the combination of Values and AmbientValues. This set can be used to select a
// set of actions, anything in this is set is 'reachable'. We determine 'best' by looking for the 'reachable' // set of actions, anything in this is set is 'reachable'. We determine 'best' by looking for the
// actions ordered by the most total constraints matched, then the most constraints matched by ambient values. // 'reachable' actions ordered by the most total constraints matched, then the most constraints matched by
// ambient values.
// //
// Ex: // Ex:
// Consider the following actions - Home/Index (no area), and Admin/Home/Index (area = Admin). // Consider the following actions - Home/Index (no area), and Admin/Home/Index (area = Admin).
// ambient values = { area = "Admin", controller = "Home", action = "Diagnostics" } // ambient values = { area = "Admin", controller = "Home", action = "Diagnostics" }
// values = { action = "Index" } // values = { action = "Index" }
@ -194,7 +201,7 @@ namespace Microsoft.AspNet.Mvc
// //
// The description here is based on the concepts we're using to implement areas in WebFx, but apply // The description here is based on the concepts we're using to implement areas in WebFx, but apply
// to any tokens that might be used in routing (including REST conventions when action == null). // to any tokens that might be used in routing (including REST conventions when action == null).
// //
// This method does not take httpmethod or dynamic action constraints into account. // This method does not take httpmethod or dynamic action constraints into account.
var actions = GetActions(); var actions = GetActions();
@ -209,7 +216,7 @@ namespace Microsoft.AspNet.Mvc
continue; continue;
} }
bool isActionValid = true; var isActionValid = true;
foreach (var constraint in action.RouteConstraints) foreach (var constraint in action.RouteConstraints)
{ {
if (constraint.Accept(context.Values)) if (constraint.Accept(context.Values))
@ -299,7 +306,7 @@ namespace Microsoft.AspNet.Mvc
// //
// This is a no-op for our default conventions, but becomes important with custom action // This is a no-op for our default conventions, but becomes important with custom action
// descriptor providers. // descriptor providers.
// //
// Ex: These are not in the same equivalence class. // Ex: These are not in the same equivalence class.
// Action 1: constraint keys - { action, controller, area } // Action 1: constraint keys - { action, controller, area }
// Action 2: constraint keys - { action, module } // Action 2: constraint keys - { action, module }

View File

@ -30,7 +30,9 @@ namespace Microsoft.AspNet.Mvc
"actionContext"); "actionContext");
} }
var controller = _activator.CreateInstance(_serviceProvider, actionDescriptor.ControllerDescriptor.ControllerTypeInfo.AsType()); var controller = _activator.CreateInstance(
_serviceProvider,
actionDescriptor.ControllerDescriptor.ControllerTypeInfo.AsType());
InitializeController(controller, actionContext); InitializeController(controller, actionContext);

View File

@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Mvc
{ {
public ParameterDescriptor GetDescriptor(ParameterInfo parameter) public ParameterDescriptor GetDescriptor(ParameterInfo parameter)
{ {
bool isFromBody = IsFromBody(parameter); var isFromBody = IsFromBody(parameter);
return new ParameterDescriptor return new ParameterDescriptor
{ {

View File

@ -12,7 +12,7 @@ namespace System.Collections.Generic
{ {
Contract.Assert(values != null); Contract.Assert(values != null);
T[] array = values as T[]; var array = values as T[];
if (array == null) if (array == null)
{ {
array = values.ToArray(); array = values.ToArray();

View File

@ -7,7 +7,8 @@ using System.Threading.Tasks;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public abstract class ActionFilterAttribute : Attribute, IActionFilter, IAsyncActionFilter, IResultFilter, IAsyncResultFilter, IOrderedFilter public abstract class ActionFilterAttribute :
Attribute, IActionFilter, IAsyncActionFilter, IResultFilter, IAsyncResultFilter, IOrderedFilter
{ {
public int Order { get; set; } public int Order { get; set; }
@ -19,7 +20,9 @@ namespace Microsoft.AspNet.Mvc
{ {
} }
public virtual async Task OnActionExecutionAsync([NotNull] ActionExecutingContext context, [NotNull] ActionExecutionDelegate next) public virtual async Task OnActionExecutionAsync(
[NotNull] ActionExecutingContext context,
[NotNull] ActionExecutionDelegate next)
{ {
OnActionExecuting(context); OnActionExecuting(context);
if (context.Result == null) if (context.Result == null)
@ -36,7 +39,9 @@ namespace Microsoft.AspNet.Mvc
{ {
} }
public virtual async Task OnResultExecutionAsync([NotNull] ResultExecutingContext context, [NotNull] ResultExecutionDelegate next) public virtual async Task OnResultExecutionAsync(
[NotNull] ResultExecutingContext context,
[NotNull] ResultExecutionDelegate next)
{ {
OnResultExecuting(context); OnResultExecuting(context);
if (!context.Cancel) if (!context.Cancel)

View File

@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Mvc
public class AuthorizationContext : FilterContext public class AuthorizationContext : FilterContext
{ {
public AuthorizationContext( public AuthorizationContext(
[NotNull] ActionContext actionContext, [NotNull] ActionContext actionContext,
[NotNull] IList<IFilter> filters) [NotNull] IList<IFilter> filters)
: base(actionContext, filters) : base(actionContext, filters)
{ {

View File

@ -8,7 +8,8 @@ using System.Threading.Tasks;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public abstract class AuthorizationFilterAttribute : Attribute, IAsyncAuthorizationFilter, IAuthorizationFilter, IOrderedFilter public abstract class AuthorizationFilterAttribute :
Attribute, IAsyncAuthorizationFilter, IAuthorizationFilter, IOrderedFilter
{ {
public int Order { get; set; } public int Order { get; set; }

View File

@ -20,8 +20,8 @@ namespace Microsoft.AspNet.Mvc
{ {
_claims = new Claim[0]; _claims = new Claim[0];
} }
public AuthorizeAttribute([NotNull]IEnumerable<Claim> claims) public AuthorizeAttribute([NotNull]IEnumerable<Claim> claims)
{ {
_claims = claims.ToArray(); _claims = claims.ToArray();
} }
@ -48,9 +48,9 @@ namespace Microsoft.AspNet.Mvc
// when no claims are specified, we just need to ensure the user is authenticated // when no claims are specified, we just need to ensure the user is authenticated
if (_claims.Length == 0) if (_claims.Length == 0)
{ {
var userIsAnonymous = var userIsAnonymous =
user == null || user == null ||
user.Identity == null || user.Identity == null ||
!user.Identity.IsAuthenticated; !user.Identity.IsAuthenticated;
if (userIsAnonymous && !HasAllowAnonymous(context)) if (userIsAnonymous && !HasAllowAnonymous(context))
@ -58,13 +58,14 @@ namespace Microsoft.AspNet.Mvc
Fail(context); Fail(context);
} }
} }
else else
{ {
var authorizationService = httpContext.RequestServices.GetService<IAuthorizationService>(); var authorizationService = httpContext.RequestServices.GetService<IAuthorizationService>();
if (authorizationService == null) if (authorizationService == null)
{ {
throw new InvalidOperationException(Resources.AuthorizeAttribute_AuthorizationServiceMustBeDefined); throw new InvalidOperationException(
Resources.AuthorizeAttribute_AuthorizationServiceMustBeDefined);
} }
var authorized = await authorizationService.AuthorizeAsync(_claims, user); var authorized = await authorizationService.AuthorizeAsync(_claims, user);

View File

@ -80,7 +80,7 @@ namespace Microsoft.AspNet.Mvc.Filters
{ {
// If the controller implements a filter, and doesn't specify order, then it should // If the controller implements a filter, and doesn't specify order, then it should
// run closest to the action. // run closest to the action.
int order = Int32.MaxValue; var order = Int32.MaxValue;
var orderedControllerFilter = controllerFilter as IOrderedFilter; var orderedControllerFilter = controllerFilter as IOrderedFilter;
if (orderedControllerFilter != null) if (orderedControllerFilter != null)
{ {

View File

@ -12,12 +12,12 @@ namespace Microsoft.AspNet.Mvc
private Exception _exception; private Exception _exception;
private ExceptionDispatchInfo _exceptionDispatchInfo; private ExceptionDispatchInfo _exceptionDispatchInfo;
public ExceptionContext([NotNull] ActionContext actionContext, [NotNull] IList<IFilter> filters) public ExceptionContext([NotNull] ActionContext actionContext, [NotNull] IList<IFilter> filters)
: base(actionContext, filters) : base(actionContext, filters)
{ {
} }
public virtual Exception Exception public virtual Exception Exception
{ {
get get
{ {
@ -38,10 +38,10 @@ namespace Microsoft.AspNet.Mvc
} }
} }
public virtual ExceptionDispatchInfo ExceptionDispatchInfo public virtual ExceptionDispatchInfo ExceptionDispatchInfo
{ {
get get
{ {
return _exceptionDispatchInfo; return _exceptionDispatchInfo;
} }

View File

@ -8,8 +8,8 @@ namespace Microsoft.AspNet.Mvc
public abstract class FilterContext : ActionContext public abstract class FilterContext : ActionContext
{ {
public FilterContext( public FilterContext(
[NotNull] ActionContext actionContext, [NotNull] ActionContext actionContext,
[NotNull] IList<IFilter> filters) [NotNull] IList<IFilter> filters)
: base(actionContext) : base(actionContext)
{ {
Filters = filters; Filters = filters;

View File

@ -13,9 +13,9 @@ namespace Microsoft.AspNet.Mvc
private ExceptionDispatchInfo _exceptionDispatchInfo; private ExceptionDispatchInfo _exceptionDispatchInfo;
public ResultExecutedContext( public ResultExecutedContext(
[NotNull] ActionContext actionContext, [NotNull] ActionContext actionContext,
[NotNull] IList<IFilter> filters, [NotNull] IList<IFilter> filters,
[NotNull] IActionResult result) [NotNull] IActionResult result)
: base(actionContext, filters) : base(actionContext, filters)
{ {
Result = result; Result = result;

View File

@ -19,7 +19,9 @@ namespace Microsoft.AspNet.Mvc
{ {
} }
public virtual async Task OnResultExecutionAsync([NotNull] ResultExecutingContext context, [NotNull] ResultExecutionDelegate next) public virtual async Task OnResultExecutionAsync(
[NotNull] ResultExecutingContext context,
[NotNull] ResultExecutionDelegate next)
{ {
OnResultExecuting(context); OnResultExecuting(context);
if (context.Result == null) if (context.Result == null)

View File

@ -1,11 +1,11 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Routing;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using Microsoft.AspNet.Routing;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {

View File

@ -10,7 +10,7 @@ namespace Microsoft.AspNet.Mvc
string Content(string contentPath); string Content(string contentPath);
bool IsLocalUrl(string url); bool IsLocalUrl(string url);
string RouteUrl(string routeName, object values, string protocol, string host, string fragment); string RouteUrl(string routeName, object values, string protocol, string host, string fragment);
} }
} }

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNet.Mvc
{ {
var type = obj.GetType(); var type = obj.GetType();
var initializeMethod = var initializeMethod =
type.GetRuntimeMethods() type.GetRuntimeMethods()
.FirstOrDefault(m => m.Name.Equals("Initialize", StringComparison.OrdinalIgnoreCase)); .FirstOrDefault(m => m.Name.Equals("Initialize", StringComparison.OrdinalIgnoreCase));
@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Mvc
return; return;
} }
var args = var args =
initializeMethod.GetParameters() initializeMethod.GetParameters()
.Select(p => services.GetService(p.ParameterType)) .Select(p => services.GetService(p.ParameterType))
.ToArray(); .ToArray();
@ -31,7 +31,10 @@ namespace Microsoft.AspNet.Mvc
initializeMethod.Invoke(obj, args); initializeMethod.Invoke(obj, args);
} }
public static void InjectProperty<TProperty>([NotNull] object obj, [NotNull] string propertyName, TProperty value) public static void InjectProperty<TProperty>(
[NotNull] object obj,
[NotNull] string propertyName,
TProperty value)
{ {
var type = obj.GetType(); var type = obj.GetType();
@ -47,7 +50,10 @@ namespace Microsoft.AspNet.Mvc
} }
} }
public static void InjectProperty<TProperty>([NotNull] object obj, [NotNull] string propertyName, [NotNull] IServiceProvider services) public static void InjectProperty<TProperty>(
[NotNull] object obj,
[NotNull] string propertyName,
[NotNull] IServiceProvider services)
{ {
var type = obj.GetType(); var type = obj.GetType();

View File

@ -15,20 +15,20 @@ namespace Microsoft.AspNet.Mvc
// Delegate type for a by-ref property getter // Delegate type for a by-ref property getter
private delegate TValue ByRefFunc<TDeclaringType, TValue>(ref TDeclaringType arg); private delegate TValue ByRefFunc<TDeclaringType, TValue>(ref TDeclaringType arg);
private static readonly MethodInfo CallPropertyGetterOpenGenericMethod = private static readonly MethodInfo CallPropertyGetterOpenGenericMethod =
typeof(PropertyHelper).GetTypeInfo().GetDeclaredMethod("CallPropertyGetter"); typeof(PropertyHelper).GetTypeInfo().GetDeclaredMethod("CallPropertyGetter");
private static readonly MethodInfo CallPropertyGetterByReferenceOpenGenericMethod = private static readonly MethodInfo CallPropertyGetterByReferenceOpenGenericMethod =
typeof(PropertyHelper).GetTypeInfo().GetDeclaredMethod("CallPropertyGetterByReference"); typeof(PropertyHelper).GetTypeInfo().GetDeclaredMethod("CallPropertyGetterByReference");
private static readonly ConcurrentDictionary<Type, PropertyHelper[]> ReflectionCache = private static readonly ConcurrentDictionary<Type, PropertyHelper[]> ReflectionCache =
new ConcurrentDictionary<Type, PropertyHelper[]>(); new ConcurrentDictionary<Type, PropertyHelper[]>();
private readonly Func<object, object> _valueGetter; private readonly Func<object, object> _valueGetter;
/// <summary> /// <summary>
/// Initializes a fast property helper. /// Initializes a fast property helper.
/// ///
/// This constructor does not cache the helper. For caching, use GetProperties. /// This constructor does not cache the helper. For caching, use GetProperties.
/// </summary> /// </summary>
public PropertyHelper(PropertyInfo property) public PropertyHelper(PropertyInfo property)
@ -47,11 +47,12 @@ namespace Microsoft.AspNet.Mvc
} }
/// <summary> /// <summary>
/// Creates and caches fast property helpers that expose getters for every public get property on the /// Creates and caches fast property helpers that expose getters for every public get property on the
/// underlying type. /// underlying type.
/// </summary> /// </summary>
/// <param name="instance">the instance to extract property accessors for.</param> /// <param name="instance">the instance to extract property accessors for.</param>
/// <returns>a cached array of all public property getters from the underlying type of target instance.</returns> /// <returns>a cached array of all public property getters from the underlying type of target instance.
/// </returns>
public static PropertyHelper[] GetProperties(object instance) public static PropertyHelper[] GetProperties(object instance)
{ {
return GetProperties(instance, CreateInstance, ReflectionCache); return GetProperties(instance, CreateInstance, ReflectionCache);
@ -63,7 +64,7 @@ namespace Microsoft.AspNet.Mvc
/// <param name="propertyInfo">propertyInfo to extract the getter for.</param> /// <param name="propertyInfo">propertyInfo to extract the getter for.</param>
/// <returns>a fast getter.</returns> /// <returns>a fast getter.</returns>
/// <remarks> /// <remarks>
/// This method is more memory efficient than a dynamically compiled lambda, and about the /// This method is more memory efficient than a dynamically compiled lambda, and about the
/// same speed. /// same speed.
/// </remarks> /// </remarks>
public static Func<object, object> MakeFastPropertyGetter(PropertyInfo propertyInfo) public static Func<object, object> MakeFastPropertyGetter(PropertyInfo propertyInfo)
@ -87,19 +88,22 @@ namespace Microsoft.AspNet.Mvc
// Create a delegate (ref TDeclaringType) -> TValue // Create a delegate (ref TDeclaringType) -> TValue
var delegateType = typeof(ByRefFunc<,>).MakeGenericType(typeInput, typeOutput); var delegateType = typeof(ByRefFunc<,>).MakeGenericType(typeInput, typeOutput);
var propertyGetterAsFunc = getMethod.CreateDelegate(delegateType); var propertyGetterAsFunc = getMethod.CreateDelegate(delegateType);
var callPropertyGetterClosedGenericMethod = var callPropertyGetterClosedGenericMethod =
CallPropertyGetterByReferenceOpenGenericMethod.MakeGenericMethod(typeInput, typeOutput); CallPropertyGetterByReferenceOpenGenericMethod.MakeGenericMethod(typeInput, typeOutput);
callPropertyGetterDelegate = callPropertyGetterDelegate =
callPropertyGetterClosedGenericMethod.CreateDelegate(typeof(Func<object, object>), propertyGetterAsFunc); callPropertyGetterClosedGenericMethod.CreateDelegate(
typeof(Func<object, object>), propertyGetterAsFunc);
} }
else else
{ {
// Create a delegate TDeclaringType -> TValue // Create a delegate TDeclaringType -> TValue
var propertyGetterAsFunc = getMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(typeInput, typeOutput)); var propertyGetterAsFunc =
var callPropertyGetterClosedGenericMethod = getMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(typeInput, typeOutput));
var callPropertyGetterClosedGenericMethod =
CallPropertyGetterOpenGenericMethod.MakeGenericMethod(typeInput, typeOutput); CallPropertyGetterOpenGenericMethod.MakeGenericMethod(typeInput, typeOutput);
callPropertyGetterDelegate = callPropertyGetterDelegate =
callPropertyGetterClosedGenericMethod.CreateDelegate(typeof(Func<object, object>), propertyGetterAsFunc); callPropertyGetterClosedGenericMethod.CreateDelegate(
typeof(Func<object, object>), propertyGetterAsFunc);
} }
return (Func<object, object>)callPropertyGetterDelegate; return (Func<object, object>)callPropertyGetterDelegate;
@ -111,14 +115,16 @@ namespace Microsoft.AspNet.Mvc
} }
// Called via reflection // Called via reflection
private static object CallPropertyGetter<TDeclaringType, TValue>(Func<TDeclaringType, TValue> getter, object target) private static object CallPropertyGetter<TDeclaringType, TValue>(
Func<TDeclaringType, TValue> getter,
object target)
{ {
return getter((TDeclaringType)target); return getter((TDeclaringType)target);
} }
// Called via reflection // Called via reflection
private static object CallPropertyGetterByReference<TDeclaringType, TValue>( private static object CallPropertyGetterByReference<TDeclaringType, TValue>(
ByRefFunc<TDeclaringType, TValue> getter, ByRefFunc<TDeclaringType, TValue> getter,
object target) object target)
{ {
var unboxed = (TDeclaringType)target; var unboxed = (TDeclaringType)target;

View File

@ -29,9 +29,9 @@ namespace Microsoft.AspNet.Mvc
} }
/// <summary> /// <summary>
/// Given an object, adds each instance property with a public get method as a key and its /// Given an object, adds each instance property with a public get method as a key and its
/// associated value to a dictionary. /// associated value to a dictionary.
/// ///
/// If the object is already an <see cref="IDictionary{string, object}"/> instance, then a copy /// If the object is already an <see cref="IDictionary{string, object}"/> instance, then a copy
/// is returned. /// is returned.
/// </summary> /// </summary>

View File

@ -50,7 +50,8 @@ namespace Microsoft.AspNet.Mvc
var ex = new InvalidOperationException( var ex = new InvalidOperationException(
Resources.FormatActionInvokerFactory_CouldNotCreateInvoker(actionDescriptor)); Resources.FormatActionInvokerFactory_CouldNotCreateInvoker(actionDescriptor));
// Add tracing/logging (what do we think of this pattern of tacking on extra data on the exception?) // Add tracing/logging (what do we think of this pattern of
// tacking on extra data on the exception?)
ex.Data.Add("AD", actionDescriptor); ex.Data.Add("AD", actionDescriptor);
throw ex; throw ex;

View File

@ -24,7 +24,8 @@ namespace Microsoft.AspNet.Mvc
IEnumerable<IModelValidatorProvider> validatorProviders) IEnumerable<IModelValidatorProvider> validatorProviders)
{ {
_modelMetadataProvider = modelMetadataProvider; _modelMetadataProvider = modelMetadataProvider;
_modelBinders = modelBinders.OrderBy(binder => binder.GetType() == typeof(ComplexModelDtoModelBinder) ? 1 : 0); _modelBinders = modelBinders.OrderBy(
binder => binder.GetType() == typeof(ComplexModelDtoModelBinder) ? 1 : 0);
_valueProviderFactories = valueProviderFactories; _valueProviderFactories = valueProviderFactories;
_inputFormatterProvider = inputFormatterProvider; _inputFormatterProvider = inputFormatterProvider;
_validatorProviders = validatorProviders; _validatorProviders = validatorProviders;

View File

@ -4,4 +4,4 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.AspNet.Mvc.Core.Test")] [assembly: InternalsVisibleTo("Microsoft.AspNet.Mvc.Core.Test")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNet.Mvc
IEnumerable<IFilter> globalFilters) IEnumerable<IFilter> globalFilters)
{ {
_controllerAssemblyProvider = controllerAssemblyProvider; _controllerAssemblyProvider = controllerAssemblyProvider;
_conventions = conventions; _conventions = conventions;
_controllerDescriptorFactory = controllerDescriptorFactory; _controllerDescriptorFactory = controllerDescriptorFactory;
_parameterDescriptorFactory = parameterDescriptorFactory; _parameterDescriptorFactory = parameterDescriptorFactory;
var filters = globalFilters ?? Enumerable.Empty<IFilter>(); var filters = globalFilters ?? Enumerable.Empty<IFilter>();
@ -49,7 +49,9 @@ namespace Microsoft.AspNet.Mvc
var assemblies = _controllerAssemblyProvider.CandidateAssemblies; var assemblies = _controllerAssemblyProvider.CandidateAssemblies;
var types = assemblies.SelectMany(a => a.DefinedTypes); var types = assemblies.SelectMany(a => a.DefinedTypes);
var controllers = types.Where(_conventions.IsController); var controllers = types.Where(_conventions.IsController);
var controllerDescriptors = controllers.Select(t => _controllerDescriptorFactory.CreateControllerDescriptor(t)).ToArray(); var controllerDescriptors = controllers
.Select(t => _controllerDescriptorFactory.CreateControllerDescriptor(t))
.ToArray();
foreach (var cd in controllerDescriptors) foreach (var cd in controllerDescriptors)
{ {
@ -112,11 +114,15 @@ namespace Microsoft.AspNet.Mvc
ad.RouteConstraints.Add(new RouteDataActionConstraint("action", RouteKeyHandling.DenyKey)); ad.RouteConstraints.Add(new RouteDataActionConstraint("action", RouteKeyHandling.DenyKey));
} }
ad.Parameters = methodInfo.GetParameters().Select(p => _parameterDescriptorFactory.GetDescriptor(p)).ToList(); ad.Parameters = methodInfo.GetParameters()
.Select(p => _parameterDescriptorFactory.GetDescriptor(p))
.ToList();
var attributes = methodInfo.GetCustomAttributes(inherit: true).ToArray(); var attributes = methodInfo.GetCustomAttributes(inherit: true).ToArray();
var filtersFromAction = attributes.OfType<IFilter>().Select(filter => new FilterDescriptor(filter, FilterScope.Action)); var filtersFromAction = attributes
.OfType<IFilter>()
.Select(filter => new FilterDescriptor(filter, FilterScope.Action));
ad.FilterDescriptors = filtersFromAction.Concat(globalAndControllerFilters) ad.FilterDescriptors = filtersFromAction.Concat(globalAndControllerFilters)
.OrderBy(d => d, FilterDescriptorOrderComparer.Comparer) .OrderBy(d => d, FilterDescriptorOrderComparer.Comparer)

View File

@ -13,7 +13,8 @@ namespace Microsoft.AspNet.Mvc
{ {
public static class ReflectedActionExecutor public static class ReflectedActionExecutor
{ {
private static readonly MethodInfo _convertOfTMethod = typeof(ReflectedActionExecutor).GetRuntimeMethods().Single(methodInfo => methodInfo.Name == "Convert"); private static readonly MethodInfo _convertOfTMethod =
typeof(ReflectedActionExecutor).GetRuntimeMethods().Single(methodInfo => methodInfo.Name == "Convert");
// Method called via reflection. // Method called via reflection.
private static Task<object> Convert<T>(object taskAsObject) private static Task<object> Convert<T>(object taskAsObject)
@ -22,13 +23,19 @@ namespace Microsoft.AspNet.Mvc
return CastToObject<T>(task); return CastToObject<T>(task);
} }
public static async Task<object> ExecuteAsync(MethodInfo actionMethodInfo, object instance, IDictionary<string, object> actionArguments) public static async Task<object> ExecuteAsync(
MethodInfo actionMethodInfo,
object instance,
IDictionary<string, object> actionArguments)
{ {
var orderedArguments = PrepareArguments(actionArguments, actionMethodInfo.GetParameters()); var orderedArguments = PrepareArguments(actionArguments, actionMethodInfo.GetParameters());
return await ExecuteAsync(actionMethodInfo, instance, orderedArguments); return await ExecuteAsync(actionMethodInfo, instance, orderedArguments);
} }
public static async Task<object> ExecuteAsync(MethodInfo actionMethodInfo, object instance, object[] orderedActionArguments) public static async Task<object> ExecuteAsync(
MethodInfo actionMethodInfo,
object instance,
object[] orderedActionArguments)
{ {
object invocationResult = null; object invocationResult = null;
try try
@ -37,19 +44,27 @@ namespace Microsoft.AspNet.Mvc
} }
catch (TargetInvocationException targetInvocationException) catch (TargetInvocationException targetInvocationException)
{ {
// Capturing the actual exception and the original callstack and rethrow for external exception handlers to observe. // Capturing the exception and the original callstack and rethrow for external exception handlers.
ExceptionDispatchInfo exceptionDispatchInfo = ExceptionDispatchInfo.Capture(targetInvocationException.InnerException); var exceptionDispatchInfo = ExceptionDispatchInfo.Capture(targetInvocationException.InnerException);
exceptionDispatchInfo.Throw(); exceptionDispatchInfo.Throw();
} }
return await CoerceResultToTaskAsync(invocationResult, actionMethodInfo.ReturnType, actionMethodInfo.Name, actionMethodInfo.DeclaringType); return await CoerceResultToTaskAsync(
invocationResult,
actionMethodInfo.ReturnType,
actionMethodInfo.Name,
actionMethodInfo.DeclaringType);
} }
// We need to CoerceResult as the object value returned from methodInfo.Invoke has to be cast to a Task<T>. // We need to CoerceResult as the object value returned from methodInfo.Invoke has to be cast to a Task<T>.
// This is necessary to enable calling await on the returned task. // This is necessary to enable calling await on the returned task.
// i.e we need to write the following var result = await (Task<ActualType>)mInfo.Invoke. // i.e we need to write the following var result = await (Task<ActualType>)mInfo.Invoke.
// Returning Task<object> enables us to await on the result. // Returning Task<object> enables us to await on the result.
private static async Task<object> CoerceResultToTaskAsync(object result, Type returnType, string methodName, Type declaringType) private static async Task<object> CoerceResultToTaskAsync(
object result,
Type returnType,
string methodName,
Type declaringType)
{ {
// If it is either a Task or Task<T> // If it is either a Task or Task<T>
// must coerce the return value to Task<object> // must coerce the return value to Task<object>
@ -62,7 +77,7 @@ namespace Microsoft.AspNet.Mvc
return await CastToObject(resultAsTask); return await CastToObject(resultAsTask);
} }
Type taskValueType = TypeHelper.GetTaskInnerTypeOrNull(returnType); var taskValueType = TypeHelper.GetTaskInnerTypeOrNull(returnType);
if (taskValueType != null) if (taskValueType != null)
{ {
// for: public Task<T> Action() // for: public Task<T> Action()
@ -75,7 +90,9 @@ namespace Microsoft.AspNet.Mvc
// This will be the case for: // This will be the case for:
// 1. Types which have derived from Task and Task<T>, // 1. Types which have derived from Task and Task<T>,
// 2. Action methods which use dynamic keyword but return a Task or Task<T>. // 2. Action methods which use dynamic keyword but return a Task or Task<T>.
throw new InvalidOperationException(Resources.FormatActionExecutor_UnexpectedTaskInstance(methodName, declaringType)); throw new InvalidOperationException(Resources.FormatActionExecutor_UnexpectedTaskInstance(
methodName,
declaringType));
} }
else else
{ {
@ -83,16 +100,18 @@ namespace Microsoft.AspNet.Mvc
} }
} }
private static object[] PrepareArguments(IDictionary<string, object> actionParameters, ParameterInfo[] declaredParameterInfos) private static object[] PrepareArguments(
IDictionary<string, object> actionParameters,
ParameterInfo[] declaredParameterInfos)
{ {
int count = declaredParameterInfos.Length; var count = declaredParameterInfos.Length;
if (count == 0) if (count == 0)
{ {
return null; return null;
} }
var arguments = new object[count]; var arguments = new object[count];
for (int index = 0; index < count; index++) for (var index = 0; index < count; index++)
{ {
var parameterInfo = declaredParameterInfos[index]; var parameterInfo = declaredParameterInfos[index];
object value; object value;
@ -123,7 +142,7 @@ namespace Microsoft.AspNet.Mvc
// This most likely indicates that the developer forgot to call Unwrap() somewhere. // This most likely indicates that the developer forgot to call Unwrap() somewhere.
if (actualTypeReturned != typeof(Task)) if (actualTypeReturned != typeof(Task))
{ {
Type innerTaskType = TypeHelper.GetTaskInnerTypeOrNull(actualTypeReturned); var innerTaskType = TypeHelper.GetTaskInnerTypeOrNull(actualTypeReturned);
if (innerTaskType != null && typeof(Task).IsAssignableFrom(innerTaskType)) if (innerTaskType != null && typeof(Task).IsAssignableFrom(innerTaskType))
{ {
throw new InvalidOperationException( throw new InvalidOperationException(

View File

@ -174,7 +174,7 @@ namespace Microsoft.AspNet.Mvc
{ {
// We've reached the 'end' of the exception filter pipeline - this means that one stack frame has // We've reached the 'end' of the exception filter pipeline - this means that one stack frame has
// been built for each exception. When we return from here, these frames will either: // been built for each exception. When we return from here, these frames will either:
// //
// 1) Call the filter (if we have an exception) // 1) Call the filter (if we have an exception)
// 2) No-op (if we don't have an exception) // 2) No-op (if we don't have an exception)
Contract.Assert(_exceptionContext == null); Contract.Assert(_exceptionContext == null);
@ -274,12 +274,16 @@ namespace Microsoft.AspNet.Mvc
if (parameter.BodyParameterInfo != null) if (parameter.BodyParameterInfo != null)
{ {
var parameterType = parameter.BodyParameterInfo.ParameterType; var parameterType = parameter.BodyParameterInfo.ParameterType;
var modelMetadata = metadataProvider.GetMetadataForType(modelAccessor: null, modelType: parameterType); var modelMetadata = metadataProvider.GetMetadataForType(
var providerContext = new InputFormatterProviderContext(actionBindingContext.ActionContext.HttpContext, modelAccessor: null,
modelMetadata, modelType: parameterType);
modelState); var providerContext = new InputFormatterProviderContext(
actionBindingContext.ActionContext.HttpContext,
modelMetadata,
modelState);
var inputFormatter = actionBindingContext.InputFormatterProvider.GetInputFormatter(providerContext); var inputFormatter = actionBindingContext.InputFormatterProvider.GetInputFormatter(
providerContext);
var formatterContext = new InputFormatterContext(actionBindingContext.ActionContext.HttpContext, var formatterContext = new InputFormatterContext(actionBindingContext.ActionContext.HttpContext,
modelMetadata, modelMetadata,
@ -290,7 +294,9 @@ namespace Microsoft.AspNet.Mvc
else else
{ {
var parameterType = parameter.ParameterBindingInfo.ParameterType; var parameterType = parameter.ParameterBindingInfo.ParameterType;
var modelMetadata = metadataProvider.GetMetadataForType(modelAccessor: null, modelType: parameterType); var modelMetadata = metadataProvider.GetMetadataForType(
modelAccessor: null,
modelType: parameterType);
var modelBindingContext = new ModelBindingContext var modelBindingContext = new ModelBindingContext
{ {
@ -394,7 +400,10 @@ namespace Microsoft.AspNet.Mvc
_actionContext.Controller, _actionContext.Controller,
_actionExecutingContext.ActionArguments); _actionExecutingContext.ActionArguments);
var underlyingReturnType = TypeHelper.GetTaskInnerTypeOrNull(actionMethodInfo.ReturnType) ?? actionMethodInfo.ReturnType; var underlyingReturnType =
TypeHelper.GetTaskInnerTypeOrNull(actionMethodInfo.ReturnType) ??
actionMethodInfo.ReturnType;
var actionResult = CreateActionResult( var actionResult = CreateActionResult(
underlyingReturnType, underlyingReturnType,
actionReturnValue); actionReturnValue);
@ -428,7 +437,8 @@ namespace Microsoft.AspNet.Mvc
Contract.Assert(_resultExecutingContext != null); Contract.Assert(_resultExecutingContext != null);
if (_resultExecutingContext.Cancel == true) if (_resultExecutingContext.Cancel == true)
{ {
// If we get here, it means that an async filter set cancel == true AND called next(). This is forbidden. // If we get here, it means that an async filter set cancel == true AND called next().
// This is forbidden.
var message = Resources.FormatAsyncResultFilter_InvalidShortCircuit( var message = Resources.FormatAsyncResultFilter_InvalidShortCircuit(
typeof(IAsyncResultFilter).Name, typeof(IAsyncResultFilter).Name,
"Cancel", "Cancel",
@ -448,7 +458,10 @@ namespace Microsoft.AspNet.Mvc
if (_resultExecutedContext == null) if (_resultExecutedContext == null)
{ {
// Short-circuited by not calling next // Short-circuited by not calling next
_resultExecutedContext = new ResultExecutedContext(_resultExecutingContext, _filters, _resultExecutingContext.Result) _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext,
_filters,
_resultExecutingContext.Result)
{ {
Canceled = true, Canceled = true,
}; };
@ -456,7 +469,10 @@ namespace Microsoft.AspNet.Mvc
else if (_resultExecutingContext.Cancel == true) else if (_resultExecutingContext.Cancel == true)
{ {
// Short-circuited by setting Cancel == true // Short-circuited by setting Cancel == true
_resultExecutedContext = new ResultExecutedContext(_resultExecutingContext, _filters, _resultExecutingContext.Result) _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext,
_filters,
_resultExecutingContext.Result)
{ {
Canceled = true, Canceled = true,
}; };
@ -469,7 +485,10 @@ namespace Microsoft.AspNet.Mvc
if (_resultExecutingContext.Cancel == true) if (_resultExecutingContext.Cancel == true)
{ {
// Short-circuited by setting Cancel == true // Short-circuited by setting Cancel == true
_resultExecutedContext = new ResultExecutedContext(_resultExecutingContext, _filters, _resultExecutingContext.Result) _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext,
_filters,
_resultExecutingContext.Result)
{ {
Canceled = true, Canceled = true,
}; };
@ -484,12 +503,18 @@ namespace Microsoft.AspNet.Mvc
await InvokeActionResult(); await InvokeActionResult();
Contract.Assert(_resultExecutedContext == null); Contract.Assert(_resultExecutedContext == null);
_resultExecutedContext = new ResultExecutedContext(_resultExecutingContext, _filters, _resultExecutingContext.Result); _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext,
_filters,
_resultExecutingContext.Result);
} }
} }
catch (Exception exception) catch (Exception exception)
{ {
_resultExecutedContext = new ResultExecutedContext(_resultExecutingContext, _filters, _resultExecutingContext.Result) _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext,
_filters,
_resultExecutingContext.Result)
{ {
ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception) ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception)
}; };
@ -502,7 +527,7 @@ namespace Microsoft.AspNet.Mvc
{ {
_cursor.SetStage(FilterStage.ActionResult); _cursor.SetStage(FilterStage.ActionResult);
// The empty result is always flowed back as the 'executed' result // The empty result is always flowed back as the 'executed' result
if (_resultExecutingContext.Result == null) if (_resultExecutingContext.Result == null)
{ {
_resultExecutingContext.Result = new EmptyResult(); _resultExecutingContext.Result = new EmptyResult();
@ -523,24 +548,24 @@ namespace Microsoft.AspNet.Mvc
} }
/// <summary> /// <summary>
/// A one-way cursor for filters. /// A one-way cursor for filters.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This will iterate the filter collection once per-stage, and skip any filters that don't have /// This will iterate the filter collection once per-stage, and skip any filters that don't have
/// the one of interfaces that applies to the current stage. /// the one of interfaces that applies to the current stage.
/// ///
/// Filters are always executed in the following order, but short circuiting plays a role. /// Filters are always executed in the following order, but short circuiting plays a role.
/// ///
/// Indentation reflects nesting. /// Indentation reflects nesting.
/// ///
/// 1. Exception Filters /// 1. Exception Filters
/// 2. Authorization Filters /// 2. Authorization Filters
/// 3. Action Filters /// 3. Action Filters
/// Action /// Action
/// ///
/// 4. Result Filters /// 4. Result Filters
/// Result /// Result
/// ///
/// </remarks> /// </remarks>
private struct FilterCursor private struct FilterCursor
{ {

View File

@ -69,7 +69,12 @@ namespace Microsoft.AspNet.Mvc.Rendering.Expressions
} }
}; };
return GetMetadataFromProvider(modelAccessor, typeof(TValue), propertyName, containerType, metadataProvider); return GetMetadataFromProvider(
modelAccessor,
typeof(TValue),
propertyName,
containerType,
metadataProvider);
} }
public static ModelMetadata FromStringExpression(string expression, public static ModelMetadata FromStringExpression(string expression,

View File

@ -39,7 +39,8 @@ namespace Microsoft.AspNet.Mvc.Rendering.Expressions
var dictionaryType = targetType.ExtractGenericInterface(typeof(IDictionary<,>)); var dictionaryType = targetType.ExtractGenericInterface(typeof(IDictionary<,>));
// Just wrap a call to the underlying IDictionary<TKey, TValue>.TryGetValue() where string can be cast to TKey. // Just wrap a call to the underlying IDictionary<TKey, TValue>.TryGetValue() where string can be cast to
// TKey.
if (dictionaryType != null) if (dictionaryType != null)
{ {
var typeArguments = dictionaryType.GetGenericArguments(); var typeArguments = dictionaryType.GetGenericArguments();

View File

@ -174,7 +174,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
public static string EmailAddressTemplate(IHtmlHelper html) public static string EmailAddressTemplate(IHtmlHelper html)
{ {
var uriString = "mailto:" + ((html.ViewData.Model == null) ? string.Empty : html.ViewData.Model.ToString()); var uriString = "mailto:" + ((html.ViewData.Model == null) ?
string.Empty :
html.ViewData.Model.ToString());
var linkedText = (html.ViewData.TemplateInfo.FormattedModelValue == null) ? var linkedText = (html.ViewData.TemplateInfo.FormattedModelValue == null) ?
string.Empty : string.Empty :
html.ViewData.TemplateInfo.FormattedModelValue.ToString(); html.ViewData.TemplateInfo.FormattedModelValue.ToString();

View File

@ -162,7 +162,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
} }
var htmlAttributes = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase) var htmlAttributes = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
{ {
{ "class", className } { "class", className }
}; };

View File

@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
public HtmlHelper( public HtmlHelper(
[NotNull] IViewEngine viewEngine, [NotNull] IViewEngine viewEngine,
[NotNull] IModelMetadataProvider metadataProvider, [NotNull] IModelMetadataProvider metadataProvider,
[NotNull] IUrlHelper urlHelper, [NotNull] IUrlHelper urlHelper,
[NotNull] AntiForgery antiForgeryInstance, [NotNull] AntiForgery antiForgeryInstance,
[NotNull] IActionBindingContextProvider actionBindingContextProvider) [NotNull] IActionBindingContextProvider actionBindingContextProvider)
{ {
@ -118,10 +118,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
} }
/// <summary> /// <summary>
/// Creates a dictionary from an object, by adding each public instance property as a key with its associated /// Creates a dictionary from an object, by adding each public instance property as a key with its associated
/// value to the dictionary. It will expose public properties from derived types as well. This is typically used /// value to the dictionary. It will expose public properties from derived types as well. This is typically
/// with objects of an anonymous type. /// used with objects of an anonymous type.
/// ///
/// If the object is already an <see cref="IDictionary{string, object}"/> instance, then it is /// If the object is already an <see cref="IDictionary{string, object}"/> instance, then it is
/// returned as-is. /// returned as-is.
/// </summary> /// </summary>
@ -137,9 +137,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
} }
/// <summary> /// <summary>
/// Creates a dictionary of HTML attributes from the input object, /// Creates a dictionary of HTML attributes from the input object,
/// translating underscores to dashes in each public instance property. /// translating underscores to dashes in each public instance property.
/// ///
/// If the object is already an <see cref="IDictionary{string, object}"/> instance, then it is /// If the object is already an <see cref="IDictionary{string, object}"/> instance, then it is
/// returned as-is. /// returned as-is.
/// <example> /// <example>
@ -441,7 +441,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
var url = _urlHelper.RouteUrl(routeName, routeValues, protocol, hostName, fragment); var url = _urlHelper.RouteUrl(routeName, routeValues, protocol, hostName, fragment);
return GenerateLink(linkText, url, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); return GenerateLink(linkText, url, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
} }
/// <inheritdoc /> /// <inheritdoc />
public HtmlString ValidationMessage(string expression, string message, object htmlAttributes, string tag) public HtmlString ValidationMessage(string expression, string message, object htmlAttributes, string tag)
{ {
@ -490,7 +490,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
{ {
foreach (var modelError in modelState.Errors) foreach (var modelError in modelState.Errors)
{ {
string errorText = ValidationHelpers.GetUserErrorMessageOrDefault(modelError, modelState: null); var errorText = ValidationHelpers.GetUserErrorMessageOrDefault(modelError, modelState: null);
if (!string.IsNullOrEmpty(errorText)) if (!string.IsNullOrEmpty(errorText))
{ {
@ -703,7 +703,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
protected virtual HtmlString GenerateDisplayName([NotNull] ModelMetadata metadata, string htmlFieldName) protected virtual HtmlString GenerateDisplayName([NotNull] ModelMetadata metadata, string htmlFieldName)
{ {
// We don't call ModelMetadata.GetDisplayName here because // We don't call ModelMetadata.GetDisplayName here because
// we want to fall back to the field name rather than the ModelType. // we want to fall back to the field name rather than the ModelType.
// This is similar to how the GenerateLabel get the text of a label. // This is similar to how the GenerateLabel get the text of a label.
// TODO: This needs to be updated after ModelMetadata has a DisplayName property // TODO: This needs to be updated after ModelMetadata has a DisplayName property
@ -717,7 +717,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
return new HtmlString(Encode(resolvedDisplayName)); return new HtmlString(Encode(resolvedDisplayName));
} }
protected virtual HtmlString GenerateDisplayText(ModelMetadata metadata) protected virtual HtmlString GenerateDisplayText(ModelMetadata metadata)
{ {
return new HtmlString(metadata.SimpleDisplayText); return new HtmlString(metadata.SimpleDisplayText);
@ -810,7 +810,11 @@ namespace Microsoft.AspNet.Mvc.Rendering
return theForm; return theForm;
} }
protected virtual HtmlString GenerateHidden(ModelMetadata metadata, string name, object value, bool useViewData, protected virtual HtmlString GenerateHidden(
ModelMetadata metadata,
string name,
object value,
bool useViewData,
object htmlAttributes) object htmlAttributes)
{ {
// Only need a dictionary if htmlAttributes is non-null. TagBuilder.MergeAttributes() is fine with null. // Only need a dictionary if htmlAttributes is non-null. TagBuilder.MergeAttributes() is fine with null.
@ -854,7 +858,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
object htmlAttributes) object htmlAttributes)
{ {
// TODO: This needs to be updated after ModelMetadata has a DisplayName property // TODO: This needs to be updated after ModelMetadata has a DisplayName property
string resolvedLabelText = labelText ?? metadata.PropertyName; var resolvedLabelText = labelText ?? metadata.PropertyName;
if (resolvedLabelText == null) if (resolvedLabelText == null)
{ {
resolvedLabelText = string.IsNullOrEmpty(htmlFieldName) ? resolvedLabelText = string.IsNullOrEmpty(htmlFieldName) ?
@ -867,7 +871,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
return HtmlString.Empty; return HtmlString.Empty;
} }
TagBuilder tag = new TagBuilder("label"); var tag = new TagBuilder("label");
tag.Attributes.Add( tag.Attributes.Add(
"for", "for",
TagBuilder.CreateSanitizedId( TagBuilder.CreateSanitizedId(
@ -1104,7 +1108,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
ModelState modelState; ModelState modelState;
ViewData.ModelState.TryGetValue(fullName, out modelState); ViewData.ModelState.TryGetValue(fullName, out modelState);
string value = string.Empty; var value = string.Empty;
if (modelState != null && modelState.Value != null) if (modelState != null && modelState.Value != null)
{ {
value = modelState.Value.AttemptedValue; value = modelState.Value.AttemptedValue;
@ -1378,7 +1382,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
return new HtmlString(Encode(resolvedValue)); return new HtmlString(Encode(resolvedValue));
} }
protected virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules(string name, ModelMetadata metadata) protected virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules(
string name,
ModelMetadata metadata)
{ {
var actionBindingContext = _actionBindingContextProvider.GetActionBindingContextAsync(ViewContext).Result; var actionBindingContext = _actionBindingContextProvider.GetActionBindingContextAsync(ViewContext).Result;
metadata = metadata ?? metadata = metadata ??

View File

@ -111,7 +111,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
return GenerateDisplayName(metadata, expressionText); return GenerateDisplayName(metadata, expressionText);
} }
/// <inheritdoc /> /// <inheritdoc />
public HtmlString DisplayTextFor<TValue>([NotNull] Expression<Func<TModel, TValue>> expression) public HtmlString DisplayTextFor<TValue>([NotNull] Expression<Func<TModel, TValue>> expression)
{ {
@ -150,7 +150,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
} }
/// <inheritdoc /> /// <inheritdoc />
public HtmlString LabelFor<TValue>([NotNull] Expression<Func<TModel, TValue>> expression, string labelText, object htmlAttributes) public HtmlString LabelFor<TValue>(
[NotNull] Expression<Func<TModel, TValue>> expression,
string labelText,
object htmlAttributes)
{ {
var metadata = GetModelMetadata(expression); var metadata = GetModelMetadata(expression);
return GenerateLabel(metadata, ExpressionHelper.GetExpressionText(expression), labelText, htmlAttributes); return GenerateLabel(metadata, ExpressionHelper.GetExpressionText(expression), labelText, htmlAttributes);

View File

@ -19,13 +19,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
private bool _readOnly; private bool _readOnly;
private object _additionalViewData; private object _additionalViewData;
public TemplateBuilder([NotNull] IViewEngine viewEngine, public TemplateBuilder([NotNull] IViewEngine viewEngine,
[NotNull] ViewContext viewContext, [NotNull] ViewContext viewContext,
[NotNull] ViewDataDictionary viewData, [NotNull] ViewDataDictionary viewData,
[NotNull] ModelMetadata metadata, [NotNull] ModelMetadata metadata,
string htmlFieldName, string htmlFieldName,
string templateName, string templateName,
bool readOnly, bool readOnly,
object additionalViewData) object additionalViewData)
{ {
_viewEngine = viewEngine; _viewEngine = viewEngine;
@ -76,13 +76,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
if (_additionalViewData != null) if (_additionalViewData != null)
{ {
foreach (KeyValuePair<string, object> kvp in HtmlHelper.ObjectToDictionary(_additionalViewData)) foreach (var kvp in HtmlHelper.ObjectToDictionary(_additionalViewData))
{ {
viewData[kvp.Key] = kvp.Value; viewData[kvp.Key] = kvp.Value;
} }
} }
object visitedObjectsKey = _metadata.Model ?? _metadata.RealModelType; var visitedObjectsKey = _metadata.Model ?? _metadata.RealModelType;
viewData.TemplateInfo.AddVisited(visitedObjectsKey); viewData.TemplateInfo.AddVisited(visitedObjectsKey);
var templateRenderer = new TemplateRenderer(_viewEngine, _viewContext, viewData, _templateName, _readOnly); var templateRenderer = new TemplateRenderer(_viewEngine, _viewContext, viewData, _templateName, _readOnly);

View File

@ -127,8 +127,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
var metadata = _viewData.ModelMetadata; var metadata = _viewData.ModelMetadata;
var templateHints = new string[] var templateHints = new string[]
{ {
_templateName, _templateName,
metadata.TemplateHint, metadata.TemplateHint,
metadata.DataTypeName metadata.DataTypeName
}; };
@ -137,7 +137,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
yield return templateHint; yield return templateHint;
} }
// We don't want to search for Nullable<T>, we want to search for T (which should handle both T and Nullable<T>) // We don't want to search for Nullable<T>, we want to search for T (which should handle both T and
// Nullable<T>).
var fieldType = Nullable.GetUnderlyingType(metadata.RealModelType) ?? metadata.RealModelType; var fieldType = Nullable.GetUnderlyingType(metadata.RealModelType) ?? metadata.RealModelType;
yield return fieldType.Name; yield return fieldType.Name;
@ -173,7 +174,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
} }
else else
{ {
bool isEnumerable = typeof(IEnumerable).IsAssignableFrom(fieldType); var isEnumerable = typeof(IEnumerable).IsAssignableFrom(fieldType);
while (true) while (true)
{ {

View File

@ -29,7 +29,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
} }
// Returns non-null list of model states, which caller will render in order provided. // Returns non-null list of model states, which caller will render in order provided.
public static IEnumerable<ModelState> GetModelStateList(ViewDataDictionary viewData, bool excludePropertyErrors) public static IEnumerable<ModelState> GetModelStateList(
ViewDataDictionary viewData,
bool excludePropertyErrors)
{ {
if (excludePropertyErrors) if (excludePropertyErrors)
{ {
@ -80,7 +82,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
{ {
return value; return value;
} }
return ModelMetadata.DefaultOrder; return ModelMetadata.DefaultOrder;
} }
} }

View File

@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
{ {
internal class HtmlAttributePropertyHelper : PropertyHelper internal class HtmlAttributePropertyHelper : PropertyHelper
{ {
private static readonly ConcurrentDictionary<Type, PropertyHelper[]> ReflectionCache = private static readonly ConcurrentDictionary<Type, PropertyHelper[]> ReflectionCache =
new ConcurrentDictionary<Type, PropertyHelper[]>(); new ConcurrentDictionary<Type, PropertyHelper[]>();
public static new PropertyHelper[] GetProperties(object instance) public static new PropertyHelper[] GetProperties(object instance)

View File

@ -420,7 +420,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// </param> /// </param>
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns> /// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
HtmlString TextArea(string name, string value, int rows, int columns, object htmlAttributes); HtmlString TextArea(string name, string value, int rows, int columns, object htmlAttributes);
/// <summary> /// <summary>
/// Render an input element of type "text". /// Render an input element of type "text".
/// </summary> /// </summary>
@ -444,7 +444,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// <param name="modelName">The name of the property that is being validated.</param> /// <param name="modelName">The name of the property that is being validated.</param>
/// <param name="message">The message to be displayed. This will always be visible but client-side /// <param name="message">The message to be displayed. This will always be visible but client-side
/// validation may update the associated CSS class.</param> /// validation may update the associated CSS class.</param>
/// <param name="htmlAttributes"> An object that contains the HTML attributes to set for the element. /// <param name="htmlAttributes"> An object that contains the HTML attributes to set for the element.
/// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes. /// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param> /// </param>
/// <param name="tag">The tag to wrap the <paramref name="message"/> in the generated HTML. /// <param name="tag">The tag to wrap the <paramref name="message"/> in the generated HTML.

View File

@ -9,6 +9,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
{ {
ViewEngineResult FindView([NotNull] IDictionary<string, object> context, [NotNull] string viewName); ViewEngineResult FindView([NotNull] IDictionary<string, object> context, [NotNull] string viewName);
ViewEngineResult FindPartialView([NotNull] IDictionary<string, object> context, [NotNull] string partialViewName); ViewEngineResult FindPartialView(
[NotNull] IDictionary<string, object> context,
[NotNull] string partialViewName);
} }
} }

View File

@ -50,7 +50,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
if (string.IsNullOrEmpty(rule.ValidationType)) if (string.IsNullOrEmpty(rule.ValidationType))
{ {
throw new ArgumentException( throw new ArgumentException(
Resources.FormatUnobtrusiveJavascript_ValidationTypeCannotBeEmpty(rule.GetType().FullName), "rule"); Resources.FormatUnobtrusiveJavascript_ValidationTypeCannotBeEmpty(rule.GetType().FullName),
"rule");
} }
if (resultsDictionary.ContainsKey(dictionaryKey)) if (resultsDictionary.ContainsKey(dictionaryKey))
@ -72,7 +73,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
if (string.IsNullOrEmpty(key)) if (string.IsNullOrEmpty(key))
{ {
throw new InvalidOperationException( throw new InvalidOperationException(
Resources.FormatUnobtrusiveJavascript_ValidationParameterCannotBeEmpty(rule.GetType().FullName)); Resources.FormatUnobtrusiveJavascript_ValidationParameterCannotBeEmpty(
rule.GetType().FullName));
} }
if (!char.IsLower(key[0]) || key.Any(c => !char.IsLower(c) && !char.IsDigit(c))) if (!char.IsLower(key[0]) || key.Any(c => !char.IsLower(c) && !char.IsDigit(c)))

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
get { return View != null; } get { return View != null; }
} }
public static ViewEngineResult NotFound([NotNull] string viewName, public static ViewEngineResult NotFound([NotNull] string viewName,
[NotNull] IEnumerable<string> searchedLocations) [NotNull] IEnumerable<string> searchedLocations)
{ {
return new ViewEngineResult return new ViewEngineResult

View File

@ -8,7 +8,10 @@ namespace Microsoft.AspNet.Mvc
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public abstract class RouteConstraintAttribute : Attribute public abstract class RouteConstraintAttribute : Attribute
{ {
protected RouteConstraintAttribute([NotNull]string routeKey, [NotNull]string routeValue, bool blockNonAttributedActions) protected RouteConstraintAttribute(
[NotNull]string routeKey,
[NotNull]string routeValue,
bool blockNonAttributedActions)
{ {
RouteKey = routeKey; RouteKey = routeKey;
RouteValue = routeValue; RouteValue = routeValue;

View File

@ -124,12 +124,12 @@ namespace Microsoft.AspNet.Mvc
if (routeValues == null) if (routeValues == null)
{ {
throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull( throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull(
"Values", "Values",
typeof(RouteData)), typeof(RouteData)),
"context"); "context");
} }
return Accept(routeValues); return Accept(routeValues);
} }
} }
} }

View File

@ -3,7 +3,8 @@
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
// This needs more thought, the intent is that we would be able to cache over this constraint without running the accept method. // This needs more thought, the intent is that we would be able to cache over this constraint
// without running the accept method.
public enum RouteKeyHandling public enum RouteKeyHandling
{ {
/// <summary> /// <summary>

View File

@ -26,7 +26,13 @@ namespace Microsoft.AspNet.Mvc
_actionSelector = actionSelector; _actionSelector = actionSelector;
} }
public string Action(string action, string controller, object values, string protocol, string host, string fragment) public string Action(
string action,
string controller,
object values,
string protocol,
string host,
string fragment)
{ {
var valuesDictionary = TypeHelper.ObjectToDictionary(values); var valuesDictionary = TypeHelper.ObjectToDictionary(values);

View File

@ -8,11 +8,11 @@ namespace Microsoft.AspNet.Mvc
public static string Action([NotNull] this IUrlHelper helper) public static string Action([NotNull] this IUrlHelper helper)
{ {
return helper.Action( return helper.Action(
action: null, action: null,
controller: null, controller: null,
values: null, values: null,
protocol: null, protocol: null,
host: null, host: null,
fragment: null); fragment: null);
} }
@ -37,21 +37,21 @@ namespace Microsoft.AspNet.Mvc
} }
public static string Action( public static string Action(
[NotNull] this IUrlHelper helper, [NotNull] this IUrlHelper helper,
string action, string action,
string controller, string controller,
object values, object values,
string protocol) string protocol)
{ {
return helper.Action(action, controller, values, protocol, host: null, fragment: null); return helper.Action(action, controller, values, protocol, host: null, fragment: null);
} }
public static string Action( public static string Action(
[NotNull] this IUrlHelper helper, [NotNull] this IUrlHelper helper,
string action, string action,
string controller, string controller,
object values, object values,
string protocol, string protocol,
string host) string host)
{ {
return helper.Action(action, controller, values, protocol, host, fragment: null); return helper.Action(action, controller, values, protocol, host, fragment: null);
@ -72,16 +72,21 @@ namespace Microsoft.AspNet.Mvc
return helper.RouteUrl(routeName, values, protocol: null, host: null, fragment: null); return helper.RouteUrl(routeName, values, protocol: null, host: null, fragment: null);
} }
public static string RouteUrl([NotNull] this IUrlHelper helper, string routeName, object values, string protocol) public static string RouteUrl(
[NotNull] this IUrlHelper helper,
string routeName,
object values,
string protocol)
{ {
return helper.RouteUrl(routeName, values, protocol, host: null, fragment: null); return helper.RouteUrl(routeName, values, protocol, host: null, fragment: null);
} }
public static string RouteUrl([NotNull] this IUrlHelper helper, public static string RouteUrl(
string routeName, [NotNull] this IUrlHelper helper,
object values, string routeName,
string protocol, object values,
string host) string protocol,
string host)
{ {
return helper.RouteUrl(routeName, values, protocol, host, fragment: null); return helper.RouteUrl(routeName, values, protocol, host, fragment: null);
} }

View File

@ -18,8 +18,8 @@ namespace Microsoft.AspNet.Mvc
private readonly object[] _args; private readonly object[] _args;
public DefaultViewComponentInvoker( public DefaultViewComponentInvoker(
[NotNull] IServiceProvider serviceProvider, [NotNull] IServiceProvider serviceProvider,
[NotNull] TypeInfo componentType, [NotNull] TypeInfo componentType,
object[] args) object[] args)
{ {
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
@ -72,7 +72,7 @@ namespace Microsoft.AspNet.Mvc
private object CreateComponent([NotNull] ViewContext context) private object CreateComponent([NotNull] ViewContext context)
{ {
var activator = _serviceProvider.GetService<ITypeActivator>(); var activator = _serviceProvider.GetService<ITypeActivator>();
object component = activator.CreateInstance(_serviceProvider, _componentType.AsType()); var component = activator.CreateInstance(_serviceProvider, _componentType.AsType());
Injector.InjectProperty(component, "ViewContext", context); Injector.InjectProperty(component, "ViewContext", context);
@ -86,7 +86,9 @@ namespace Microsoft.AspNet.Mvc
return component; return component;
} }
private async Task<IViewComponentResult> InvokeAsyncCore([NotNull] MethodInfo method, [NotNull] ViewContext context) private async Task<IViewComponentResult> InvokeAsyncCore(
[NotNull] MethodInfo method,
[NotNull] ViewContext context)
{ {
var component = CreateComponent(context); var component = CreateComponent(context);

View File

@ -10,7 +10,8 @@ namespace Microsoft.AspNet.Mvc
{ {
private readonly INestedProviderManager<ViewComponentInvokerProviderContext> _providerManager; private readonly INestedProviderManager<ViewComponentInvokerProviderContext> _providerManager;
public DefaultViewComponentInvokerFactory(INestedProviderManager<ViewComponentInvokerProviderContext> providerManager) public DefaultViewComponentInvokerFactory(
INestedProviderManager<ViewComponentInvokerProviderContext> providerManager)
{ {
_providerManager = providerManager; _providerManager = providerManager;
} }

View File

@ -21,7 +21,8 @@ namespace Microsoft.AspNet.Mvc
public void Invoke([NotNull] ViewComponentInvokerProviderContext context, [NotNull] Action callNext) public void Invoke([NotNull] ViewComponentInvokerProviderContext context, [NotNull] Action callNext)
{ {
context.Result = new DefaultViewComponentInvoker(_serviceProvider, context.ComponentType, context.Arguments); context.Result =
new DefaultViewComponentInvoker(_serviceProvider, context.ComponentType, context.Arguments);
callNext(); callNext();
} }
} }

View File

@ -21,12 +21,12 @@ namespace Microsoft.AspNet.Mvc
var assemblies = _assemblyProvider.CandidateAssemblies; var assemblies = _assemblyProvider.CandidateAssemblies;
var types = assemblies.SelectMany(a => a.DefinedTypes); var types = assemblies.SelectMany(a => a.DefinedTypes);
var components = var components =
types types
.Where(ViewComponentConventions.IsComponent) .Where(ViewComponentConventions.IsComponent)
.Select(c => new { Name = ViewComponentConventions.GetComponentName(c), Type = c.AsType() }); .Select(c => new { Name = ViewComponentConventions.GetComponentName(c), Type = c.AsType() });
var matching = var matching =
components components
.Where(c => string.Equals(c.Name, componentName, StringComparison.OrdinalIgnoreCase)) .Where(c => string.Equals(c.Name, componentName, StringComparison.OrdinalIgnoreCase))
.ToArray(); .ToArray();

View File

@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Mvc
} }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether to indent elements when writing data. /// Gets or sets a value indicating whether to indent elements when writing data.
/// </summary> /// </summary>
public bool Indent { get; set; } public bool Indent { get; set; }

View File

@ -22,7 +22,8 @@ namespace Microsoft.AspNet.Mvc
return null; return null;
} }
if (!method.ReturnType.GetTypeInfo().IsGenericType || method.ReturnType.GetGenericTypeDefinition() != typeof(Task<>)) if (!method.ReturnType.GetTypeInfo().IsGenericType ||
method.ReturnType.GetGenericTypeDefinition() != typeof(Task<>))
{ {
throw new InvalidOperationException( throw new InvalidOperationException(
Resources.FormatViewComponent_AsyncMethod_ShouldReturnTask(AsyncMethodName)); Resources.FormatViewComponent_AsyncMethod_ShouldReturnTask(AsyncMethodName));
@ -41,7 +42,8 @@ namespace Microsoft.AspNet.Mvc
if (method.ReturnType == typeof(void)) if (method.ReturnType == typeof(void))
{ {
throw new InvalidOperationException(Resources.FormatViewComponent_SyncMethod_ShouldReturnValue(SyncMethodName)); throw new InvalidOperationException(
Resources.FormatViewComponent_SyncMethod_ShouldReturnValue(SyncMethodName));
} }
return method; return method;
@ -58,16 +60,21 @@ namespace Microsoft.AspNet.Mvc
try try
{ {
// We're currently using this technique to make a call into a component method that looks like a regular method call. // We're currently using this technique to make a call into a component method that looks like a
// regular method call.
// //
// Ex: @Component.Invoke<Cart>("hello", 5) => cart.Invoke("hello", 5) // Ex: @Component.Invoke<Cart>("hello", 5) => cart.Invoke("hello", 5)
// //
// This approach has some drawbacks, namely it doesn't account for default parameters, and more noticably, it throws // This approach has some drawbacks, namely it doesn't account for default parameters, and more
// if the method is not found. // noticably, it throws if the method is not found.
// //
// Unfortunely the overload of Type.GetMethod that we would like to use is not present in CoreCLR. Item #160 in Jira // Unfortunely the overload of Type.GetMethod that we would like to use is not present in CoreCLR.
// tracks these issues. // Item #160 in Jira tracks these issues.
var expression = Expression.Call(Expression.Constant(null, componentType.AsType()), methodName, null, argumentExpressions); var expression = Expression.Call(
Expression.Constant(null, componentType.AsType()),
methodName,
null,
argumentExpressions);
return expression.Method; return expression.Method;
} }
catch (InvalidOperationException) catch (InvalidOperationException)

View File

@ -42,8 +42,8 @@ namespace Microsoft.AspNet.Mvc
} }
else else
{ {
// This will produce a string like: // This will produce a string like:
// //
// Components/Cart/Default // Components/Cart/Default
// //
// The view engine will combine this with other path info to search paths like: // The view engine will combine this with other path info to search paths like:

View File

@ -48,7 +48,8 @@ namespace Microsoft.AspNet.Mvc
ReflectedRouteConstraintsActionDescriptorProvider>(); ReflectedRouteConstraintsActionDescriptorProvider>();
yield return describe.Transient<INestedProvider<ActionInvokerProviderContext>, yield return describe.Transient<INestedProvider<ActionInvokerProviderContext>,
ReflectedActionInvokerProvider>(); ReflectedActionInvokerProvider>();
yield return describe.Singleton<IActionDescriptorsCollectionProvider, DefaultActionDescriptorsCollectionProvider>(); yield return describe.Singleton<IActionDescriptorsCollectionProvider,
DefaultActionDescriptorsCollectionProvider>();
yield return describe.Transient<IModelMetadataProvider, DataAnnotationsModelMetadataProvider>(); yield return describe.Transient<IModelMetadataProvider, DataAnnotationsModelMetadataProvider>();
yield return describe.Transient<IActionBindingContextProvider, DefaultActionBindingContextProvider>(); yield return describe.Transient<IActionBindingContextProvider, DefaultActionBindingContextProvider>();