c# - 是否可以从每个请求中调用一个方法

标签 c# asp.net asp.net-mvc

我正在做一个 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)

最佳答案

您可以在操作过滤器中恢复大部分(如果不是全部)信息。这里唯一缺少的可能是命名空间,但您应该能够通过访问 filterContext.Controller 对象并对其进行一些反射(reflection)来找到它。

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

    }
}

关于c# - 是否可以从每个请求中调用一个方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29492750/

相关文章:

asp.net - IIS 6 的服务器.TransferRequest

asp.net-mvc - RenderAction 与 RenderPartial 性能

c# - Web 服务网站(初学者帮助)

asp.net 成员(member)资格 IsApproved false 但仍允许登录

c# - MvcSiteMapProvider 不适用于简单的 MVC.SiteMap 文件

javascript - @jQuery 中字符串的符号

c#,设置数据源后设置datagridview列格式

c# - WCF Restful Web服务端点暴露,但方法全部返回http 404未找到c#

c# - 从 C# 编辑配置文件的基址

c# - Marshal.PtrToStructure 抛出 AccessViolationException