// http://stackoverflow.com/questions/6852979/get-current-controller-in-view string controller = (string)this.ViewContext.RouteData.Values["controller"]; string action = (string)this.ViewContext.RouteData.Values["action"]; // can use this too: (string)this.ViewContext.Controller.ValueProvider.GetValue("action").RawValue; if (controller == "Companies" && action == "Search") { ... }
We can improve it by making it refactoring-friendly:
Type controllerType = ViewContext.Controller.GetType(); string action = (string)this.ViewContext.RouteData.Values["action"]; // can use this too: (string)this.ViewContext.Controller.ValueProvider.GetValue("action").RawValue; if (controllerType == typeof(Erp.Controllers.CompaniesController) && action == StaticReflection.GetMemberName<Erp.Controllers.CompaniesController>(m => m.Search(null)) { ... }
The refactoring enabler:
namespace Erp.Helper { // http://joelabrahamsson.com/getting-property-and-method-names-using-static-reflection-in-c/ public class StaticReflection { public static string GetMemberName<T>(System.Linq.Expressions.Expression<Func<T, object>> expression) { if (expression == null) { throw new ArgumentException( "The expression cannot be null."); } return GetMemberName(expression.Body); } public static string GetMemberName<T>(System.Linq.Expressions.Expression<Action<T>> expression) { if (expression == null) { throw new ArgumentException( "The expression cannot be null."); } return GetMemberName(expression.Body); } private static string GetMemberName(System.Linq.Expressions.Expression expression) { if (expression == null) { throw new ArgumentException( "The expression cannot be null."); } if (expression is System.Linq.Expressions.MemberExpression) { // Reference type property or field var memberExpression = (System.Linq.Expressions.MemberExpression)expression; return memberExpression.Member.Name; } if (expression is System.Linq.Expressions.MethodCallExpression) { // Reference type method var methodCallExpression = (System.Linq.Expressions.MethodCallExpression)expression; return methodCallExpression.Method.Name; } if (expression is System.Linq.Expressions.UnaryExpression) { // Property, field of method returning value type var unaryExpression = (System.Linq.Expressions.UnaryExpression)expression; return GetMemberName(unaryExpression); } throw new ArgumentException("Invalid expression"); } } }
No approach is complete if it is not wrapped in a fluent API. Now your code is completely free of string, typos could be avoided:
if (ViewContext.Controller.Verify<Erp.Controllers.CompaniesController>().IsTheContext()) { ... }
If we want to detect both controller and action:
if (ViewContext.Controller .Verify<Erp.Controllers.CompaniesController>().WithAction(m => m.Search(null)).IsTheContext()) { ... }
The supporting API:
public static class StaticReflectionExtension { public static ControllerDetector<T> Verify<T>(this System.Web.Mvc.ControllerBase controller) where T : System.Web.Mvc.ControllerBase { return new ControllerDetector<T>(controller); } } public class ControllerDetector<T> where T : System.Web.Mvc.ControllerBase { System.Web.Mvc.ControllerBase _controller; string _action = ""; public ControllerDetector(System.Web.Mvc.ControllerBase controller) { _controller = controller; } public bool IsTheContext() { return _controller.GetType() == typeof(T) && ( _action == "" || _action == (string)_controller.ValueProvider.GetValue("action").RawValue ); } public ControllerDetector<T> WithAction(System.Linq.Expressions.Expression<Func<T, object>> expression) { _action = StaticReflection.GetMemberName<T>(expression); return this; } }
Happy Coding!
No comments:
Post a Comment