The Nevada dust has settled, everyone is back home and full of impressions from the 404 Conference in Las Vegas, and slowly cooling down from the exciting time we had. Following the theme of the event, here are a few failures I would like to share. Hopefully others can learn from my mistakes, as I certainly did get a lot of value out of the honest experiences that the 404 Conference presenters shared.
During the development phase of an ecommerce website, custom functionality was developed which included a dropdown for selecting a state.
Being an Australian-based website, one of the options in the dropdown was 'Western Australia'. As the dropdown option value, the state code of 'WA' was used.
As us programmers tend to do, the simplest (and at the time, most logical) solution was chosen for obtaining the
StateInfo object from the state code:
public StateInfo StateInfoProvider.GetStateInfoByCode(string stateCode)
Guess what happened when
StateInfoProvider.GetStateInfoByCode("WA") was called? The resulting state object was "Washington", not "Western Australia". The
GetStateInfoByCode method simply returns the first state object it can find in the database that has the specified state code, regardless of the country. Both "Washington" and "Western Australia" share the same state code of "WA"
Conclusion: Be careful - the API feature you are using might not be doing what you think. In our case,
... had to be replaced with something along the lines of
StateInfoProvider.GetStates() .WhereEquals("StateCode", "WA") .WhereEquals("CountryID", 284) .FirstObject
I was approached by a team member with a very interesting problem.
The setup included a custom class with a "CommentArticleID" field, which was a foreign key reference to pages.
To retrieve the data, the good old
InfoProvider was used.
The article page with the ID of 5 was published, and the
InfoProvider was returning data.
Surprisingly enough, for an unpublished article page, the
InfoProvider was not returning any results.
This didn't make sense, so we thought about it... Could Kentico have some hidden version 9 smarts, where the
InfoProvider is actually aware that the
CommentArticleID field is a foreign key reference to a page? Is the
InfoProvider automatically limiting the results for published pages only? How could we prevent it from doing so?
Next step was to look at the actual SQL query that the
InfoProvider is generating.
Of course, we expected something along the lines of:
DECLARE @CommentArticleID INT = 5; SELECT * FROM ABC_Comments WHERE CommentArticleID = @CommentArticleID;
We retrieved the query text:
var queryText = CommentInfoProvider.GetComments().WhereEquals("CommentArticleID", 5).GetFullQueryText();
This was the actual SQL query:
DECLARE @CommentArticleID INT = 5; SELECT * FROM ABC_Comments INNER JOIN ABC_Article ON ArticleID = CommentArticleID INNER JOIN View_CMS_Tree_Joined ON DocumentForeignKeyValue = ArticleID AND ClassName = 'ABC.Article' WHERE ((DocumentPublishFrom IS NULL) OR (DocumentPublishFrom <= GETDATE())) AND ((DocumentPublishTo IS NULL) OR (DocumentPublishTo >= GETDATE())) AND CommentArticleID = @CommentArticleID
The query was named
selectall, which is a reserved name, and is picked up by the
InfoProvider. This was, of course, purely coincidental, and steered us towards overthinking the cause of the issue.
Conclusion: Follow the rules of naming in Kentico, and make sure you are up-to-date with the reserved naming.
This failure is fairly obvious and does not need "detective work" as the ones mentioned above, however it can happen in the wrong time and cause headaches.
A lot of times we use the
DocumentEvents global events, to trigger custom functionality in the event of creation and changes of pages.
DocumentEvents.Insert.After += Document_Insert_After; DocumentEvents.Update.After += Document_Update_After;
This works well until we get a phone call from the client, asking "can we turn on the workflow now?".
When writing these event handler methods, we usually consider the pages being published immediately, and we forget about workflow.
The workflow is enabled, and our custom event handlers misbehave.
That's when we start the journey of implementing other event handlers, such as
Conclusion: Always plan out your
DocumentEvents event handlers, and think about the consequences of enabling a workflow on the pages that are relevant to your event handlers.