Clean up trailing whitespace in Core project
- checked and found no tabs in this project 😄
This commit is contained in:
parent
822d84a2b4
commit
84396ad875
|
|
@ -46,9 +46,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
public static Type ExtractGenericInterface([NotNull] this Type queryType, Type interfaceType)
|
||||
{
|
||||
Func<Type, bool> matchesInterface = t => t.IsGenericType() && t.GetGenericTypeDefinition() == interfaceType;
|
||||
return (matchesInterface(queryType)) ?
|
||||
queryType :
|
||||
Func<Type, bool> matchesInterface =
|
||||
t => t.IsGenericType() && t.GetGenericTypeDefinition() == interfaceType;
|
||||
return (matchesInterface(queryType)) ?
|
||||
queryType :
|
||||
queryType.GetInterfaces().FirstOrDefault(matchesInterface);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
// The Http Abstractions should take care of these.
|
||||
_httpMethods = methods.Select(method => method.ToUpperInvariant());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HTTP methods the action supports.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
RouteData = routeData;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IViewEngine _viewEngine;
|
||||
|
||||
|
||||
public ActionResultHelper(IServiceProvider serviceProvider, IViewEngine viewEngine)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
if (Content != null)
|
||||
{
|
||||
await response.WriteAsync(Content);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <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>
|
||||
public bool Indent { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
@ -12,7 +9,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
public override void ExecuteResult([NotNull] ActionContext context)
|
||||
{
|
||||
HttpResponse response = context.HttpContext.Response;
|
||||
var response = context.HttpContext.Response;
|
||||
|
||||
#if NET45
|
||||
response.StatusCode = (int)HttpStatusCode.NoContent;
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
catch
|
||||
{
|
||||
// Need to prevent writes/flushes on dispose because the StreamWriter will flush even if nothing
|
||||
// got written. This leads to a response going out on the wire prematurely in case an exception
|
||||
// is being thrown inside the try catch block.
|
||||
// Need to prevent writes/flushes on dispose because the StreamWriter will flush even if
|
||||
// nothing got written. This leads to a response going out on the wire prematurely in case an
|
||||
// exception is being thrown inside the try catch block.
|
||||
wrappedStream.BlockWrites = true;
|
||||
throw;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <returns>An HTML string corresponding to an <input type="hidden">
|
||||
/// element. This element should be put inside a <form>.</returns>
|
||||
/// <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.
|
||||
/// </remarks>
|
||||
public HtmlString GetHtml([NotNull] HttpContext context)
|
||||
{
|
||||
TagBuilder builder = _worker.GetFormInputElement(context);
|
||||
var builder = _worker.GetFormInputElement(context);
|
||||
return builder.ToHtmlString(TagRenderMode.SelfClosing);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
set;
|
||||
}
|
||||
|
||||
// TODO: Replace the stub.
|
||||
// TODO: Replace the stub.
|
||||
private static string GetAntiForgeryCookieName()
|
||||
{
|
||||
return AntiForgeryTokenFieldName;
|
||||
|
|
|
|||
|
|
@ -70,12 +70,13 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
var deserializedToken = new AntiForgeryToken();
|
||||
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();
|
||||
|
||||
if (!deserializedToken.IsSessionToken)
|
||||
{
|
||||
bool isClaimsBased = reader.ReadBoolean();
|
||||
var isClaimsBased = reader.ReadBoolean();
|
||||
if (isClaimsBased)
|
||||
{
|
||||
var claimUidBytes = reader.ReadBytes(AntiForgeryToken.ClaimUidBitLength / 8);
|
||||
|
|
@ -140,7 +141,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < base64String.Length; i++)
|
||||
for (var i = 0; i < base64String.Length; i++)
|
||||
{
|
||||
switch (base64String[i])
|
||||
{
|
||||
|
|
@ -165,7 +166,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
private byte[] UrlTokenDecode(string input)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
for (var i = 0; i < input.Length; i++)
|
||||
{
|
||||
switch (input[i])
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
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.
|
||||
// In such cases a call to GetTokens would return a token set with null cookie token.
|
||||
public string CookieToken { get; private set; }
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
private readonly IAntiForgeryConfig _config;
|
||||
private readonly IAntiForgeryTokenSerializer _serializer;
|
||||
|
||||
internal AntiForgeryTokenStore([NotNull] IAntiForgeryConfig config,
|
||||
internal AntiForgeryTokenStore([NotNull] IAntiForgeryConfig config,
|
||||
[NotNull] IAntiForgeryTokenSerializer serializer)
|
||||
{
|
||||
_config = config;
|
||||
|
|
@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
public AntiForgeryToken GetCookieToken(HttpContext httpContext)
|
||||
{
|
||||
var cookie = httpContext.Request.Cookies[_config.CookieName];
|
||||
if (String.IsNullOrEmpty(cookie))
|
||||
if (string.IsNullOrEmpty(cookie))
|
||||
{
|
||||
// did not exist
|
||||
return null;
|
||||
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
public async Task<AntiForgeryToken> GetFormTokenAsync(HttpContext httpContext)
|
||||
{
|
||||
var form = await httpContext.Request.GetFormAsync();
|
||||
string value = form[_config.FormFieldName];
|
||||
var value = form[_config.FormFieldName];
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
// did not exist
|
||||
|
|
@ -47,7 +47,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
public void SaveCookieToken(HttpContext httpContext, AntiForgeryToken token)
|
||||
{
|
||||
string serializedToken = _serializer.Serialize(token);
|
||||
var serializedToken = _serializer.Serialize(token);
|
||||
var options = new CookieOptions() { HttpOnly = true };
|
||||
|
||||
// Note: don't use "newCookie.Secure = _config.RequireSSL;" since the default
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
: null;
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Caller will just regenerate token in case of failure.")]
|
||||
private AntiForgeryToken DeserializeTokenNoThrow(string serializedToken)
|
||||
{
|
||||
try
|
||||
|
|
@ -66,7 +65,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
if (httpContext != null)
|
||||
{
|
||||
ClaimsPrincipal user = httpContext.User;
|
||||
var user = httpContext.User;
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
|
|
@ -79,7 +78,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
return null;
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Caller will just regenerate token in case of failure.")]
|
||||
private AntiForgeryToken GetCookieTokenNoThrow(HttpContext httpContext)
|
||||
{
|
||||
try
|
||||
|
|
@ -137,7 +135,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
public AntiForgeryTokenSet GetTokens([NotNull] HttpContext httpContext, string serializedOldCookieToken)
|
||||
{
|
||||
CheckSSLConfig(httpContext);
|
||||
AntiForgeryToken oldCookieToken = DeserializeTokenNoThrow(serializedOldCookieToken);
|
||||
var oldCookieToken = DeserializeTokenNoThrow(serializedOldCookieToken);
|
||||
var tokenSet = GetTokens(httpContext, oldCookieToken);
|
||||
|
||||
var serializedNewCookieToken = Serialize(tokenSet.CookieToken);
|
||||
|
|
@ -156,7 +154,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
Contract.Assert(_validator.IsCookieTokenValid(oldCookieToken));
|
||||
|
||||
AntiForgeryToken formToken = _generator.GenerateFormToken(
|
||||
var formToken = _generator.GenerateFormToken(
|
||||
httpContext,
|
||||
ExtractIdentity(httpContext),
|
||||
oldCookieToken);
|
||||
|
|
@ -201,7 +199,11 @@ namespace Microsoft.AspNet.Mvc
|
|||
var deserializedFormToken = DeserializeToken(formToken);
|
||||
|
||||
// Validate
|
||||
_validator.ValidateTokens(httpContext, ExtractIdentity(httpContext), deserializedCookieToken, deserializedFormToken);
|
||||
_validator.ValidateTokens(
|
||||
httpContext,
|
||||
ExtractIdentity(httpContext),
|
||||
deserializedCookieToken,
|
||||
deserializedFormToken);
|
||||
}
|
||||
|
||||
private class AntiForgeryTokenSetInternal
|
||||
|
|
|
|||
|
|
@ -48,13 +48,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by debugger.")]
|
||||
private string DebuggerString
|
||||
{
|
||||
get
|
||||
{
|
||||
StringBuilder sb = new StringBuilder("0x", 2 + (_data.Length * 2));
|
||||
for (int i = 0; i < _data.Length; i++)
|
||||
var sb = new StringBuilder("0x", 2 + (_data.Length * 2));
|
||||
for (var i = 0; i < _data.Length; i++)
|
||||
{
|
||||
sb.AppendFormat(CultureInfo.InvariantCulture, "{0:x2}", _data[i]);
|
||||
}
|
||||
|
|
@ -93,14 +92,14 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
private static byte[] GenerateNewToken(int bitLength)
|
||||
{
|
||||
byte[] data = new byte[bitLength / 8];
|
||||
var data = new byte[bitLength / 8];
|
||||
CryptRand.FillBuffer(new ArraySegment<byte>(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.
|
||||
[MethodImplAttribute(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
|
||||
[MethodImplAttribute(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
|
||||
private static bool AreByteArraysEqual(byte[] a, byte[] b)
|
||||
{
|
||||
if (a == null || b == null || a.Length != b.Length)
|
||||
|
|
@ -108,8 +107,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
return false;
|
||||
}
|
||||
|
||||
bool areEqual = true;
|
||||
for (int i = 0; i < a.Length; i++)
|
||||
var areEqual = true;
|
||||
for (var i = 0; i < a.Length; i++)
|
||||
{
|
||||
areEqual &= (a[i] == b[i]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
var uniqueIdentifierParameters = GetUniqueIdentifierParameters(claimsIdentity);
|
||||
byte[] claimUidBytes = ComputeSHA256(uniqueIdentifierParameters);
|
||||
var claimUidBytes = ComputeSHA256(uniqueIdentifierParameters);
|
||||
return Convert.ToBase64String(claimUidBytes);
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Given a cookie token, generates a corresponding form token.
|
||||
// The incoming cookie token must be valid.
|
||||
AntiForgeryToken GenerateFormToken(HttpContext httpContext, ClaimsIdentity identity, AntiForgeryToken cookieToken);
|
||||
AntiForgeryToken GenerateFormToken(
|
||||
HttpContext httpContext,
|
||||
ClaimsIdentity identity,
|
||||
AntiForgeryToken cookieToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
bool IsCookieTokenValid(AntiForgeryToken cookieToken);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
private readonly IAntiForgeryConfig _config;
|
||||
private readonly IAntiForgeryAdditionalDataProvider _additionalDataProvider;
|
||||
|
||||
internal TokenProvider(IAntiForgeryConfig config,
|
||||
internal TokenProvider(IAntiForgeryConfig config,
|
||||
IClaimUidExtractor claimUidExtractor,
|
||||
IAntiForgeryAdditionalDataProvider additionalDataProvider)
|
||||
{
|
||||
|
|
@ -33,7 +33,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
};
|
||||
}
|
||||
|
||||
public AntiForgeryToken GenerateFormToken(HttpContext httpContext,
|
||||
public AntiForgeryToken GenerateFormToken(HttpContext httpContext,
|
||||
ClaimsIdentity identity,
|
||||
AntiForgeryToken cookieToken)
|
||||
{
|
||||
|
|
@ -45,7 +45,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
IsSessionToken = false
|
||||
};
|
||||
|
||||
bool isIdentityAuthenticated = false;
|
||||
var isIdentityAuthenticated = false;
|
||||
|
||||
// populate Username and ClaimUid
|
||||
if (identity != null && identity.IsAuthenticated)
|
||||
|
|
@ -82,22 +82,29 @@ namespace Microsoft.AspNet.Mvc
|
|||
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?
|
||||
if (sessionToken == null)
|
||||
{
|
||||
throw new InvalidOperationException(Resources.FormatAntiForgeryToken_CookieMissing(_config.CookieName));
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatAntiForgeryToken_CookieMissing(_config.CookieName));
|
||||
}
|
||||
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?
|
||||
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?
|
||||
|
|
@ -107,7 +114,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
// Is the incoming token meant for the current user?
|
||||
string currentUsername = string.Empty;
|
||||
var currentUsername = string.Empty;
|
||||
BinaryBlob currentClaimUid = null;
|
||||
|
||||
if (identity != null && identity.IsAuthenticated)
|
||||
|
|
@ -121,13 +128,14 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// OpenID and other similar authentication schemes use URIs for the username.
|
||||
// These should be treated as case-sensitive.
|
||||
bool useCaseSensitiveUsernameComparison = currentUsername.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
|
||||
|| currentUsername.StartsWith("https://", StringComparison.OrdinalIgnoreCase);
|
||||
var useCaseSensitiveUsernameComparison =
|
||||
currentUsername.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
|
||||
currentUsername.StartsWith("https://", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (!String.Equals(fieldToken.Username,
|
||||
currentUsername,
|
||||
(useCaseSensitiveUsernameComparison) ?
|
||||
StringComparison.Ordinal :
|
||||
StringComparison.Ordinal :
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
|
|
@ -140,7 +148,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
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)
|
||||
{
|
||||
return actionDescript.RouteConstraints.Any(rc => string.Equals(rc.RouteKey, routeKey, StringComparison.OrdinalIgnoreCase));
|
||||
return actionDescript.RouteConstraints.Any(
|
||||
rc => string.Equals(rc.RouteKey, routeKey, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,7 +42,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
private ActionDescriptorsCollection GetCollection()
|
||||
{
|
||||
var actionDescriptorProvider = _serviceProvider.GetService<INestedProviderManager<ActionDescriptorProviderContext>>();
|
||||
var actionDescriptorProvider =
|
||||
_serviceProvider.GetService<INestedProviderManager<ActionDescriptorProviderContext>>();
|
||||
var actionDescriptorProviderContext = new ActionDescriptorProviderContext();
|
||||
|
||||
actionDescriptorProvider.Invoke(actionDescriptorProviderContext);
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
!method.IsConstructor &&
|
||||
!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).
|
||||
!method.IsSpecialName &&
|
||||
!method.IsDefined(typeof(NonActionAttribute));
|
||||
|
|
@ -98,7 +98,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var supportedHttpMethods =
|
||||
_supportedHttpMethodsByConvention.FirstOrDefault(
|
||||
httpMethod => methodInfo.Name.Equals(httpMethod, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
|
||||
if (supportedHttpMethods != null)
|
||||
{
|
||||
yield return supportedHttpMethods;
|
||||
|
|
@ -128,7 +128,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var actionAttributes = GetActionCustomAttributes(methodInfo);
|
||||
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.
|
||||
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 httpMethods = GetSupportedHttpMethods(methodInfo);
|
||||
|
|
@ -165,8 +167,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
// 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.
|
||||
// If there are existing action infos with http constraints for GET and POST, this action info is not added for default method.
|
||||
// Only constraints (out of GET and POST) for which there are no convention based actions available are
|
||||
// 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))
|
||||
{
|
||||
var existingHttpMethods = new HashSet<string>();
|
||||
|
|
|
|||
|
|
@ -64,12 +64,17 @@ namespace Microsoft.AspNet.Mvc
|
|||
throw new ArgumentNullException("descriptor");
|
||||
}
|
||||
|
||||
return (descriptor.RouteConstraints == null || descriptor.RouteConstraints.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)));
|
||||
return (descriptor.RouteConstraints == null ||
|
||||
descriptor.RouteConstraints.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>();
|
||||
foreach (var action in candidates)
|
||||
|
|
@ -90,7 +95,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
continue;
|
||||
}
|
||||
|
||||
if (await actionBindingContext.ValueProvider.ContainsPrefixAsync(parameter.ParameterBindingInfo.Prefix))
|
||||
if (await actionBindingContext.ValueProvider.ContainsPrefixAsync(
|
||||
parameter.ParameterBindingInfo.Prefix))
|
||||
{
|
||||
candidate.FoundParameters++;
|
||||
if (parameter.IsOptional)
|
||||
|
|
@ -122,7 +128,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
.OrderByDescending(g => g.Key)
|
||||
.First();
|
||||
|
||||
var fewestOptionalParameters =
|
||||
var fewestOptionalParameters =
|
||||
mostParametersSatisfied
|
||||
.GroupBy(c => c.FoundOptionalParameters)
|
||||
.OrderBy(g => g.Key).First()
|
||||
|
|
@ -151,7 +157,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
var actions =
|
||||
GetActions().Where(
|
||||
action =>
|
||||
action =>
|
||||
action.RouteConstraints == null ||
|
||||
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
|
||||
// values and ambient route values.
|
||||
//
|
||||
// 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
|
||||
// by this method are used by the link generation code to manipulate the route values so that routes that
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//
|
||||
// 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'
|
||||
// actions ordered by the most total constraints matched, then the most constraints matched by ambient values.
|
||||
// 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' 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).
|
||||
// ambient values = { area = "Admin", controller = "Home", action = "Diagnostics" }
|
||||
// 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
|
||||
// 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.
|
||||
|
||||
var actions = GetActions();
|
||||
|
|
@ -209,7 +216,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
continue;
|
||||
}
|
||||
|
||||
bool isActionValid = true;
|
||||
var isActionValid = true;
|
||||
foreach (var constraint in action.RouteConstraints)
|
||||
{
|
||||
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
|
||||
// descriptor providers.
|
||||
//
|
||||
//
|
||||
// Ex: These are not in the same equivalence class.
|
||||
// Action 1: constraint keys - { action, controller, area }
|
||||
// Action 2: constraint keys - { action, module }
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
"actionContext");
|
||||
}
|
||||
|
||||
var controller = _activator.CreateInstance(_serviceProvider, actionDescriptor.ControllerDescriptor.ControllerTypeInfo.AsType());
|
||||
var controller = _activator.CreateInstance(
|
||||
_serviceProvider,
|
||||
actionDescriptor.ControllerDescriptor.ControllerTypeInfo.AsType());
|
||||
|
||||
InitializeController(controller, actionContext);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
public ParameterDescriptor GetDescriptor(ParameterInfo parameter)
|
||||
{
|
||||
bool isFromBody = IsFromBody(parameter);
|
||||
var isFromBody = IsFromBody(parameter);
|
||||
|
||||
return new ParameterDescriptor
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace System.Collections.Generic
|
|||
{
|
||||
Contract.Assert(values != null);
|
||||
|
||||
T[] array = values as T[];
|
||||
var array = values as T[];
|
||||
if (array == null)
|
||||
{
|
||||
array = values.ToArray();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ using System.Threading.Tasks;
|
|||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
[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; }
|
||||
|
||||
|
|
@ -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);
|
||||
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);
|
||||
if (!context.Cancel)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
public class AuthorizationContext : FilterContext
|
||||
{
|
||||
public AuthorizationContext(
|
||||
[NotNull] ActionContext actionContext,
|
||||
[NotNull] ActionContext actionContext,
|
||||
[NotNull] IList<IFilter> filters)
|
||||
: base(actionContext, filters)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ using System.Threading.Tasks;
|
|||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
[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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
_claims = new Claim[0];
|
||||
}
|
||||
|
||||
public AuthorizeAttribute([NotNull]IEnumerable<Claim> claims)
|
||||
|
||||
public AuthorizeAttribute([NotNull]IEnumerable<Claim> claims)
|
||||
{
|
||||
_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
|
||||
if (_claims.Length == 0)
|
||||
{
|
||||
var userIsAnonymous =
|
||||
user == null ||
|
||||
user.Identity == null ||
|
||||
var userIsAnonymous =
|
||||
user == null ||
|
||||
user.Identity == null ||
|
||||
!user.Identity.IsAuthenticated;
|
||||
|
||||
if (userIsAnonymous && !HasAllowAnonymous(context))
|
||||
|
|
@ -58,13 +58,14 @@ namespace Microsoft.AspNet.Mvc
|
|||
Fail(context);
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
var authorizationService = httpContext.RequestServices.GetService<IAuthorizationService>();
|
||||
|
||||
if (authorizationService == null)
|
||||
{
|
||||
throw new InvalidOperationException(Resources.AuthorizeAttribute_AuthorizationServiceMustBeDefined);
|
||||
throw new InvalidOperationException(
|
||||
Resources.AuthorizeAttribute_AuthorizationServiceMustBeDefined);
|
||||
}
|
||||
|
||||
var authorized = await authorizationService.AuthorizeAsync(_claims, user);
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ namespace Microsoft.AspNet.Mvc.Filters
|
|||
{
|
||||
// If the controller implements a filter, and doesn't specify order, then it should
|
||||
// run closest to the action.
|
||||
int order = Int32.MaxValue;
|
||||
var order = Int32.MaxValue;
|
||||
var orderedControllerFilter = controllerFilter as IOrderedFilter;
|
||||
if (orderedControllerFilter != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
private Exception _exception;
|
||||
private ExceptionDispatchInfo _exceptionDispatchInfo;
|
||||
|
||||
public ExceptionContext([NotNull] ActionContext actionContext, [NotNull] IList<IFilter> filters)
|
||||
public ExceptionContext([NotNull] ActionContext actionContext, [NotNull] IList<IFilter> filters)
|
||||
: base(actionContext, filters)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual Exception Exception
|
||||
public virtual Exception Exception
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
@ -38,10 +38,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
public virtual ExceptionDispatchInfo ExceptionDispatchInfo
|
||||
public virtual ExceptionDispatchInfo ExceptionDispatchInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
get
|
||||
{
|
||||
return _exceptionDispatchInfo;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
public abstract class FilterContext : ActionContext
|
||||
{
|
||||
public FilterContext(
|
||||
[NotNull] ActionContext actionContext,
|
||||
[NotNull] IList<IFilter> filters)
|
||||
[NotNull] ActionContext actionContext,
|
||||
[NotNull] IList<IFilter> filters)
|
||||
: base(actionContext)
|
||||
{
|
||||
Filters = filters;
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
private ExceptionDispatchInfo _exceptionDispatchInfo;
|
||||
|
||||
public ResultExecutedContext(
|
||||
[NotNull] ActionContext actionContext,
|
||||
[NotNull] ActionContext actionContext,
|
||||
[NotNull] IList<IFilter> filters,
|
||||
[NotNull] IActionResult result)
|
||||
[NotNull] IActionResult result)
|
||||
: base(actionContext, filters)
|
||||
{
|
||||
Result = result;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
if (context.Result == null)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Routing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Routing;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
string Content(string contentPath);
|
||||
|
||||
bool IsLocalUrl(string url);
|
||||
|
||||
|
||||
string RouteUrl(string routeName, object values, string protocol, string host, string fragment);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
var type = obj.GetType();
|
||||
|
||||
var initializeMethod =
|
||||
var initializeMethod =
|
||||
type.GetRuntimeMethods()
|
||||
.FirstOrDefault(m => m.Name.Equals("Initialize", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
return;
|
||||
}
|
||||
|
||||
var args =
|
||||
var args =
|
||||
initializeMethod.GetParameters()
|
||||
.Select(p => services.GetService(p.ParameterType))
|
||||
.ToArray();
|
||||
|
|
@ -31,7 +31,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
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();
|
||||
|
||||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -15,20 +15,20 @@ namespace Microsoft.AspNet.Mvc
|
|||
// Delegate type for a by-ref property getter
|
||||
private delegate TValue ByRefFunc<TDeclaringType, TValue>(ref TDeclaringType arg);
|
||||
|
||||
private static readonly MethodInfo CallPropertyGetterOpenGenericMethod =
|
||||
private static readonly MethodInfo CallPropertyGetterOpenGenericMethod =
|
||||
typeof(PropertyHelper).GetTypeInfo().GetDeclaredMethod("CallPropertyGetter");
|
||||
|
||||
private static readonly MethodInfo CallPropertyGetterByReferenceOpenGenericMethod =
|
||||
typeof(PropertyHelper).GetTypeInfo().GetDeclaredMethod("CallPropertyGetterByReference");
|
||||
|
||||
private static readonly ConcurrentDictionary<Type, PropertyHelper[]> ReflectionCache =
|
||||
private static readonly ConcurrentDictionary<Type, PropertyHelper[]> ReflectionCache =
|
||||
new ConcurrentDictionary<Type, PropertyHelper[]>();
|
||||
|
||||
private readonly Func<object, object> _valueGetter;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a fast property helper.
|
||||
///
|
||||
/// Initializes a fast property helper.
|
||||
///
|
||||
/// This constructor does not cache the helper. For caching, use GetProperties.
|
||||
/// </summary>
|
||||
public PropertyHelper(PropertyInfo property)
|
||||
|
|
@ -47,11 +47,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <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)
|
||||
{
|
||||
return GetProperties(instance, CreateInstance, ReflectionCache);
|
||||
|
|
@ -63,7 +64,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <param name="propertyInfo">propertyInfo to extract the getter for.</param>
|
||||
/// <returns>a fast getter.</returns>
|
||||
/// <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.
|
||||
/// </remarks>
|
||||
public static Func<object, object> MakeFastPropertyGetter(PropertyInfo propertyInfo)
|
||||
|
|
@ -87,19 +88,22 @@ namespace Microsoft.AspNet.Mvc
|
|||
// Create a delegate (ref TDeclaringType) -> TValue
|
||||
var delegateType = typeof(ByRefFunc<,>).MakeGenericType(typeInput, typeOutput);
|
||||
var propertyGetterAsFunc = getMethod.CreateDelegate(delegateType);
|
||||
var callPropertyGetterClosedGenericMethod =
|
||||
var callPropertyGetterClosedGenericMethod =
|
||||
CallPropertyGetterByReferenceOpenGenericMethod.MakeGenericMethod(typeInput, typeOutput);
|
||||
callPropertyGetterDelegate =
|
||||
callPropertyGetterClosedGenericMethod.CreateDelegate(typeof(Func<object, object>), propertyGetterAsFunc);
|
||||
callPropertyGetterDelegate =
|
||||
callPropertyGetterClosedGenericMethod.CreateDelegate(
|
||||
typeof(Func<object, object>), propertyGetterAsFunc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a delegate TDeclaringType -> TValue
|
||||
var propertyGetterAsFunc = getMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(typeInput, typeOutput));
|
||||
var callPropertyGetterClosedGenericMethod =
|
||||
var propertyGetterAsFunc =
|
||||
getMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(typeInput, typeOutput));
|
||||
var callPropertyGetterClosedGenericMethod =
|
||||
CallPropertyGetterOpenGenericMethod.MakeGenericMethod(typeInput, typeOutput);
|
||||
callPropertyGetterDelegate =
|
||||
callPropertyGetterClosedGenericMethod.CreateDelegate(typeof(Func<object, object>), propertyGetterAsFunc);
|
||||
callPropertyGetterDelegate =
|
||||
callPropertyGetterClosedGenericMethod.CreateDelegate(
|
||||
typeof(Func<object, object>), propertyGetterAsFunc);
|
||||
}
|
||||
|
||||
return (Func<object, object>)callPropertyGetterDelegate;
|
||||
|
|
@ -111,14 +115,16 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Called via reflection
|
||||
private static object CallPropertyGetterByReference<TDeclaringType, TValue>(
|
||||
ByRefFunc<TDeclaringType, TValue> getter,
|
||||
ByRefFunc<TDeclaringType, TValue> getter,
|
||||
object target)
|
||||
{
|
||||
var unboxed = (TDeclaringType)target;
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <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.
|
||||
///
|
||||
///
|
||||
/// If the object is already an <see cref="IDictionary{string, object}"/> instance, then a copy
|
||||
/// is returned.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
var ex = new InvalidOperationException(
|
||||
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);
|
||||
|
||||
throw ex;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
IEnumerable<IModelValidatorProvider> validatorProviders)
|
||||
{
|
||||
_modelMetadataProvider = modelMetadataProvider;
|
||||
_modelBinders = modelBinders.OrderBy(binder => binder.GetType() == typeof(ComplexModelDtoModelBinder) ? 1 : 0);
|
||||
_modelBinders = modelBinders.OrderBy(
|
||||
binder => binder.GetType() == typeof(ComplexModelDtoModelBinder) ? 1 : 0);
|
||||
_valueProviderFactories = valueProviderFactories;
|
||||
_inputFormatterProvider = inputFormatterProvider;
|
||||
_validatorProviders = validatorProviders;
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNet.Mvc.Core.Test")]
|
||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
IEnumerable<IFilter> globalFilters)
|
||||
{
|
||||
_controllerAssemblyProvider = controllerAssemblyProvider;
|
||||
_conventions = conventions;
|
||||
_conventions = conventions;
|
||||
_controllerDescriptorFactory = controllerDescriptorFactory;
|
||||
_parameterDescriptorFactory = parameterDescriptorFactory;
|
||||
var filters = globalFilters ?? Enumerable.Empty<IFilter>();
|
||||
|
|
@ -49,7 +49,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
var assemblies = _controllerAssemblyProvider.CandidateAssemblies;
|
||||
var types = assemblies.SelectMany(a => a.DefinedTypes);
|
||||
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)
|
||||
{
|
||||
|
|
@ -112,11 +114,15 @@ namespace Microsoft.AspNet.Mvc
|
|||
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 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)
|
||||
.OrderBy(d => d, FilterDescriptorOrderComparer.Comparer)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
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.
|
||||
private static Task<object> Convert<T>(object taskAsObject)
|
||||
|
|
@ -22,13 +23,19 @@ namespace Microsoft.AspNet.Mvc
|
|||
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());
|
||||
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;
|
||||
try
|
||||
|
|
@ -37,19 +44,27 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
catch (TargetInvocationException targetInvocationException)
|
||||
{
|
||||
// Capturing the actual exception and the original callstack and rethrow for external exception handlers to observe.
|
||||
ExceptionDispatchInfo exceptionDispatchInfo = ExceptionDispatchInfo.Capture(targetInvocationException.InnerException);
|
||||
// Capturing the exception and the original callstack and rethrow for external exception handlers.
|
||||
var exceptionDispatchInfo = ExceptionDispatchInfo.Capture(targetInvocationException.InnerException);
|
||||
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>.
|
||||
// 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.
|
||||
// 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>
|
||||
// must coerce the return value to Task<object>
|
||||
|
|
@ -62,7 +77,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
return await CastToObject(resultAsTask);
|
||||
}
|
||||
|
||||
Type taskValueType = TypeHelper.GetTaskInnerTypeOrNull(returnType);
|
||||
var taskValueType = TypeHelper.GetTaskInnerTypeOrNull(returnType);
|
||||
if (taskValueType != null)
|
||||
{
|
||||
// for: public Task<T> Action()
|
||||
|
|
@ -75,7 +90,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
// This will be the case for:
|
||||
// 1. Types which have derived from Task and 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
|
||||
{
|
||||
|
|
@ -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)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var arguments = new object[count];
|
||||
for (int index = 0; index < count; index++)
|
||||
for (var index = 0; index < count; index++)
|
||||
{
|
||||
var parameterInfo = declaredParameterInfos[index];
|
||||
object value;
|
||||
|
|
@ -123,7 +142,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
// This most likely indicates that the developer forgot to call Unwrap() somewhere.
|
||||
if (actualTypeReturned != typeof(Task))
|
||||
{
|
||||
Type innerTaskType = TypeHelper.GetTaskInnerTypeOrNull(actualTypeReturned);
|
||||
var innerTaskType = TypeHelper.GetTaskInnerTypeOrNull(actualTypeReturned);
|
||||
if (innerTaskType != null && typeof(Task).IsAssignableFrom(innerTaskType))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// been built for each exception. When we return from here, these frames will either:
|
||||
//
|
||||
//
|
||||
// 1) Call the filter (if we have an exception)
|
||||
// 2) No-op (if we don't have an exception)
|
||||
Contract.Assert(_exceptionContext == null);
|
||||
|
|
@ -274,12 +274,16 @@ namespace Microsoft.AspNet.Mvc
|
|||
if (parameter.BodyParameterInfo != null)
|
||||
{
|
||||
var parameterType = parameter.BodyParameterInfo.ParameterType;
|
||||
var modelMetadata = metadataProvider.GetMetadataForType(modelAccessor: null, modelType: parameterType);
|
||||
var providerContext = new InputFormatterProviderContext(actionBindingContext.ActionContext.HttpContext,
|
||||
modelMetadata,
|
||||
modelState);
|
||||
var modelMetadata = metadataProvider.GetMetadataForType(
|
||||
modelAccessor: null,
|
||||
modelType: parameterType);
|
||||
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,
|
||||
modelMetadata,
|
||||
|
|
@ -290,7 +294,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
else
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
@ -394,7 +400,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
_actionContext.Controller,
|
||||
_actionExecutingContext.ActionArguments);
|
||||
|
||||
var underlyingReturnType = TypeHelper.GetTaskInnerTypeOrNull(actionMethodInfo.ReturnType) ?? actionMethodInfo.ReturnType;
|
||||
var underlyingReturnType =
|
||||
TypeHelper.GetTaskInnerTypeOrNull(actionMethodInfo.ReturnType) ??
|
||||
actionMethodInfo.ReturnType;
|
||||
|
||||
var actionResult = CreateActionResult(
|
||||
underlyingReturnType,
|
||||
actionReturnValue);
|
||||
|
|
@ -428,7 +437,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
Contract.Assert(_resultExecutingContext != null);
|
||||
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(
|
||||
typeof(IAsyncResultFilter).Name,
|
||||
"Cancel",
|
||||
|
|
@ -448,7 +458,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
if (_resultExecutedContext == null)
|
||||
{
|
||||
// Short-circuited by not calling next
|
||||
_resultExecutedContext = new ResultExecutedContext(_resultExecutingContext, _filters, _resultExecutingContext.Result)
|
||||
_resultExecutedContext = new ResultExecutedContext(
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext.Result)
|
||||
{
|
||||
Canceled = true,
|
||||
};
|
||||
|
|
@ -456,7 +469,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
else if (_resultExecutingContext.Cancel == true)
|
||||
{
|
||||
// Short-circuited by setting Cancel == true
|
||||
_resultExecutedContext = new ResultExecutedContext(_resultExecutingContext, _filters, _resultExecutingContext.Result)
|
||||
_resultExecutedContext = new ResultExecutedContext(
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext.Result)
|
||||
{
|
||||
Canceled = true,
|
||||
};
|
||||
|
|
@ -469,7 +485,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
if (_resultExecutingContext.Cancel == true)
|
||||
{
|
||||
// Short-circuited by setting Cancel == true
|
||||
_resultExecutedContext = new ResultExecutedContext(_resultExecutingContext, _filters, _resultExecutingContext.Result)
|
||||
_resultExecutedContext = new ResultExecutedContext(
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext.Result)
|
||||
{
|
||||
Canceled = true,
|
||||
};
|
||||
|
|
@ -484,12 +503,18 @@ namespace Microsoft.AspNet.Mvc
|
|||
await InvokeActionResult();
|
||||
|
||||
Contract.Assert(_resultExecutedContext == null);
|
||||
_resultExecutedContext = new ResultExecutedContext(_resultExecutingContext, _filters, _resultExecutingContext.Result);
|
||||
_resultExecutedContext = new ResultExecutedContext(
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext.Result);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_resultExecutedContext = new ResultExecutedContext(_resultExecutingContext, _filters, _resultExecutingContext.Result)
|
||||
_resultExecutedContext = new ResultExecutedContext(
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext.Result)
|
||||
{
|
||||
ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception)
|
||||
};
|
||||
|
|
@ -502,7 +527,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
_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)
|
||||
{
|
||||
_resultExecutingContext.Result = new EmptyResult();
|
||||
|
|
@ -523,24 +548,24 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// A one-way cursor for filters.
|
||||
/// A one-way cursor for filters.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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.
|
||||
///
|
||||
///
|
||||
/// Filters are always executed in the following order, but short circuiting plays a role.
|
||||
///
|
||||
///
|
||||
/// Indentation reflects nesting.
|
||||
///
|
||||
///
|
||||
/// 1. Exception Filters
|
||||
/// 2. Authorization Filters
|
||||
/// 3. Action Filters
|
||||
/// Action
|
||||
///
|
||||
///
|
||||
/// 4. Result Filters
|
||||
/// Result
|
||||
///
|
||||
///
|
||||
/// </remarks>
|
||||
private struct FilterCursor
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ namespace Microsoft.AspNet.Mvc.Rendering.Expressions
|
|||
|
||||
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)
|
||||
{
|
||||
var typeArguments = dictionaryType.GetGenericArguments();
|
||||
|
|
|
|||
|
|
@ -174,7 +174,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
|
||||
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) ?
|
||||
string.Empty :
|
||||
html.ViewData.TemplateInfo.FormattedModelValue.ToString();
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
}
|
||||
|
||||
var htmlAttributes = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{
|
||||
{ "class", className }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
public HtmlHelper(
|
||||
[NotNull] IViewEngine viewEngine,
|
||||
[NotNull] IModelMetadataProvider metadataProvider,
|
||||
[NotNull] IUrlHelper urlHelper,
|
||||
[NotNull] IUrlHelper urlHelper,
|
||||
[NotNull] AntiForgery antiForgeryInstance,
|
||||
[NotNull] IActionBindingContextProvider actionBindingContextProvider)
|
||||
{
|
||||
|
|
@ -118,10 +118,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// with objects of an anonymous type.
|
||||
///
|
||||
/// 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 with objects of an anonymous type.
|
||||
///
|
||||
/// If the object is already an <see cref="IDictionary{string, object}"/> instance, then it is
|
||||
/// returned as-is.
|
||||
/// </summary>
|
||||
|
|
@ -137,9 +137,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
}
|
||||
|
||||
/// <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.
|
||||
///
|
||||
///
|
||||
/// If the object is already an <see cref="IDictionary{string, object}"/> instance, then it is
|
||||
/// returned as-is.
|
||||
/// <example>
|
||||
|
|
@ -441,7 +441,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
var url = _urlHelper.RouteUrl(routeName, routeValues, protocol, hostName, fragment);
|
||||
return GenerateLink(linkText, url, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
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)
|
||||
{
|
||||
string errorText = ValidationHelpers.GetUserErrorMessageOrDefault(modelError, modelState: null);
|
||||
var errorText = ValidationHelpers.GetUserErrorMessageOrDefault(modelError, modelState: null);
|
||||
|
||||
if (!string.IsNullOrEmpty(errorText))
|
||||
{
|
||||
|
|
@ -703,7 +703,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
|
||||
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.
|
||||
// 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
|
||||
|
|
@ -717,7 +717,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
|
||||
return new HtmlString(Encode(resolvedDisplayName));
|
||||
}
|
||||
|
||||
|
||||
protected virtual HtmlString GenerateDisplayText(ModelMetadata metadata)
|
||||
{
|
||||
return new HtmlString(metadata.SimpleDisplayText);
|
||||
|
|
@ -810,7 +810,11 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
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)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
resolvedLabelText = string.IsNullOrEmpty(htmlFieldName) ?
|
||||
|
|
@ -867,7 +871,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
return HtmlString.Empty;
|
||||
}
|
||||
|
||||
TagBuilder tag = new TagBuilder("label");
|
||||
var tag = new TagBuilder("label");
|
||||
tag.Attributes.Add(
|
||||
"for",
|
||||
TagBuilder.CreateSanitizedId(
|
||||
|
|
@ -1104,7 +1108,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
ModelState modelState;
|
||||
ViewData.ModelState.TryGetValue(fullName, out modelState);
|
||||
|
||||
string value = string.Empty;
|
||||
var value = string.Empty;
|
||||
if (modelState != null && modelState.Value != null)
|
||||
{
|
||||
value = modelState.Value.AttemptedValue;
|
||||
|
|
@ -1378,7 +1382,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
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;
|
||||
metadata = metadata ??
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
|
||||
return GenerateDisplayName(metadata, expressionText);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public HtmlString DisplayTextFor<TValue>([NotNull] Expression<Func<TModel, TValue>> expression)
|
||||
{
|
||||
|
|
@ -150,7 +150,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
}
|
||||
|
||||
/// <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);
|
||||
return GenerateLabel(metadata, ExpressionHelper.GetExpressionText(expression), labelText, htmlAttributes);
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
private bool _readOnly;
|
||||
private object _additionalViewData;
|
||||
|
||||
public TemplateBuilder([NotNull] IViewEngine viewEngine,
|
||||
[NotNull] ViewContext viewContext,
|
||||
[NotNull] ViewDataDictionary viewData,
|
||||
[NotNull] ModelMetadata metadata,
|
||||
string htmlFieldName,
|
||||
string templateName,
|
||||
bool readOnly,
|
||||
public TemplateBuilder([NotNull] IViewEngine viewEngine,
|
||||
[NotNull] ViewContext viewContext,
|
||||
[NotNull] ViewDataDictionary viewData,
|
||||
[NotNull] ModelMetadata metadata,
|
||||
string htmlFieldName,
|
||||
string templateName,
|
||||
bool readOnly,
|
||||
object additionalViewData)
|
||||
{
|
||||
_viewEngine = viewEngine;
|
||||
|
|
@ -76,13 +76,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
|
||||
if (_additionalViewData != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in HtmlHelper.ObjectToDictionary(_additionalViewData))
|
||||
foreach (var kvp in HtmlHelper.ObjectToDictionary(_additionalViewData))
|
||||
{
|
||||
viewData[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
object visitedObjectsKey = _metadata.Model ?? _metadata.RealModelType;
|
||||
var visitedObjectsKey = _metadata.Model ?? _metadata.RealModelType;
|
||||
viewData.TemplateInfo.AddVisited(visitedObjectsKey);
|
||||
|
||||
var templateRenderer = new TemplateRenderer(_viewEngine, _viewContext, viewData, _templateName, _readOnly);
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
var metadata = _viewData.ModelMetadata;
|
||||
var templateHints = new string[]
|
||||
{
|
||||
_templateName,
|
||||
metadata.TemplateHint,
|
||||
_templateName,
|
||||
metadata.TemplateHint,
|
||||
metadata.DataTypeName
|
||||
};
|
||||
|
||||
|
|
@ -137,7 +137,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
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;
|
||||
|
||||
yield return fieldType.Name;
|
||||
|
|
@ -173,7 +174,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
}
|
||||
else
|
||||
{
|
||||
bool isEnumerable = typeof(IEnumerable).IsAssignableFrom(fieldType);
|
||||
var isEnumerable = typeof(IEnumerable).IsAssignableFrom(fieldType);
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
|
@ -80,7 +82,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
return ModelMetadata.DefaultOrder;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
{
|
||||
internal class HtmlAttributePropertyHelper : PropertyHelper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<Type, PropertyHelper[]> ReflectionCache =
|
||||
private static readonly ConcurrentDictionary<Type, PropertyHelper[]> ReflectionCache =
|
||||
new ConcurrentDictionary<Type, PropertyHelper[]>();
|
||||
|
||||
public static new PropertyHelper[] GetProperties(object instance)
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
/// </param>
|
||||
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
|
||||
HtmlString TextArea(string name, string value, int rows, int columns, object htmlAttributes);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Render an input element of type "text".
|
||||
/// </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="message">The message to be displayed. This will always be visible but client-side
|
||||
/// 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.
|
||||
/// </param>
|
||||
/// <param name="tag">The tag to wrap the <paramref name="message"/> in the generated HTML.
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
if (string.IsNullOrEmpty(rule.ValidationType))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
Resources.FormatUnobtrusiveJavascript_ValidationTypeCannotBeEmpty(rule.GetType().FullName), "rule");
|
||||
Resources.FormatUnobtrusiveJavascript_ValidationTypeCannotBeEmpty(rule.GetType().FullName),
|
||||
"rule");
|
||||
}
|
||||
|
||||
if (resultsDictionary.ContainsKey(dictionaryKey))
|
||||
|
|
@ -72,7 +73,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
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)))
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
get { return View != null; }
|
||||
}
|
||||
|
||||
public static ViewEngineResult NotFound([NotNull] string viewName,
|
||||
public static ViewEngineResult NotFound([NotNull] string viewName,
|
||||
[NotNull] IEnumerable<string> searchedLocations)
|
||||
{
|
||||
return new ViewEngineResult
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||
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;
|
||||
RouteValue = routeValue;
|
||||
|
|
|
|||
|
|
@ -124,12 +124,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
if (routeValues == null)
|
||||
{
|
||||
throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull(
|
||||
"Values",
|
||||
typeof(RouteData)),
|
||||
"Values",
|
||||
typeof(RouteData)),
|
||||
"context");
|
||||
}
|
||||
|
||||
return Accept(routeValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,13 @@ namespace Microsoft.AspNet.Mvc
|
|||
_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);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ namespace Microsoft.AspNet.Mvc
|
|||
public static string Action([NotNull] this IUrlHelper helper)
|
||||
{
|
||||
return helper.Action(
|
||||
action: null,
|
||||
controller: null,
|
||||
values: null,
|
||||
protocol: null,
|
||||
host: null,
|
||||
action: null,
|
||||
controller: null,
|
||||
values: null,
|
||||
protocol: null,
|
||||
host: null,
|
||||
fragment: null);
|
||||
}
|
||||
|
||||
|
|
@ -37,21 +37,21 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
public static string Action(
|
||||
[NotNull] this IUrlHelper helper,
|
||||
string action,
|
||||
string controller,
|
||||
object values,
|
||||
[NotNull] this IUrlHelper helper,
|
||||
string action,
|
||||
string controller,
|
||||
object values,
|
||||
string protocol)
|
||||
{
|
||||
return helper.Action(action, controller, values, protocol, host: null, fragment: null);
|
||||
}
|
||||
|
||||
public static string Action(
|
||||
[NotNull] this IUrlHelper helper,
|
||||
string action,
|
||||
string controller,
|
||||
object values,
|
||||
string protocol,
|
||||
[NotNull] this IUrlHelper helper,
|
||||
string action,
|
||||
string controller,
|
||||
object values,
|
||||
string protocol,
|
||||
string host)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public static string RouteUrl([NotNull] this IUrlHelper helper,
|
||||
string routeName,
|
||||
object values,
|
||||
string protocol,
|
||||
string host)
|
||||
public static string RouteUrl(
|
||||
[NotNull] this IUrlHelper helper,
|
||||
string routeName,
|
||||
object values,
|
||||
string protocol,
|
||||
string host)
|
||||
{
|
||||
return helper.RouteUrl(routeName, values, protocol, host, fragment: null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
private readonly object[] _args;
|
||||
|
||||
public DefaultViewComponentInvoker(
|
||||
[NotNull] IServiceProvider serviceProvider,
|
||||
[NotNull] TypeInfo componentType,
|
||||
[NotNull] IServiceProvider serviceProvider,
|
||||
[NotNull] TypeInfo componentType,
|
||||
object[] args)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
|
|
@ -72,7 +72,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
private object CreateComponent([NotNull] ViewContext context)
|
||||
{
|
||||
var activator = _serviceProvider.GetService<ITypeActivator>();
|
||||
object component = activator.CreateInstance(_serviceProvider, _componentType.AsType());
|
||||
var component = activator.CreateInstance(_serviceProvider, _componentType.AsType());
|
||||
|
||||
Injector.InjectProperty(component, "ViewContext", context);
|
||||
|
||||
|
|
@ -86,7 +86,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
private readonly INestedProviderManager<ViewComponentInvokerProviderContext> _providerManager;
|
||||
|
||||
public DefaultViewComponentInvokerFactory(INestedProviderManager<ViewComponentInvokerProviderContext> providerManager)
|
||||
public DefaultViewComponentInvokerFactory(
|
||||
INestedProviderManager<ViewComponentInvokerProviderContext> providerManager)
|
||||
{
|
||||
_providerManager = providerManager;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,12 +21,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
var assemblies = _assemblyProvider.CandidateAssemblies;
|
||||
var types = assemblies.SelectMany(a => a.DefinedTypes);
|
||||
|
||||
var components =
|
||||
var components =
|
||||
types
|
||||
.Where(ViewComponentConventions.IsComponent)
|
||||
.Select(c => new { Name = ViewComponentConventions.GetComponentName(c), Type = c.AsType() });
|
||||
|
||||
var matching =
|
||||
var matching =
|
||||
components
|
||||
.Where(c => string.Equals(c.Name, componentName, StringComparison.OrdinalIgnoreCase))
|
||||
.ToArray();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
/// <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>
|
||||
public bool Indent { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
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(
|
||||
Resources.FormatViewComponent_AsyncMethod_ShouldReturnTask(AsyncMethodName));
|
||||
|
|
@ -41,7 +42,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
if (method.ReturnType == typeof(void))
|
||||
{
|
||||
throw new InvalidOperationException(Resources.FormatViewComponent_SyncMethod_ShouldReturnValue(SyncMethodName));
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatViewComponent_SyncMethod_ShouldReturnValue(SyncMethodName));
|
||||
}
|
||||
|
||||
return method;
|
||||
|
|
@ -58,16 +60,21 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
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)
|
||||
//
|
||||
// This approach has some drawbacks, namely it doesn't account for default parameters, and more noticably, it throws
|
||||
// if the method is not found.
|
||||
// This approach has some drawbacks, namely it doesn't account for default parameters, and more
|
||||
// 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
|
||||
// tracks these issues.
|
||||
var expression = Expression.Call(Expression.Constant(null, componentType.AsType()), methodName, null, argumentExpressions);
|
||||
// Unfortunely the overload of Type.GetMethod that we would like to use is not present in CoreCLR.
|
||||
// Item #160 in Jira tracks these issues.
|
||||
var expression = Expression.Call(
|
||||
Expression.Constant(null, componentType.AsType()),
|
||||
methodName,
|
||||
null,
|
||||
argumentExpressions);
|
||||
return expression.Method;
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
else
|
||||
{
|
||||
// This will produce a string like:
|
||||
//
|
||||
// This will produce a string like:
|
||||
//
|
||||
// Components/Cart/Default
|
||||
//
|
||||
// The view engine will combine this with other path info to search paths like:
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
ReflectedRouteConstraintsActionDescriptorProvider>();
|
||||
yield return describe.Transient<INestedProvider<ActionInvokerProviderContext>,
|
||||
ReflectedActionInvokerProvider>();
|
||||
yield return describe.Singleton<IActionDescriptorsCollectionProvider, DefaultActionDescriptorsCollectionProvider>();
|
||||
yield return describe.Singleton<IActionDescriptorsCollectionProvider,
|
||||
DefaultActionDescriptorsCollectionProvider>();
|
||||
|
||||
yield return describe.Transient<IModelMetadataProvider, DataAnnotationsModelMetadataProvider>();
|
||||
yield return describe.Transient<IActionBindingContextProvider, DefaultActionBindingContextProvider>();
|
||||
|
|
|
|||
Loading…
Reference in New Issue