6

I need to create some helper controller actions and associated views, that I'd like to be able to (conditionally?) disable in production.

One way would be #ifdef DEBUG pragmas around the particular routes in the RegisterRoutes() body, but that's not flexible at all.

A setting in web.config would be just as good, but I'm not sure how to hook that up.

How do the established "plugin" projects like Glimpse or Phil Haack's older Route Debugger do it?

I'd rather do something simple than something YAGNI...

2 Answers 2

10
+25

You could also use a filter, eg throw this class somewhere:

    public class DebugOnlyAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(
                                           ActionExecutingContext filterContext)
        {
             #if DEBUG
             #else
                 filterContext.Result = new HttpNotFoundResult();
             #endif
        }
    }

Then you'd be able to just drop into the controller and decorate the action methods (or entire controllers) you need not to show up in production with [DebugOnly].

You could also use filterContext.HttpContext.IsDebuggingEnabled instead of the uglier #if DEBUG I'd just be inclined to use the precompiler directive since the decision is definitely not going to take any CPU cycle that way.

If instead you want a global filter to check everything against a few URLs, register it as a global filter in Global.asax:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) {

    filters.Add(new DebugActionFilter());
}

Then you can just check the URL or whatever you want against the list (App-relative path shown here):

public class DebugActionFilter : IActionFilter
{
    private List<string> DebugUrls = new List<string> {"~/Home/",
                                                        "~/Debug/"}; 
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.IsDebuggingEnabled 
            && DebugUrls.Contains(
                      filterContext
                     .HttpContext
                     .Request
                     .AppRelativeCurrentExecutionFilePath))
        {
            filterContext.Result = new HttpNotFoundResult();
        }
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2
@if (HttpContext.Current.IsDebuggingEnabled)
{
}

Class

public class UrlInformation
{
    [XmlElement(ElementName = "ActionName")]
    public string ActionName { get; set; }

    [XmlElement(ElementName = "ControllerName")]
    public string ControllerName { get; set; }

    [XmlElement(ElementName = "AreaName")]
    public string AreaName { get; set; }
}

Class for XML Serializaion

[XmlTypeAttribute(AnonymousType = true)]
public class clsUrlInformation
{
    [XmlElement("Files")]
    public List<UrlInformation> Url { get; set; }

    public clsUrlInformation()
    {
        Url = new List<UrlInformation>();
    }
}

Sample XML(Define your debug action method/controller/area names here)

<?xml version="1.0" ?>
<Url>
    <Files>
    <AreaName></AreaName>
    <ControllerName>Home</ControllerName>
    <ActionName>Index</ActionName>
    </Files>
    <Files>
    <AreaName></AreaName>
    <ControllerName></ControllerName>
    <ActionName></ActionName>
    </Files>                      
</Url>

Action Filter

public class MyActionClass : ActionFilterAttribute
{
    public override void OnActionExecuting(
                                       ActionExecutingContext filterContext)
    {

Let's say you have XML. XML contains information about Area, Action Method Name and Controller Name

var xml =
@"<?xml version=""1.0"" ?>
<Url>
    <Files>
    <AreaName></AreaName>
    <ControllerName>Home</ControllerName>
    <ActionName>Index</ActionName>
    </Files>
    <Files>
    <AreaName></AreaName>
    <ControllerName></ControllerName>
    <ActionName></ActionName>
    </Files>                      
</Url>";

Doing XML Serialization and convert XML to List of Class.

        var serializer = new XmlSerializer(typeof(clsUrlInformation),
                                 new XmlRootAttribute("Url"));
        using (var stringReader = new StringReader(xml))
        using (var reader = XmlReader.Create(stringReader))
        {
            clsUrlInformation result =
                     (clsUrlInformation)serializer.Deserialize(reader);
            RouteData Route = 
                  filterContext.Controller.ControllerContext.RouteData;
            String controller = Convert.ToString(Route.Values["controller"]);
            String action = Convert.ToString(Route.Values["action"]);
            String area = Convert.ToString(Route.DataTokens["area"]);

Comparing the current action with xml so as to show 404

            foreach (var item in result.Url)
            {
                if (HttpContext.Current.IsDebuggingEnabled    &&
                            controller == item.ControllerName &&
                                action == item.ActionName     &&
                                  area == item.AreaName)
                {
                    filterContext.Result = new HttpNotFoundResult();
                    return;
                }
            }
        }

        base.OnActionExecuting(filterContext);
    }
}

@CristiDiaconescu : Mentioning the debug urls in XML file will be more flexible. WHY? Because, later on you can make modification in your XML to increase/decrease/update the url information without making the code change and without deploying the dll. Isn't that ?

3 Comments

Your first two approaches look like Razor code, at which point it might already be too late - I'd rather have a (list of) 'debug URL(s)' that can be disabled - i.e. hitting them would return 404, not a ustom (empty?) page. However, +1 for HttpContext.Current.IsDebuggingEnabled
@CristiDiaconescu : Mentioning the debug urls in XML file will be more flexible. WHY? Because, later on you can make modification in your XML to increase/decrease/update the url information without making the code change and without deploying the dll. Isn't that ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.