MVC browser history
This is the part 5 of 5 of my implementing of a MVC Browser history
MVC browser history – idea
Browser history –2 – implementing, small bugs
Browser history 3–trying to Nuget – modifications in order to can be transformed from an application to a component
Browser history 4–NuGet again – finally Nuget deployment
Browser history–part 5–conclusions – conclusions
I want to do another small open source utilities project – MVC browser history . That seems simple at the beginning – but , yet , there are small tasks to do that are not so easy .
What does MVC browser history does? Well, keep an history of the links the user clicks through an MVC site. I must eliminate the ajax requests and Child requests – so keep the just the URL’s
So what I have learned after one hour:
Thinking process :
I must somehow maintain the url’s – either in database , either in memory – so a Repository concept came handy.
Data to be saved includes :
- URL –easy – HttpContext.Request.Url.ToString();
- Date – easy – DateTime.Now;
- UserName – not so easy – what if user not registered?
- PageName – it should belong to that, but, from a RelationalDatabase in a 3rd form, should be another table.
Named this class BrowserUserHistoryData ( rather a long name, but descriptive)
Now detailing:
URL – possible problem : differentiate between Person/Edit/1 and Person/Edit/2. It’s a feature, not a bug : browser history, not Action history. More, the User can have acces to Person/Edit/1 and NOT Person/Edit/2.
UserName – maybe Session , if not registered? (con.User.Identity.IsAuthenticated ? con.User.Identity.Name : con.Session.SessionID); , if not WebApp, then … ok, not for this time.
How to obtain the data? The global filter from http://bradwilson.typepad.com/blog/2010/07/aspnet-mvc-filters-and-statefulness.html
What to obtain ? A user history and first 5 links order by count
Programming:
Errors repaired:
- Brad Wilson put data in
context.HttpContext.Items
. Forget that is good for one request only. Thinking about how to persist and obtain data in MVC action and Global filter- and storing to Application . Made public static T AddOrRetrieveFromApplication - Adding ViewName in OnResultExecuting, not in OnResultExecuted.
- Reading data from Repository WITHOUT persisting there .
- Thinking that the Model of the page is just the list of user history. Nope, it is also the first 5 links order by count : HistoryViewModel
public class HistoryViewModel { public BrowserUserHistory UserHis; public IBrowserUserHistoryRepository rep; }
Errors not repaired:
- Not showing just HIS user browser history, but all ( not to be repaired, since Cassini changes session_id all the time) . NOT TO BE REPAIRED.
- Latest links, history himself, not show view name
What I have enjoyed:
- Programming process
- The idea that will be useful to other people
- Linq: – can be translated to database also.
public IEnumerable<KeyValuePair<string,int>> MostUsed(int Count, DateTime? date) { var data= historyMemory.Where(item =>(date==null || item.Date.Subtract(date.Value).Days == 0)).GroupBy(item=>item.Url).OrderByDescending(g=>g.Count()).Take(Count); return data.Select(i =>new KeyValuePair<string,int>( i.Key,i.Count())); }
What to do next:
- Correct the error
- Test more the application with a real application
- Make the application understandable – comments.
- Make the application publicly available
- Spread the word ( already did, but not enough).
Code can be downloaded from BrowserHistory
. Play with it – and, if you like, drop a comment.
Interesting
Two questions:
– why not use the IIS built-in logs for this? (eventually filtered etc..)
– since you used Entity Framework for the persistence, why have you implemented a repository on top of it? EF implements by itself the repository pattern (as described at http://martinfowler.com/eaaCatalog/repository.html), like most other modern O/RMs..
1. Maybe you have not access to IIS logs.
2. IIS logs does not show you the page title
3. IIS logs does not show you what request was Ajax, Partial View…
4. I did not use EF. I have use a memory based repository – that can be replaced (interface) with EF repository