Thanks for providing this module, we are using it very successfully in umbraco v4.11.8.
However, the time has come to upgrade to 6.1.4, and i have come across a couple of issues using it (the latest version 2.2.2) in our upgraded site. In order to minimise confusion, i have also installed it in a base install 6.1.4 site and observed the same issues:
1. Document moves are not being recorded by the url tracker. Having downloaded the url tracker source, traced the execution and done some independent testing, it seems that the umbraco Document BeforeMove event handler is no longer being called (not in 6.1.3 either). So i don't know if this is an Umbraco bug or not - since Document is now obsolete - but the effect is that moves are not recorded in the URL Tracker.
I then modified the url tracker source to use the new API ContentService event handlers (Publishing, Moving, Deleting) instead of Document (BeforePublish, BeforeMove, BeforeDelete) and url recording was then working as expected. Are there any plans to provide a version of the url tracker that targets the new api (i can supply my code for a start if useful to you)?
However, i then encountered the next issue:
2. The following exception is being thrown in the url tracker http module. Note, this error is only thrown in umbraco 6.1.4 - everything works as expected in 6.1.3, so this could also be an umbraco 6.1.4 issue rather than url tracker:
Server Error in '/' Application.
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 82: {
Line 83: rootNodeId = -1;
Line 84: List children = new Node(rootNodeId).ChildrenAsList;
Line 85: if (children != null && children.Any())
Line 86: rootNodeId = children.First().Id;
Source File: e:\BN\Dev\UrlTracker-master\UrlTracker\Modules\UrlTrackerModule.cs Line: 84
Stack Trace:
[NullReferenceException: Object reference not set to an instance of an object.]
umbraco.presentation.UmbracoContext.GetXml() +17
umbraco.NodeFactory.Node..ctor(Int32 NodeId) +164
InfoCaster.Umbraco.UrlTracker.Modules.UrlTrackerModule.context_EndRequest(Object sender, EventArgs e) in e:\BN\Dev\UrlTracker-master\UrlTracker\Modules\UrlTrackerModule.cs:84
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +79
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +164
From the Umbraco source, the error is coming from the following lines (UmbracoContext.cs, GetXml), where umbracoContext.ContentCache is null, hence the error:
var umbracoContext = Umbraco.Web.UmbracoContext.Current; var cache = umbracoContext.ContentCache.InnerCache as Umbraco.Web.PublishedCache.XmlPublishedCache.PublishedContentCache;
So i'm now not sure whether this is a problem due to 6.1.4 possibly requiring different methods to instantiate Node (and usage of UmbracoContext in the http module) or simply something not being initialised properly within Umbraco 6.1.4. Any ideas?
I'm afraid my hands are tied here, I don't know what I can do to fix these issues without having to create a v4 and v6 version of the package. Also I don't have a clue at all how to fix the second issue...
The issue is that the UmbracoContext and other items in the HttpContext.Items collection was not being disposed of properly at the end of the request which is doing now. The reason this exception is thrown is that the disposal will probably have already happened before the code in the UrlTrackerModule.context_EndRequest is executed.
From the looks of the code for that module, you need to get the response.StatusCode which is probably why you are executing in EndRequest, but you can get that result in the PostReleaseRequestState event which occurs before the EndRequest event. I would actually recommend the code going in that event in case there's other potential things that might need to be referenced but get disposed at the end of requests.
I've tried this out in the URL Tracker (using PostReleaseRequestState instead of EndRequest), and it seems to work well; not found requests are now being redirected appropriately. So this looks like a good solution to me, thanks very much Shannon; we also have a couple of other areas in our code that are hooked into EndRequest (and using umbraco context information) that will need to be changed over.
I'll leave this topic open until Stefan has a chance to view and comment.
Thanks for the reply Shannon, but I'm not getting the same result as Bruce. For me the PostReleaseRequestState event is not fired for 404 requests; both IntegratedPipeline 404 requests (like '/some-url') and StaticFile 404 requests (like '/some-url.htm')...
It does fire for requests to '/umbraco/webservices/legacyAjaxCalls.asmx/GetSecondsBeforeUserLogout'. Weird right?
Ok, here's a wacky idea... try keeping your module executing on EndRequest and then ensure your http module is declared higher in the web.config than the Umbraco one... see if yours fires first.
That's obviously just a hack/temp solution if it works and we'll need to figure something else out. Let me know if that does/doesnt work.
Ok well I think we'll have to create a fix for it. So what changed in 6.1.4 is:
we dispose of any object in the HttpContext.Items collection on request end so that if something has referenced an object there (like the UmbracoContext) from a static field, then it won't continue to remain in memory in a stale state, since this will cause problems down the track. Initially the reason for this was that the UmbracoContext also references an HttpContext so if someone references the UmbracoContext singleton from a static field, they are also making the stale instance of that particular HttpContext and all of it's items stuck in memory and plus it is stale... again causing problems in the future. The next reason is because the WebSecurity classwhich is a property of the UmbracoContext has a reference to the HttpContext so it needs to release that too for the same reason.
I wasn't really expecting any of this to cause problems but it just goes to show that anything can happen. So the only way I can see a fix for this while ensuring we are releasing resources is to not set the UmbracoContext's reference to ContentCache/MediaCache to null on disposal. Everything else would get released except these but that is ok because these have an application lifespan anyways. I'll create an issue to get this done for the next release.
Apart from fixing that and using a nightly build I'm not sure how else you could fix this without an update from the core. Perhaps you can dynamically remove the UmbracoModule, add yours and then re-add the UmbracoModule ?
Sounds good Shannon. I'd rather leave umbraco as-is and use the PostReleaseRequestState event instead of the EndRequest event, but I just can't figure out why it's working for Bruce and not working for me...
Cool, well it can't hurt to remove the null assignments for the content/media cache on disposal, that will fix your issue too and not cause problems with the core, but it's a fix the core needs to make and release of course.
I've done a little more testing: on our corporate site, the URLTracker module code (hooked into PostReleaseRequestState, no http module declarations in web.config) is being called for not found requests (our site uses nice urls like '/some-url'), however in the default Umbraco install site, it isn't. I don't know yet why there is a difference in behaviour.
@suzyb
I don't understand the question, but I guess this is not related to this topic. Could you create a new topic with your question and a bit more explanation/details?
In the standard Umbraco install site (i'm using the simple starter site with u.media skin), if you change the <error404> setting within umbracoSettings.config from the default of 1 to an actual document id (eg.doc id 1051 from the simple starter site, although of course in a real life site it would be set to an actual error page), then the PostReleaseRequestState event is fired and URL Tracker handles redirects correctly.
Presumably, when <error404> is set to 1, Umbraco intercepts the request early on and simply puts up the intentionally ugly error page.
Sorry I was posting in a hurry and didn't sense check my post :(
I'm getting the same exception as Bruce and was wondering if there was a way to switch off the 301 tracker so visiting a not found page doesn't cause the exception.
Hi,
I have a clean version of UmbracoCms 7.3.0 with "Umbraco Txt" starter kit.
I installed your package and when I browse for old url or inexistent url I got this error:
Object reference not set to an instance of an object.
[NullReferenceException: Object reference not set to an instance of an object.]
Umbraco.Web.Routing.DefaultUrlProvider.GetUrl(UmbracoContext umbracoContext, Int32 id, Uri current, UrlProviderMode mode) +275
Umbraco.Web.Routing.<>cDisplayClass3.0(IUrlProvider provider) +47
System.Linq.WhereSelectArrayIterator2.MoveNext() +79
System.Linq.Enumerable.FirstOrDefault(IEnumerable1 source, Func`2 predicate) +115
Umbraco.Web.Routing.UrlProvider.GetUrl(Int32 id, Uri current, UrlProviderMode mode) +259
umbraco.library.NiceUrl(Int32 nodeID) +61
InfoCaster.Umbraco.UrlTracker.Modules.UrlTrackerModule.UrlTrackerDo(String callingEventName, Boolean ignoreHttpStatusCode) in d:\kipusoep\Documents\GitHub\UrlTracker\Modules\UrlTrackerModule.cs:0
InfoCaster.Umbraco.UrlTracker.Modules.UrlTrackerModule.context_EndRequest(Object sender, EventArgs e) in d:\kipusoep\Documents\GitHub\UrlTracker\Modules\UrlTrackerModule.cs:81
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +141
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +91
I'm looking into this issue also. In 7.3.1 UmbracoContext.Security is still disposed on EndRequest. This causes UmbracoContext.Current.UrlProvider.GetUrl() to throw an exception. The problem is that it doesn't seem possible to catch certain requests (mainly for static files) on any other event than EndRequest. At least not after that Umbraco has handled the request. I've tried PostReleaseRequestState and UpdateRequestCache and neither fires.
Perhaps the only workaround now is putting the module before the umbraco module in web.config?
That would just mean that you force redirect everything if it exists in UrlTracker as that one will fire before any of the Umbraco content has been resolved.
Issues with URL Tracker in 6.1.4
Hi Stefan,
Thanks for providing this module, we are using it very successfully in umbraco v4.11.8.
However, the time has come to upgrade to 6.1.4, and i have come across a couple of issues using it (the latest version 2.2.2) in our upgraded site. In order to minimise confusion, i have also installed it in a base install 6.1.4 site and observed the same issues:
1. Document moves are not being recorded by the url tracker. Having downloaded the url tracker source, traced the execution and done some independent testing, it seems that the umbraco Document BeforeMove event handler is no longer being called (not in 6.1.3 either). So i don't know if this is an Umbraco bug or not - since Document is now obsolete - but the effect is that moves are not recorded in the URL Tracker.
I then modified the url tracker source to use the new API ContentService event handlers (Publishing, Moving, Deleting) instead of Document (BeforePublish, BeforeMove, BeforeDelete) and url recording was then working as expected. Are there any plans to provide a version of the url tracker that targets the new api (i can supply my code for a start if useful to you)?
However, i then encountered the next issue:
2. The following exception is being thrown in the url tracker http module. Note, this error is only thrown in umbraco 6.1.4 - everything works as expected in 6.1.3, so this could also be an umbraco 6.1.4 issue rather than url tracker:
From the Umbraco source, the error is coming from the following lines (UmbracoContext.cs, GetXml), where umbracoContext.ContentCache is null, hence the error:
So i'm now not sure whether this is a problem due to 6.1.4 possibly requiring different methods to instantiate Node (and usage of UmbracoContext in the http module) or simply something not being initialised properly within Umbraco 6.1.4. Any ideas?
Thanks, Bruce.
Bruce,
Thank you for the great bug report. I wish all bug reports were like this one :-)
I'm going to look into it and will report back soon.
Thanks again!
So I've had a look and came to the same conclusion as you; the Document.Move event is not fired in umbraco v6 and something's changed in v6.1.4 which causes the UrlTracker HttpModule to fail: https://twitter.com/sitereactor/status/372269183075368960 & http://issues.umbraco.org/issue/U4-2712#comment=67-9124
I'm afraid my hands are tied here, I don't know what I can do to fix these issues without having to create a v4 and v6 version of the package. Also I don't have a clue at all how to fix the second issue...
Ok, many thanks for following this up, i see there is some activity on it so i'll just wait and see how that progresses.
The issue is that the UmbracoContext and other items in the HttpContext.Items collection was not being disposed of properly at the end of the request which is doing now. The reason this exception is thrown is that the disposal will probably have already happened before the code in the UrlTrackerModule.context_EndRequest is executed.
From the looks of the code for that module, you need to get the response.StatusCode which is probably why you are executing in EndRequest, but you can get that result in the PostReleaseRequestState event which occurs before the EndRequest event. I would actually recommend the code going in that event in case there's other potential things that might need to be referenced but get disposed at the end of requests.
As for the move event not firing, is there an issue logged in the tracker for that already ?
ah found it :) http://issues.umbraco.org/issue/U4-2729
I've tried this out in the URL Tracker (using PostReleaseRequestState instead of EndRequest), and it seems to work well; not found requests are now being redirected appropriately. So this looks like a good solution to me, thanks very much Shannon; we also have a couple of other areas in our code that are hooked into EndRequest (and using umbraco context information) that will need to be changed over.
I'll leave this topic open until Stefan has a chance to view and comment.
Thanks for the reply Shannon, but I'm not getting the same result as Bruce. For me the PostReleaseRequestState event is not fired for 404 requests; both IntegratedPipeline 404 requests (like '/some-url') and StaticFile 404 requests (like '/some-url.htm')...
It does fire for requests to '/umbraco/webservices/legacyAjaxCalls.asmx/GetSecondsBeforeUserLogout'. Weird right?
Ok, here's a wacky idea... try keeping your module executing on EndRequest and then ensure your http module is declared higher in the web.config than the Umbraco one... see if yours fires first.
That's obviously just a hack/temp solution if it works and we'll need to figure something else out. Let me know if that does/doesnt work.
Yes that works. My problem is; I'm using the DynamicModuleUtility to register the module instead of using the web.config:
This way the UrlTracker is just a single assembly without any configuration stuff, really clean.
Ok well I think we'll have to create a fix for it. So what changed in 6.1.4 is:
we dispose of any object in the HttpContext.Items collection on request end so that if something has referenced an object there (like the UmbracoContext) from a static field, then it won't continue to remain in memory in a stale state, since this will cause problems down the track. Initially the reason for this was that the UmbracoContext also references an HttpContext so if someone references the UmbracoContext singleton from a static field, they are also making the stale instance of that particular HttpContext and all of it's items stuck in memory and plus it is stale... again causing problems in the future. The next reason is because the WebSecurity class which is a property of the UmbracoContext has a reference to the HttpContext so it needs to release that too for the same reason.
I wasn't really expecting any of this to cause problems but it just goes to show that anything can happen. So the only way I can see a fix for this while ensuring we are releasing resources is to not set the UmbracoContext's reference to ContentCache/MediaCache to null on disposal. Everything else would get released except these but that is ok because these have an application lifespan anyways. I'll create an issue to get this done for the next release.
Apart from fixing that and using a nightly build I'm not sure how else you could fix this without an update from the core. Perhaps you can dynamically remove the UmbracoModule, add yours and then re-add the UmbracoModule ?
Sounds good Shannon. I'd rather leave umbraco as-is and use the PostReleaseRequestState event instead of the EndRequest event, but I just can't figure out why it's working for Bruce and not working for me...
Cool, well it can't hurt to remove the null assignments for the content/media cache on disposal, that will fix your issue too and not cause problems with the core, but it's a fix the core needs to make and release of course.
I've done a little more testing: on our corporate site, the URLTracker module code (hooked into PostReleaseRequestState, no http module declarations in web.config) is being called for not found requests (our site uses nice urls like '/some-url'), however in the default Umbraco install site, it isn't. I don't know yet why there is a difference in behaviour.
Is there a way to stop the exception when a page isn't found without having to uninstall the package.
@suzyb
I don't understand the question, but I guess this is not related to this topic. Could you create a new topic with your question and a bit more explanation/details?
I've done a litttle more work on this.
In the standard Umbraco install site (i'm using the simple starter site with u.media skin), if you change the <error404> setting within umbracoSettings.config from the default of 1 to an actual document id (eg.doc id 1051 from the simple starter site, although of course in a real life site it would be set to an actual error page), then the PostReleaseRequestState event is fired and URL Tracker handles redirects correctly.
Presumably, when <error404> is set to 1, Umbraco intercepts the request early on and simply puts up the intentionally ugly error page.
Sorry I was posting in a hurry and didn't sense check my post :(
I'm getting the same exception as Bruce and was wondering if there was a way to switch off the 301 tracker so visiting a not found page doesn't cause the exception.
Yes, if you click on the 'I'-icon (information) in the UrlTracker UI on the top-right, you'll see a Settings tab, which states:
Just as an FYI: We are releasing an out-of-band patch release Monday to solve this and a few other issues people had with 6.1.4.
w00t bring it on :-)
This bug does seem to be fixed in 6.1.5 xD
Thanks Stefan, Shannon, Sebastiaan & the Umbraco community - great job on a great product, the Url Tracker is working well with 6.1.5.
anyone still gettting this error on a clean 6.1.6 install?
Yes, there's still something weird going on: http://our.umbraco.org/projects/developer-tools/301-url-tracker/version-2/45546-Value-cannot-be-null-Parameter-name-umbracoContext
Issues should be resolved with v2.2.6.
@Stefan, yes the issue is resolved with v2.2.6
thanks!
Sorry..this package give problem with UBlogsy pacjage too!!!!!!!!!!
I use Umbraco 6.1.6 and UBlogsy 3.x
Hi, I have a clean version of UmbracoCms 7.3.0 with "Umbraco Txt" starter kit. I installed your package and when I browse for old url or inexistent url I got this error:
Object reference not set to an instance of an object. [NullReferenceException: Object reference not set to an instance of an object.] Umbraco.Web.Routing.DefaultUrlProvider.GetUrl(UmbracoContext umbracoContext, Int32 id, Uri current, UrlProviderMode mode) +275 Umbraco.Web.Routing.<>cDisplayClass3.0(IUrlProvider provider) +47 System.Linq.WhereSelectArrayIterator
2.MoveNext() +79 System.Linq.Enumerable.FirstOrDefault(IEnumerable
1 source, Func`2 predicate) +115 Umbraco.Web.Routing.UrlProvider.GetUrl(Int32 id, Uri current, UrlProviderMode mode) +259 umbraco.library.NiceUrl(Int32 nodeID) +61 InfoCaster.Umbraco.UrlTracker.Modules.UrlTrackerModule.UrlTrackerDo(String callingEventName, Boolean ignoreHttpStatusCode) in d:\kipusoep\Documents\GitHub\UrlTracker\Modules\UrlTrackerModule.cs:0 InfoCaster.Umbraco.UrlTracker.Modules.UrlTrackerModule.context_EndRequest(Object sender, EventArgs e) in d:\kipusoep\Documents\GitHub\UrlTracker\Modules\UrlTrackerModule.cs:81 System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +141 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +91Here you can find log file in debug priority https://drive.google.com/a/alecsandria.it/file/d/0Bw9KEu7pGmHWaFZ6czI3TEI0a0E/view?usp=sharing
I also tried to change error404 value in umbracoSettings from 1 to published node id.
Thanks for your support.
Marco
https://github.com/kipusoep/UrlTracker/issues/93
Hi,
I'm looking into this issue also. In 7.3.1 UmbracoContext.Security is still disposed on EndRequest. This causes UmbracoContext.Current.UrlProvider.GetUrl() to throw an exception. The problem is that it doesn't seem possible to catch certain requests (mainly for static files) on any other event than EndRequest. At least not after that Umbraco has handled the request. I've tried PostReleaseRequestState and UpdateRequestCache and neither fires.
Perhaps the only workaround now is putting the module before the umbraco module in web.config?
That would just mean that you force redirect everything if it exists in UrlTracker as that one will fire before any of the Umbraco content has been resolved.
After some further debugging in 7.3.1 it seems this could be solved by replacing
with
in Umbraco.Web.Routing.DefaultUrlProvider and Umbraco.Web.PublishedCache.XmlPublishedCache.PublishedContentCache
This is because UmbracoContext gets disposed, even if UmbracoContext.EnsureContext() is run in EndRequest event. Not sure why that's happening.
If this substitution is a good or bad thing I don't know though.
is working on a reply...
This forum is in read-only mode while we transition to the new forum.
You can continue this topic on the new forum by tapping the "Continue discussion" link below.