Reputation: 15
I'm working with c# mvc 5 and I have a url which writes a log. I call it in ajax in all my pages via javascript:
$.ajax({ url: log?page=index&userid=15, async: true });
Now I'm willing to log more critical data, so, for safety matters I need to remove this javascript from my pages, and instead, put it in every controller and every action of my projects.
There is a way to do this asyn in asp net mvc 5? What I want is something like this:
public ActionResult Index()
{
// I want a method that makes a post/get to some url, but don't block
// the rest of the code. I don't need any return from the post
// It would be nice to be a Post, but a Get would do the trick
PostOrGetAsync("log?page=index&userid=15");
return view();
}
Thank you in advance!
Upvotes: 0
Views: 2286
Reputation: 54638
There is a way to do this async in asp net mvc 5? What I want is something like this:
Yes. However, your url in ajax log?page=index&userid=15
does not appear to be a remote server so you can call it directly.
public async ActionResult Index()
{
// I want a method that makes a post/get to some url, but don't block
// the rest of the code. I don't need any return from the post
// It would be nice to be a Post, but a Get would do the trick
var controller = new LogController();
await controller.Log("index", 15);
return view();
}
This really isn't maintainable. To make it global requires a little bit of work. You can use an ActionFilter to globally log all calls.
public class LogActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Log("OnActionExecuting", filterContext.RouteData);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
Log("OnActionExecuted", filterContext.RouteData);
}
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
Log("OnResultExecuting", filterContext.RouteData);
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
Log("OnResultExecuted", filterContext.RouteData);
}
private void Log(string methodName, RouteData routeData)
{
var controllerName = routeData.Values["controller"];
var actionName = routeData.Values["action"];
var message = String.Format("{0} controller:{1} action:{2}",
methodName,
controllerName,
actionName);
Debug.WriteLine(message, "Action Filter Log");
}
}
You can either apply the Log to specific actions/controllers:
[LogActionFilter()]
public ActionResult Index()
{
return view();
}
or all controllers:
protected void Application_Start()
{
// Register global filter
GlobalFilters.Filters.Add(new MyActionFilterAttribute());
RegisterGlobalFilters(GlobalFilters.Filters);
}
However, asp.net-mvc does not currently support async action filters, but I don't think you need it anyway.
I need some information that is inside the method. Like, when the user is creating a new registry.
[LogActionFilter()]
public ActionResult Index()
{
SomeSharedLogic();
return view();
}
Extension Method
public static ControllerExtensions()
{
public static void SomeSharedLogic(this ControllerBase controller)
{
controller.TempData["ShareLogicValue"] = "WhateveR";
}
}
Update the log method
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var sharedLogic = filterContext.Controller.TempData["ShareLogicValue"]
as String;
var logName = "OnActionExecuted";
if (sharedLogic != null)
{
logName += ":" + sharedLogic;
}
Log(logName, filterContext.RouteData);
}
Upvotes: 1