views:

1209

answers:

1

I seem to be encountering some funky behaviour when tracing is enabled in an ASP.NET MVC application:

Whenever tracing is enabled, the HandleError attribute fails.

I've reproduced this on the vanilla ASP.NET MVC app, and was wondering whether anyone has experienced anything similar.

Steps to Reproduce

Step 1

Create a new ASP.NET MVC application

Step 2

Turn on tracing in web.config:

<trace enabled="true" localOnly="false" pageOutput="false" requestLimit="500" traceMode="SortByTime" />

Step 3

At this point everything works fine. The home page loads:

http://localhost/MvcApplication2/

and the trace page works:

http://localhost/mvcapplication2/trace.axd

Step 4

Simulate an exception somewhere where the HandleError attribute can find it (controller action, view).

I'm throwing an exception in the Home\Index.aspx view:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="System.Threading"%>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= Html.Encode(ViewData["Message"]) %></h2>
    <p>
        To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc&lt;/a&gt;.
        <% throw new NotImplementedException(); %>
    </p>
</asp:Content>

Result

Instead of getting the a view returned by the HandleError filter (Shared\Error.aspx), I'm getting the ASP.NET CustomErrors error instead:

http://localhost/mvcapplication2/GenericErrorPage.htm?aspxerrorpath=/MvcApplication2/

Digging Deeper

Step 5

Disable tracing in web.config:

<!--<trace enabled="true" localOnly="false" pageOutput="false" requestLimit="500" traceMode="SortByTime" />-->

Result

The HandleError filter view (Shared\Error.aspx) is returned correctly:

Sorry, an error occurred while processing your request.

Observations

Going back to Step 4 and doing some debugging reveals:

  • The HandleError is being invoked correctly
  • The HandleError view (Shared\Error.aspx) is throwing an error, and that's why we're sent to the ASP.NET custom errors

Thanks, to ELMAH, here's the exception that the view is throwing:

System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Web.HttpException: Multiple controls with the same ID 'ctl00' were found. Trace requires that controls have unique IDs.
   at System.Web.TraceContext.AddNewControl(String id, String parentId, String type, Int32 viewStateSize, Int32 controlStateSize)
   at System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState)
   at System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   --- End of inner exception stack trace ---
   at System.Web.UI.Page.HandleError(Exception e)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest()
   at System.Web.UI.Page.ProcessRequest(HttpContext context)
   at ASP.views_error_internalerror_aspx.ProcessRequest(HttpContext context) in c:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\root\c3a94d6e\b487cfcc\App_Web_m5awwxof.0.cs:line 0
   at System.Web.Mvc.ViewPage.RenderView(ViewContext viewContext)
   at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

(Note that for this trace, my HandleError view is called "InternalError.aspx" instead of the default "Error.aspx")

Bug?

So the question is, do I get a cookie for finding a bug, or do I get slapped with a trout for missing something obvious?

Thank you in advance for you help!

A: 

As a follow up to this:

The issue still exists, but for the mean time I have implemented a workaround.

I have a custom HandleError attribute defined, because I am plugging in ELMAH:

How to get ELMAH to work with ASP.NET MVC [HandleError] attribute? http://stackoverflow.com/questions/766610/how-to-get-elmah-to-work-with-asp-net-mvc-handleerror-attribute

At the end of the OnException method I simply put this:

filterContext.HttpContext.Trace.IsEnabled = false;

By programatically disabling tracing for that request, I am able to avoid the hard crash.

Since the exception is being logged anyways, I also don't lose out by turning off tracing.

Martin Aatmaa