if (e.IndexType == IndexTypes.Content && e.Fields["nodeTypeAlias"].ToLower()=="product")
{
var node = ApplicationContext.Current.Services.ContentService.GetById(e.NodeId);
InjectTags(e, node);
}
}
In my log file i get
2013-07-09 13:23:07,658 [41] INFO Umbraco.Core.PluginManager - [Thread 41] Completed resolution of types of umbraco.BusinessLogic.Actions.IActionHandler, found 1 (took 7ms)
I read somewhere that there is always the possibility of your event being fired more than once at startup and ever since I've used a lock object to make sure the init code only fires once.
private void InjectRange(string min, string max, IndexingNodeDataEventArgs e, string field)
{
}
}
I am getting nothing in the log and no events being wiredup. Running localhost I cannot debug becuase event its being hit. Am i missing something obvious?
No idea why but its now working. Also i had to use IApplicationEventHandler i was also getting some js errors in backend i somehow had .net45 references i took those out then updated to IApplicationEventHandler and then rebuilt all good now.
Just glad its working as it was really doing my head in. Many thanks for your help.
Umbraco v6.1 events
Guys,
I am trying to do some gatheringnode data and I have a class looks like
public class ExamineEvents : ApplicationEventHandler
{
private static readonly Dictionary<string, Action<IndexingNodeDataEventArgs>> PropertyLookUp =
new Dictionary<string, Action<IndexingNodeDataEventArgs>>();
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
Init();
}
private void Init()
{
InitDictionaryLookUp();
ExamineManager.Instance.IndexProviderCollection[Helpers.Constants.Examine.TefIndexer].GatheringNodeData += TefExamineEvents_GatheringNodeData;
}
void TefExamineEvents_GatheringNodeData(object sender, IndexingNodeDataEventArgs e)
{
if (e.IndexType == IndexTypes.Content && e.Fields["nodeTypeAlias"].ToLower()=="product")
{
var node = ApplicationContext.Current.Services.ContentService.GetById(e.NodeId);
InjectTags(e, node);
}
}
In my log file i get
2013-07-09 13:23:07,658 [41] INFO Umbraco.Core.PluginManager - [Thread 41] Completed resolution of types of umbraco.BusinessLogic.Actions.IActionHandler, found 1 (took 7ms)
2013-07-09 13:23:11,145 [41] ERROR Umbraco.Core.UmbracoApplicationBase - [Thread 41] An unhandled exception occurred
System.ArgumentException: An item with the same key has already been added.
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Umbraco.Core.Models.UmbracoObjectTypesExtensions.GetGuid(UmbracoObjectTypes umbracoObjectType)
at Umbraco.Core.Services.EntityService.GetChildren(Int32 parentId, UmbracoObjectTypes umbracoObjectType)
at umbraco.cms.presentation.Trees.BaseContentTree.Render(XmlTree& Tree)
at umbraco.presentation.webservices.TreeDataService.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
2013-07-09 13:23:11,149 [33] ERROR Umbraco.Core.UmbracoApplicationBase - [Thread 33] An unhandled exception occurred
System.ArgumentException: An item with the same key has already been added.
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Umbraco.Core.Models.UmbracoObjectTypesExtensions.GetGuid(UmbracoObjectTypes umbracoObjectType)
at Umbraco.Core.Services.EntityService.GetChildren(Int32 parentId, UmbracoObjectTypes umbracoObjectType)
at umbraco.cms.presentation.Trees.BaseContentTree.Render(XmlTree& Tree)
at umbraco.presentation.webservices.TreeDataService.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Ismail
I read somewhere that there is always the possibility of your event being fired more than once at startup and ever since I've used a lock object to make sure the init code only fires once.
I put it in the wiki a while back
http://our.umbraco.org/wiki/reference/api-cheatsheet/using-iapplicationeventhandler-to-register-events
Kevin,
Just used your code and also made the methods public as per your wiki entry still no joy. The errors have stopped but the event is not wiring up.
Any ideas?
Cheers
So I upgraded to 6.1.2 and my code looks like:
public class ExamineEvents : ApplicationEventHandler
{
private static readonly Dictionary<string, Action<IndexingNodeDataEventArgs>> PropertyLookUp =
new Dictionary<string, Action<IndexingNodeDataEventArgs>>();
private static object _lockObj = new object();
private static bool _ran = false;
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
if (!_ran)
{
lock (_lockObj)
{
if (!_ran)
{
// everything we do here is blocking
// on application start, so we should be
// quick.
// do you're registering here... or in a function
// you will need to add the relevent class at the top of your code (i.e using Umbraco.cms.businesslogic.web)
LogHelper.Debug(typeof(ExamineEvents), () => "ApplicationStarted for event " +
Helpers.Constants.Examine.TefIndexer);
Init();
_ran = true;
}
}
}
}
private void Init()
{
InitDictionaryLookUp();
ExamineManager.Instance.IndexProviderCollection[Helpers.Constants.Examine.TefIndexer].GatheringNodeData += TefExamineEvents_GatheringNodeData;
}
void TefExamineEvents_GatheringNodeData(object sender, IndexingNodeDataEventArgs e)
{
if (e.IndexType == IndexTypes.Content && e.Fields["nodeTypeAlias"].ToLower()=="product")
{
var node = ApplicationContext.Current.Services.ContentService.GetById(e.NodeId);
LogHelper.Debug(typeof(ExamineEvents), () => "in gathering node data for " +
Helpers.Constants.Examine.TefIndexer);
InjectTags(e, node);
}
}
private void InjectTags(IndexingNodeDataEventArgs e, Umbraco.Core.Models.IContent node)
{
try
{
LogHelper.Debug(typeof(ExamineEvents), () => "attempting to inject tags for examine index " +
TEF.Common.Helpers.Constants.Examine.TefIndexer);
//match the property with what we have in dictionary then call that event to post process the indexing data
foreach (var property in node.Properties)
{
if (PropertyLookUp.ContainsKey(property.Alias))
{
PropertyLookUp[property.Alias](e);
}
}
}
catch (Exception ex)
{
LogHelper.Error(typeof(ExamineEvents), "Error attempting to inject tags " + ex.ToString(), ex);
}
}
private void InitDictionaryLookUp()
{
if (PropertyLookUp.Keys.Count == 0)
{
LogHelper.Debug(typeof(ExamineEvents), () => "initialised dictionary lookup for examine index " +
Helpers.Constants.Examine.TefIndexer);
PropertyLookUp.Add("weight", indexWeight);
PropertyLookUp.Add("thickness", indexThickness);
PropertyLookUp.Add("minTemperatureResistance", indexMinTemperatureResistance);
PropertyLookUp.Add("maxTemperatureResistance", indexMaxTemperatureResistance);
PropertyLookUp.Add("tensileStrength", indexTensileStrengthResistance);
}
}
#region index formatting methods
/// <summary>
/// inject in extra tags that are searchable for the weight range
/// </summary>
/// <param name="e"></param>
private void indexWeight(IndexingNodeDataEventArgs e)
{
ProcessRange("weight", e, "gsm");
}
private void indexThickness(IndexingNodeDataEventArgs e)
{
ProcessRange("thickness", e, "mm");
}
private void indexMinTemperatureResistance(IndexingNodeDataEventArgs e)
{
}
private void indexMaxTemperatureResistance(IndexingNodeDataEventArgs e)
{
}
private void indexTensileStrengthResistance(IndexingNodeDataEventArgs e)
{
ProcessRange("tensileStrength", e, "N/5mm");
}
#endregion
/// <summary>
/// gets the node id form mntp field then gets the value and injects into
/// index a searable range
/// </summary>
/// <param name="field"></param>
/// <param name="e"></param>
/// <param name="replaceUnit"></param>
private void ProcessRange(string field, IndexingNodeDataEventArgs e, string replaceUnit)
{
int nodeId = int.Parse(e.Fields[field]);
//the value is mntp lookup so get the node
var node = ApplicationContext.Current.Services.ContentService.GetById(nodeId);
//we have actual values so preprocess them
if (CanInjectDummyMin(field, e, node) == false)
{
string fieldRaw = node.Name;
fieldRaw = fieldRaw.Replace(replaceUnit, "").TrimEnd();
if (fieldRaw.Contains("+"))
{
decimal fieldValue = decimal.Parse(fieldRaw.Replace("+", ""));
InjectRange(fieldValue.ToString("D6"), Helpers.Constants.Examine.MaxValue, e, field);
}
else
{
string[] values = fieldRaw.Split('-');
decimal valueMin = decimal.Parse(values[0]);
decimal valueMax = decimal.Parse(values[1]);
InjectRange(valueMin.ToString("D6"), valueMax.ToString("D6"), e, field);
}
}
}
private bool CanInjectDummyMin(string field, IndexingNodeDataEventArgs e, IContent node)
{
string raw = node.Name;
if (raw.ToLower().Contains("know"))
{
e.Fields.Add(Helpers.Constants.Examine.MinPrefix + field, Helpers.Constants.Examine.MinValue);
e.Fields.Add(Helpers.Constants.Examine.MaxPrefix + field, Helpers.Constants.Examine.MinValue);
return true;
}
return false;
}
private void InjectRange(string min, string max, IndexingNodeDataEventArgs e, string field)
{
}
}
I am getting nothing in the log and no events being wiredup. Running localhost I cannot debug becuase event its being hit. Am i missing something obvious?
Regards
Ismail
It looks fine,
however i usally impliment the IApplicationEventHandler interface, it looks like you are just inheriting the class ?
so
public class ExamineEvents : ApplicationEventHandler
public class ExamineEvents : IApplicationEventHandler
Kevin,
I have that initially. I also went and tried ApplicationBase as its still there but even that dont work.
Cheers
Ismail
Just cut and pasted the code into a DLL -
Log.Debug messages don't appear in the logs by default (you have to do some setting)
I changed the one in the ApplicationStarted to Log.Info - it appears in the umbraco log.
I commented out all the examine stuff, but it is at least firing for me.
Kevin,
No idea why but its now working. Also i had to use IApplicationEventHandler i was also getting some js errors in backend i somehow had .net45 references i took those out then updated to IApplicationEventHandler and then rebuilt all good now.
Just glad its working as it was really doing my head in. Many thanks for your help.
Regards
Ismail
Hi Ismail/Kevin,
I'm having the same (or very similar) issue but I can't seem to shake it: http://our.umbraco.org/forum/developers/api-questions/47361-Examine-event-not-firing-to-implement-GatheringNodeData-in-61. Any ideas chaps?
is working on a reply...