We have some obsolete views in our MVC 4 web project. I would like to create some statistic on how often are view files accessed, if at all. If some files are not accessed in a long time, it's possible they are obsolete.
Is it possible to get this information from IIS or windows logs?
You can use filter context before and after action finished execution
to log which view is accesss you can use following example
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
string actionName = filterContext.ActionDescriptor.ActionName;
string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName
.....
base.OnActionExecuting(filterContext);
}
form the controller and actionname you can maintain your view log's
i hope it help's you..
Related
What is the best way to capture the number of page views and update the database in MVC? I have gone through what is the best way to capture page views per user in asp.net-mvc solutions in which using action filters are suggested. But what if we want to track the pageviews for each unique parameter passed to the action method - like how stackoverflow calculates the page visits for each question ? I think, we cannot use action filters in this case as page views differs for different parameters.
Is there any solution available otherthan incrementing the database value each time the page is viewed ?
why can you not use action filters
public class MyActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var actionName = filterContext.ActionDescriptor.ActionName;
var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
var parameterICareAbout = filterContext.ActionParameters["parameterICareAbout "];
//write to database using parameterICareAbout
}
}
As for not storing value on the database everytime, you could set up a Singleton class in your app that keeps track of all these requests and then bulk writes them to the database at some cadence/ or writes to the database during the application spin down process
So I've come to understand that MVC doesn't really have a forms PageLoadevent equivalency so where do I put a code that I would like to execute every time a page loads? I'd like to check for a cookie.
Put it in the Constructor of the MVC Controller.
Or like this:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
// check for cookies!
}
I think this might fire for every action on the page if there are multiple actions on the page (for example partial views).
If you only want it to fire once you many need to check for
filterContext.IsChildAction
Like this
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
if (filterContext.IsChildAction) return;
// check for cookies!
}
Mentioned here
In ASP.NET MVC 3, what is filterContext.IsChildAction?
I'm currently revamping my application. I have a method called "Test" in my controller which is being currently being called my many pages. I've now created a new method called "TestNew" in my controller and I want few of my pages to be redirected to the new method.
It would be great if you can let me know of a quick fix that can be done at one place so that by putting some condition like
if(viewName = "abc")
then redirect to "TestNew", instead of making change across the application. I've tried doing something in
public override void OnActionExecuting(ActionExecutingContext filterContext)
but this never gets called.
Thanks in advance.
This should be really simple as per all ASP MVC books & basics:
public ActionResult Test()
{
return RedirectToAction("NewTest");
}
Hope this helps
I want to keep a log of all the requests to my MVC 3 app, including requested URL, user's ip adress, user agent, etc. Where is the best place to do this,
1) use a base controller?
2) use an action filter?
3) others?
I do this inside my BaseController. Something like this:
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
// If in Debug mode...
if (filterContext.HttpContext.IsDebuggingEnabled)
{
var message = string.Format(CultureInfo.InvariantCulture,
"Leaving {0}.{1} => {2}",
filterContext.Controller.GetType().Name,
filterContext.ActionDescriptor.ActionName.Trim(),
filterContext.Result);
Logger.Debug(message);
}
// Logs error no matter what
if (filterContext.Exception != null)
{
var message = string.Format(CultureInfo.InvariantCulture,
"Exception occured {0}.{1} => {2}",
filterContext.Controller.GetType().Name,
filterContext.ActionDescriptor.ActionName.Trim(),
filterContext.Exception.Message);
Logger.Error(message);
}
base.OnActionExecuted(filterContext);
}
Hope you get the idea.
You can also log before the action is executed using:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
An HttpModule seems like the best fit, if you ask me.
All of the data you're talking about logging is available well before any particular Controller gets invoked. So if you do logging outside of the controller, then you get to capture even those requests which are not to valid controller actions. And there's no need to clutter your controller code with something that's really a cross-cutting concern.
You can have multiple action methods triggered when rendering a single request. Consider using RenderAction on your layout page as follows:
Html.RenderAction("Navigation", "Menu")
It's worth noting that you'd then have two log entries with the same information if you choose to use action filter for logging.
since my app has a sidebar menu that gets built dynamically through an xml everytime I want to load a view I need to pass all of this parameters.
ViewData["mainItems"] = navigation.getItems();
ViewData["controller"] = controller;//this is just a string with the name of my controller
how can I avoid doing this everytime but that the parameters keep getting being retrieved and passed?
You don't really need to pass the controller name. you have it in the viewContext.
See this SO question : Find what ASP.NET MVC controller in master view
If i understand what your problem is correctly, then you might want to create a base class controller and make all your controller inherit from this base controller. Then override the OnActionExecuted event which gets fired on every action.
public class BaseController : Controller {
protected override void OnActionExecuted(ActionExecutedContext filterContext) {
ViewData["mainItems"] = navigation.getItems();
ViewData["controller"] = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
base.OnActionExecuted(filterContext);
}