1

I'm using the setup described in this SO answer: Unobtrusive AOP with Spring.Net and source based on q9114762_aop_on_mvc_controllers on GitHub to get AOP logging for my controllers.

All is great except when a controller method with optional parameters is invoked without the optional parameter.

My test methods:

using System.Web.Mvc;

public class OrderController : Controller
{
   [SetMethodInfoAsMessage]
   virtual public ActionResult Test1()
   {
       return null;
   }

    [SetMethodInfoAsMessage]
    virtual public ActionResult Test2(int someParam = 0)
    {
        return null;
    }

    [SetMethodInfoAsMessage]
    virtual public ActionResult Test3(int? someParam = 0)
    {
        return null;
    }

    [SetMethodInfoAsMessage]
    virtual public ActionResult Test4(int someParam)
    {
        return null;
    }
}

and here's the corresponding behaviour when GETting these methods from a browser:

  1. http://localhost:62376/Order/Test1 - 200 OK

  2. http://localhost:62376/Order/Test2 - 500 Internal Server Error. Server Error in '/' Application. The parameters dictionary contains an invalid entry for parameter 'someParam' for method 'System.Web.Mvc.ActionResult Test2(Int32)' in 'InheritanceAopProxy_7b93ae81d25d46529bebc7ed00ebc409'. The dictionary contains a value of type 'System.Reflection.Missing', but the parameter requires a value of type 'System.Int32'. Parameter name: parameters

  3. http://localhost:62376/Order/Test2?someParam=15 - 200 OK

  4. http://localhost:62376/Order/Test3 - 500 Internal Server Error. Server Error in '/' Application. The parameters dictionary contains an invalid entry for parameter 'someParam' for method 'System.Web.Mvc.ActionResult Test3(System.Nullable1[System.Int32])' in 'InheritanceAopProxy_7b93ae81d25d46529bebc7ed00ebc409'. The dictionary contains a value of type 'System.Reflection.Missing', but the parameter requires a value of type 'System.Nullable1[System.Int32]'. Parameter name: parameters

  5. http://localhost:62376/Order/Test3?someParam=15 - 200 OK

  6. http://localhost:62376/Order/Test4 - 500 Internal Server Error. Server Error in '/' Application. The parameters dictionary contains a null entry for parameter 'someParam' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Test4(Int32)' in 'InheritanceAopProxy_7b93ae81d25d46529bebc7ed00ebc409'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters

The last test (6.) makes sense since someParam is mandatory. But we can see from 2. and 4. that not supplying an optional parameter results in a 500. Another thing to note is the error text from 4. - An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. So according to this, 4. should work, right? (since Test3's optional parameter is nullable).

Has anyone else experienced this? Anyone have any suggestions as to a workaround (other than manually adding logging statements to the methods) ?

This is using Spring.Aop 1.3.2, Spring.Core 1.3.2, Spring.Web. 1.3.2 and Spring.Web.Mvc3 1.3.2.

EDIT: as requested, here's the advice. It simply logs out args except for passwords (we don't want those logged):

public class SetMethodInfoAsMessageAdvice : IMethodBeforeAdvice //, IThrowsAdvice
{
    private static readonly PELogger log = Log4NetHelper.GetLogger(typeof(SetMethodInfoAsMessageAdvice));

    public void Before(MethodInfo m, object[] args, object target)
    {
        ILog logger = LogManager.GetLogger(m.DeclaringType);

        string dump = args.ToJson();
        if (dump.Contains("password", StringComparison.OrdinalIgnoreCase))
            dump = "<password hidden>";

        logger.Info(m.Name + "(" + dump + ")");
   }
}
Community
  • 1
  • 1
sming
  • 801
  • 2
  • 12
  • 25
  • Can we see the advice for your SetMethodInfoAsMessage attribute? This smells like it comes either from that or Spring's proxy. – Paarth Jan 02 '15 at 02:58

0 Answers0