I learned the hard way that anonymous users cannot kick off a new workflow.

Someone had set up an automated spam-bot that kept submitting spammed comments to my blog on a daily basis. I thought that I would simply set up a validation workflow, that would make sure the date the user entered was today’s date. Unfortunately, when an anonymous user tries to kick off a workflow, SharePoint looks for the name of the user who initiated it, and when it can’t find it, it goes into an infinite loop. You can read about it on this thread.

Unfotunately, even after I deleted all traces of the workflow, and even rummaged through the database, it still throws an error every time someone submits a comment to the Comment list anonymously. This is beyond exasperating and I don’t know how to undo it. The difficult about this is that this web site is hosted, so I don’t have the liberty to write custom code to fix the problem, since I don’t have permission to deploy custom code to the server.

I have created a rather miserable hack, and I’m rather embarassed to put it out there for the world to see, but I had to do something if I didn’t want to have to re-create my whole blog, and I thought there might be some other poor soul or two out there struggling with the same thing I am. So, here’s my hack. (Oh wait, I was told once by a friend of mine that I shouldn’t use the term “hack”; instead, I should use the phrase “embrace and extend”…. )

First, I created an alternative list (which I called “CommentsTemp”). I created the same fields in that list that were in my comments list. (If you want people to be able to contribute to that list anonymously, make sure you turn on contributor rights for anonymous users on that list.)

The next problem is that, when users submit their comment, I didn’t want them to get redirected to the CommentsTemp list after they submitted their comment, which is the default behavior. (Even when I added the “Source” keyword to my query string, it still didn’t redirect back to the page the user submitted from.) I found this post on the SharePoint Development Forum where someone described how to hardcode the URL a page gets redireced to after the form is submited. Since the posting requires you to swap out the “Save” button with my own, I couldn’t just drop in my own List Form web part; instead, I needed to add a “Custom List Form” web part to the page.

To redirect to a page called “ThankYou.aspx” in the same Postings list, I swapped out the submit buttons with controls that looked like this:

<input type="button" class="ms-ButtonHeightWidth" value="Save" name="btnSave" onclick="javascript: {ddwrt:GenFireServerEvent('__commit;__redirect= ThankYou.aspx ')}" />

A comment is tied to a particular blog posting, so when a comment is entered, it needs to be associated with a particular posting. Here’s the tricky thing: SharePoint understands that if you’re tied to a lookup list, you could potentially have hundreds of item you’re binding to. If there are more than 20 items in a lookup list, SharePoint will not use a typical HTML control; instead, it will substitute a textbox input control with javascript that displays a dropdown menu showing your options. I needed to create the input form in such a way that it would automatically select the name of the current posting in that control. This was easier said than done. For a while, I tried deciphering the javascript on my own until I came to this helpful post which shows you how to select an item from the dropdown menu based on an item passed in on the query string, by adding some javascrpt classes to your code. In my case, the Posting.aspx page passes in the ID of the posting in the query string, which worked out great, because I wanted to select an item from dropdown list of postings with that ID as well.

Finally, I set a workflow on the new CommentsTemp thread that I can kick off manually, that copies an item from the temp list to the “real” Comments list. (I can only kick off the workflow if I’m logged in, so I won’t risk creating the same problem again of trying to kick off a workflow anonymously.) Although this whole process seems ridiculous, the truth is, I still had moderation enabled for the comments in my Comments list when they were submitted; this does the same thing, except it simply moves the comments from one list to another when they’re approved.