Property XXX is read only ?!

Vote:
 

Hi

I'm making a simple total hits counts using a property, I put thess code in the onload event, but it doesn't do the trick

 

CurrentPage["total_hits"] = Convert.ToInt32(CurrentPage["total_hits"]) + 1;

DataFactory.Instance.Save(CurrentPage, SaveAction.Publish, EPiServer.Security.AccessLevel.NoAccess);

 

then I got an error says "The property total_hits is read-only"

 

Could any1 tell me where I screw up?

 

 

#33549
Oct 15, 2009 14:54
Vote:
 

Check the method "CreateWritableClone()" in the SDK. You must create a writable clone of the page to be able to write to it. EPiServer return read-only versions of PageData objects for performance.

Can't test it but I guess this will work:

PageData writableCurrentPage = CurrentPage.CreateWritableClone();
int totalHits = Convert.ToInt32(CurrentPage["total_hits"]);
writableCurrentPage.Property["total_hits"].Value = totalHits + 1;
DataFactory.Instance.Save(writableCurrentPage, SaveAction.Publish, EPiServer.Security.AccessLevel.NoAccess);

Hope it helps

/Hans

#33565
Edited, Oct 15, 2009 20:13
Vote:
 

Exactly! I've been checking souce code from the demo project and found out that I need a writableclone then it works.

 Thx to u reply anyway.

Cheers Laughing

#33569
Oct 15, 2009 21:50
Vote:
 

A follow up question:

I read it here that someone says using property as a hits counter is a bad idea, it will lower down the performance a lot, and he suggested to use tools like Google Statistics or something. Well, in a way I understand why it lowers down the performance, but in our case, we need to use these total hits data to do things, I don't think I can get it from Google Statistics, or?

So, what's a common way to build a hits counter?

#33570
Oct 15, 2009 21:57
Vote:
 

One reason why a property is a bad way to store hits is because you will effectively disable caching. When the page is updated the cache is purged, and since you update the page on every hit it will purge the cache on every hit. Another reason is that publishing a page itself spawns a number of operations considerably heaver than reading a page from cache.

I haven't constructed a hits counter myself, but unless there are tools available I would probably use a custom database table to store the hits on a per page/language basis.

#33589
Oct 16, 2009 10:16
jo
Vote:
 

And a third reason is that the actual hitcount value is stored in the published page version..

What happens if the editor decides to go back and republish a previous version of the page..? hit count is reset to what value it had back then...

So, all in all, you should definetely store hitcount data _outside_ the pagedata.

/johan

 

#33590
Oct 16, 2009 10:23
Vote:
 

A solution with a HttpModule

Code:

using System; using System.Web; using EPiServer; using EPiServer.Core; namespace YourCompany.EPiServer.Web.HttpModules {     public class HitCounterModule : IHttpModule     {         #region Methods         public void Dispose() {}         public void Init(HttpApplication application)         {             application.PostRequestHandlerExecute += new EventHandler(this.OnPostRequestHandlerExecute);         }         #endregion         #region Eventhandlers         private void OnPostRequestHandlerExecute(Object source, EventArgs e)         {             IHttpHandler httpHandler = HttpContext.Current.Handler;             if (httpHandler != null && httpHandler is PageBase)             {                 try                 {                     PageData currentPage = (httpHandler as PageBase).CurrentPage;                     // You can now get currentPage.PageLink and the id, increase a counter, and log it somewhere, e.g in a database table. You can use log4net to log in a database table.                 }                 catch(Exception exception)                 {                     // Maybe you want to log the exception here                 }             }         }         #endregion     } }

Web.Config:
<httpModules>
    ...
    <add name="HitCounterModule" type="YourCompany.EPiServer.Web.HttpModules.HitCounterModule, YourCompany.EPiServer" />
</httpModules>

/Hans

#33593
Oct 16, 2009 10:47
Vote:
 

Thx guys

one question, if I create another table, will it bring problems when we updated Episerver? will it still work?  I heard that lots of these custom tables don't work correctly after an update. is it so?

 

 

#33598
Oct 16, 2009 11:05
jo
Vote:
 

No problem, EPiServer wont touch any custom tables.

Modifications to EPiServers own tables is another story, they might get
changed during product upgrades.

/johan

#33599
Oct 16, 2009 11:07
Vote:
 
A hits counter table would however be dependent on the structure of the episerver tables, at least the page ID (and language ID). Those might change, however that's unlikely?
#33600
Oct 16, 2009 11:09
Vote:
 

Alright, New table it is!

I don't think pageID or language ID would change, actually, once a page is created it won't be touched at all until it's deleted from the site. That's why we thought of using a property to do hits counts.

Oh, I just mentioned deleting a page, now I got another question:

When u delete a page, all the pages files are still physically there on the VPP folder, so, those files has to be removed manually? Is it designed like that on purpose?

#33601
Oct 16, 2009 11:26
Vote:
 
What I mean is that it is possible but unlikely that EPiServer in a future version would migrate to identifying pages by something other than their ID and language, for example a GUID. That would render the count table incompatible. In that way you have a depencency even if you don't modify the episerver tables or even use constraints on them.
#33602
Oct 16, 2009 11:36
jo
Vote:
 

Yeah, it might actually be a better idea to store the hitcount indexed by the page's (relative) url rather than by its id.

This would automatically "migrate" the hitcounts from an old deleted page to a new  published under the same url, which is probably a good thing. 

You might want to do a migration if a page changes its name, as that would alter its url.

/johan

 

#33603
Oct 16, 2009 11:46
This thread is locked and should be used for reference only. Please use the Episerver CMS 7 and earlier versions forum to open new discussions.