我正在开发一个asp.net MVC项目。我们想以这种方式记录所有的动作方法调用:
namespace.controller.method(parameter1name: parameter1value, ... parameternname: parameternvalue)
这在C#或带有属性的asp.net MVC中是否可行?我的想法是ActionFilterAttribute
,但据我了解,在调用实际方法之前调用它们。
更多细节,为什么ActionFilterAttribute
在这种情况下不起作用。我们希望使用完整的.net命名空间,类名,原始方法名和所有参数来记录方法调用。
这是一个例子
namespace MyTestNamespace {
public class HomeController {
[ActionName("Index")]
[HttpGet]
public ActionResult MyCall(string username) {
ViewBag.Great = "Hello " + username;
return View();
}
}
}
日志记录输出应如下所示:
MyTestNamespace.HomeController.MyCall(username: Knerd)
但我可以使用ActionFilterAttribute
得到的日志输出是这样的:
MyTestNamespace.HomeController.Index(username: Knerd)
答案 0 :(得分:3)
您可以在动作过滤器中恢复大部分(如果不是全部)此类信息。这里唯一缺少的可能是命名空间,但你应该能够通过访问filterContext.Controller
对象并对其进行一些反思来找到它。
public class MyFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controllerName = routeData.Values["controller"];
var actionName = routeData.Values["action"];
foreach(var kvp in filterContext.ActionParameters)
//log your params
//thanks @Andy Nichols
var fullControllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerType.FullName;
}
}
在大多数情况下,路线的名称应与方法的名称相匹配。如果没有,您可以为这些路由映射设置某种全局注册表。
以下是如何执行此操作的示例。你在这里失去了一些路由可配置性,但你可以扩展它以允许它。
public static class RouteMappingConfig
{
static RouteMappingConfig () { RouteMappings = new List<RouteMapping>(); }
public static List<RouteMapping> RouteMappings { get; set; }
}
public class RouteMapping
{
public class RouteMapping(string ctrl, string action, string method) { /*...*/ }
public string Controller { get; set; }
public string Action { get; set; }
public string Method { get; set; }
}
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
//set up mappings
RouteMappingConfig.RouteMappings.Add(new RouteMapping("MyController", "MyAction", "MyMethod"));
foreach(var mapping in RouteMappingConfig.RouteMappings)
{
routes.MapRoute(
name: mapping.Controller + "_" + mapping.Action,
url: "{controller}/{action}/",
defaults: new { controller = mapping.Controller, action = mapping.Action }
);
}
}
}
public class MyFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controllerName = routeData.Values["controller"];
var actionName = routeData.Values["action"];
//thanks @Andy Nichols
var fullControllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerType.FullName;
var mapping = RouteMappingConfig.RouteMappings.SingleOrDefault(x => x.Controller == controllerName && x.Action == actionName);
string methodName = actionName;
if(mapping != null)
{
methodName = mapping.Method;
}
foreach(var kvp in filterContext.ActionParameters)
//log your params
}
}