// 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