Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Fix to special case Dispose method to be treated as non-action
Browse files Browse the repository at this point in the history
  • Loading branch information
kanchanm committed Nov 12, 2014
1 parent e9d8c84 commit 4598505
Show file tree
Hide file tree
Showing 7 changed files with 294 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +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.Collections.Generic;
using System.Linq;
using System.Reflection;
Expand All @@ -16,9 +17,9 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
public class DefaultActionModelBuilder : IActionModelBuilder
{
/// <inheritdoc />
public IEnumerable<ActionModel> BuildActionModels([NotNull] MethodInfo methodInfo)
public IEnumerable<ActionModel> BuildActionModels([NotNull] TypeInfo typeInfo, [NotNull] MethodInfo methodInfo)
{
if (!IsAction(methodInfo))
if (!IsAction(typeInfo, methodInfo))
{
return Enumerable.Empty<ActionModel>();
}
Expand Down Expand Up @@ -131,29 +132,70 @@ public IEnumerable<ActionModel> BuildActionModels([NotNull] MethodInfo methodInf
/// Returns <c>true</c> if the <paramref name="methodInfo"/> is an action. Otherwise <c>false</c>.
/// </summary>
/// <param name="methodInfo">The <see cref="MethodInfo"/>.</param>
/// <param name="typeInfo">The <see cref="TypeInfo"/>.</param>
/// <returns><c>true</c> if the <paramref name="methodInfo"/> is an action. Otherwise <c>false</c>.</returns>
/// <remarks>
/// Override this method to provide custom logic to determine which methods are considered actions.
/// </remarks>
protected virtual bool IsAction([NotNull] MethodInfo methodInfo)
protected virtual bool IsAction([NotNull] TypeInfo typeInfo, [NotNull] MethodInfo methodInfo)
{
// 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).
if (methodInfo.IsSpecialName)
{
return false;
}

if (methodInfo.IsDefined(typeof(NonActionAttribute)))
{
return false;
}

// Overriden methods from Object class, e.g. Equals(Object), GetHashCode(), etc., are not valid.
if (methodInfo.GetBaseDefinition().DeclaringType == typeof(object))
{
return false;
}

// Dispose method implemented from IDisposable is not valid
if (IsIDisposableMethod(methodInfo, typeInfo))
{
return false;
}

if (methodInfo.IsStatic)
{
return false;
}

if (methodInfo.IsAbstract)
{
return false;
}

if (methodInfo.IsConstructor)
{
return false;
}

if (methodInfo.IsGenericMethod)
{
return false;
}

return
methodInfo.IsPublic &&
!methodInfo.IsStatic &&
!methodInfo.IsAbstract &&
!methodInfo.IsConstructor &&
!methodInfo.IsGenericMethod &&

// 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).
!methodInfo.IsSpecialName &&
!methodInfo.IsDefined(typeof(NonActionAttribute)) &&

// Overriden methods from Object class, e.g. Equals(Object), GetHashCode(), etc., are not valid.
methodInfo.GetBaseDefinition().DeclaringType != typeof(object);
methodInfo.IsPublic;
}

/// <summary>
private bool IsIDisposableMethod(MethodInfo methodInfo, TypeInfo typeInfo)
{
return
(typeof(IDisposable).GetTypeInfo().IsAssignableFrom(typeInfo) &&
typeInfo.GetRuntimeInterfaceMap(typeof(IDisposable)).TargetMethods[0] == methodInfo);
}


/// <suethodandlemary>
/// Creates an <see cref="ActionModel"/> for the given <see cref="MethodInfo"/>.
/// </summary>
/// <param name="methodInfo">The <see cref="MethodInfo"/>.</param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public ControllerModel BuildControllerModel([NotNull] TypeInfo typeInfo)

foreach (var methodInfo in typeInfo.AsType().GetMethods())
{
var actionModels = _actionModelBuilder.BuildActionModels(methodInfo);
var actionModels = _actionModelBuilder.BuildActionModels(typeInfo, methodInfo);
if (actionModels != null)
{
foreach (var actionModel in actionModels)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +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.Collections.Generic;
using System.Reflection;

Expand All @@ -16,11 +17,12 @@ public interface IActionModelBuilder
/// <paramref name="methodInfo"/> is not an action method.
/// </summary>
/// <param name="methodInfo">The <see cref="MethodInfo"/>.</param>
/// <param name="typeInfo">The <see cref="TypeInfo"/>.</param>
/// <returns>A set of <see cref="ActionModel"/> or null.</returns>
/// <remarks>
/// Instances of <see cref="ActionModel"/> returned from this interface should have their
/// <see cref="ActionModel.Parameters"/> initialized.
/// </remarks>
IEnumerable<ActionModel> BuildActionModels([NotNull] MethodInfo methodInfo);
IEnumerable<ActionModel> BuildActionModels([NotNull] TypeInfo typeInfo, [NotNull] MethodInfo methodInfo);
}
}
1 change: 0 additions & 1 deletion src/Microsoft.AspNet.Mvc.Core/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,6 @@ public virtual async Task<bool> TryUpdateModelAsync<TModel>([NotNull] TModel mod
bindingContext.ValidatorProvider);
}

[NonAction]
public void Dispose()
{
Dispose(disposing: true);
Expand Down
1 change: 0 additions & 1 deletion src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,6 @@ public virtual HttpStatusCodeResult StatusCode(HttpStatusCode status)
return new HttpStatusCodeResult((int)status);
}

[NonAction]
public void Dispose()
{
Dispose(true);
Expand Down
Loading

0 comments on commit 4598505

Please sign in to comment.