09 December 2009

robust email address validation through regex and javascript

Regular expressions are a representation of a grammar that helps computers and programs interpret and validate human input.  Unfortunately they are a huge time-suck and are a form of mental masturbation.  But one person's poison is another's Picasso; some regular expressions are like poetry to the mathmatically-bent computer scientists, and great debate has ensued over the best interpretation of RFC822, the internet's email address specification. 

Also, with the 16-Nov-2009 Internet Corporation for Assigned Names and Numbers (ICANN's) move to accept multi-byte, internationalized top-level domain names (IDN/TLD), I wonder how many hosts will need to update their assumptions in their regex.  Also I wonder what google mail, yahoo, amazon, ebay, facebook, or twitter might consider for their own RFC822 validation routines going forward.

Since there seems to be as many regular expressions developed and published as there are email addresses, I'll contribute what I've come across as well.  We'll see how this evolves in 2010 when people start employing these new domain names.

simple one in javascript (from Dustin Diaz):

var pattern = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;


and a big one (from Paul Warren) - though I've yet to see an escape sequence for adapting this expression for use in javascript:


(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?: \r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0 31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+ (?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?: (?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n) ?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\ r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[\t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n) ?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[\t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*) *:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+ |\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r \n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?: \r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)? [ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]| \\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<> @,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|" (?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000- \031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\ [\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\ r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\] |\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0 00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])* (?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\". \[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+| \Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?: [^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n) ?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[" ()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n) ?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<> @,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[\t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)? (?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\". \[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?: \r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t]) *))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]) +|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*))*)?;\s*)
  

04 December 2009

SharePoint 2007 URL Quick List still holds up


I think its funny/slightly sad that very little about this list of URLs have changed since Heather Solomon wrote this information up in July 2005 - 4.5 years later; this is a relevant and useful administrative list of URLs that are sometimes hidden depending on a few factors in your deployment:

Portal and WSS

Function
Add to the URL
Notes
Manage List Template Gallery
/_catalogs/lt/Forms/AllItems.aspx
Manage Site Collection Users
/_layouts/1033/siteusrs.aspx
To access you must be an admin on the server or a site collection admin for the site.
Manage Site Groups
/_layouts/1033/role.aspx
Manage Users
/_layouts/1033/user.aspx
Manage Web Part Gallery
/_catalogs/wp/Forms/AllItems.aspx
Site Usage Report
/_layouts/1033/UsageDetails.aspx
Site Usage Summary
/_layouts/1033/Usage.aspx
User Information
/_layouts/1033/userinfo.aspx
Web Parts Maintenance Page
?contents=1
Add to the end of the page URL

Portal Only

Function
Add to the URL
Notes
Create
[area]/_layouts/1033/spscreate.aspx
Create list in a different portal area
/_layouts/1033/new.aspx?
NewPageFilename=YourTemplateName.stp&
ListTemplate=100&
ListBaseType=0
When you save a template in a portal area and try to create a new list in a different portal area, the template will not show on the Create page. Use this URL to force it to show. More info.
Manage Audiences
/_layouts/1033/Audience_Main.aspx
Manage Site Template Gallery
/_catalogs/wt/Forms/AllItems.aspx
Manage User Alerts
/_layouts/1033/AlertsAdmin.aspx
Site Settings
/_layouts/1033/default.aspx
Sites Registry
/SiteDirectory/Lists/Sites/Summary.aspx

WSS Only

Function
Add to the URL
Notes
Add Web Parts Pane
?ToolPaneView=2
Add to the end of the page URL *Not supported by MSFT on Form Pages*
Create
/_layouts/1033/create.aspx
Documents and Lists
/_layouts/1033/viewlsts.aspx
Manage Cross Site Groups
/_layouts/1033/mygrps.aspx
Manage My Alerts
/_layouts/1033/MySubs.aspx
Manage Site Template Gallery
/_catalogs/wt/Forms/Common.aspx
Manage User Alerts
/_layouts/1033/SiteSubs.aspx
Site Settings
/_layouts/1033/settings.aspx
Top-level Site Administration
/_layouts/1033/webadmin.aspx
but since there were some enhancements made in SharePoint 2007, Josef Nielsen wrote up a more complete set, though it's not organized w/consideration to WSS.
People and Groups
_layouts/people.aspx
Users and Permissions
Site Collection Admins
_layouts/mngsiteadmin.aspx
Users and Permissions
Advanced Permissions
_layouts/user.aspx
Users and Permissions
Master Pages
_Layouts/ChangeSiteMasterPage.aspx
Look and Feel
Title, Desc, and Icon
_layouts/prjsetng.aspx
Look and Feel
Navigation
_layouts/AreaNavigationSettings.aspx
Look and Feel
Page Layout and Ste Templates
_Layouts/AreaTemplateSettings.aspx
Look and Feel
Welcome Page
_Layouts/AreaWelcomePage.aspx
Look and Feel
Tree View
_layouts/navoptions.aspx
Look and Feel
Top Nav Bar
_layouts/topnav.aspx
Look and Feel
Site Theme
_layouts/themeweb.aspx
Look and Feel
Reset to Site Definition
_layouts/reghost.aspx
Look and Feel
Searchable Columns
_Layouts/NoCrawlSettings.aspx
Look and Feel
Site Content Types
_layouts/mngctype.aspx
Galleries
Site Columns
_layouts/mngfield.aspx
Galleries
Site Templates
_catalogs/wt/Forms/Common.aspx
Galleries
List Templates
_catalogs/lt/Forms/AllItems.aspx
Galleries
Web Parts
_catalogs/wp/Forms/AllItems.aspx
Galleries
Workflows
_layouts/wrkmng.aspx
Galleries
Master Pages and Page Layouts
_catalogs/masterpage/Forms/AllItems.aspx
Galleries
Regoinal Settings
_layouts/regionalsetng.aspx
Site Administration
Site Libraries and Lists
_layouts/mcontent.aspx
Site Administration
Site Usage Report
_layouts/usageDetails.aspx
Site Administration
User Alerts
_layouts/sitesubs.aspx
Site Administration
RSS
_layouts/siterss.aspx
Site Administration
Search Visability
_layouts/srchvis.aspx
Site Administration
Sites and Workspaces
_layouts/mngsubwebs.aspx
Site Administration
Site Features
_layouts/ManageFeatures.aspx
Site Administration
Delete This Site
_layouts/deleteweb.aspx
Site Administration
Site Output Cache
_Layouts/areacachesettings.aspx
Site Administration
Content and Structure
_Layouts/sitemanager.aspx
Site Administration
Content and Structure Logs
_Layouts/SiteManager.aspx?lro=all
Site Administration
Search Settings
_layouts/enhancedSearch.aspx
Site Collection Administration
Search Scopes
_layouts/viewscopes.aspx?mode=site
Site Collection Administration
Search Keywords
_layouts/listkeywords.aspx
Site Collection Administration
Recycle Bin
_layouts/AdminRecycleBin.aspx
Site Collection Administration
Site Collection Features
_layouts/ManageFeatures.aspx?Scope=Site
Site Collection Administration
Site Hierachy
_layouts/vsubwebs.aspx
Site Collection Administration
Portal Site Connection
_layouts/portal.aspx
Site Collection Administration
Site Collection Audit Settings
_layouts/AuditSettings.aspx
Site Collection Administration
Site Collection Policies
_layouts/Policylist.aspx
Site Collection Administration
Site Collection Cache Profiles
Cache%20Profiles/AllItems.aspx
Site Collection Administration
Site Collection Output Cache
_Layouts/sitecachesettings.aspx
Site Collection Administration
Site Collection Object Cache
_Layouts/objectcachesettings.aspx
Site Collection Administration
Variations
_Layouts/VariationSettings.aspx
Site Collection Administration
Variation Labels
_Layouts/VariationLabels.aspx
Site Collection Administration
Translatable Columns
_Layouts/TranslatableSettings.aspx
Site Collection Administration
Variation Logs
_Layouts/VariationLogs.aspx
Site Collection Administration
Site Settings
_layouts/settings.aspx
Other

SharePoint Jokes


  1. What do you call a smiling, SOBER courteous person at a SharePoint conference? A: The caterer.
  2. Light travels faster than sound. This is why some SharePoint consultants appear bright until you hear them speak.
  3. A good SharePoint consultant is someone who can tell you to go to hell in such a way that you look forward to the trip.
  4. How many SharePoint consultants does it take to screw in a light bulb? How many can you afford?
  5. I always take SharePoint with a grain of salt, ...plus a slice of lemon, ...and a shot of tequila.
  6. Client says to SharePoint consultant - Well aren't you a waste of two billion years of evolution.
  7. SharePoint: working daily to make the human brain obsolete.
  8. I told my boss that everyone hates SharePoint. He said I was being ridiculous… everyone hasn't used it yet.
  9. SharePoint work is something you do that nobody notices until you don't do it.
  10. Top three things SharePoint Consultant won't say:
    1. You're right; we're billing way too much for this.
    2. How about paying us based on the success of the project?
    3. I don't know enough to speak intelligently about that.


  11. I should've known it wasn't going to work out between my ex-girlfriend and me. After all, I'm a SharePoint and she's a Documentum.
  12. I drink beer to celebrate major events, the fall of communism, or the fact that our SharePoint is still working.
  13. SharePoint Consultants have credibility because they aren't dumb enough to work at your company.
  14. A SharePoint consultant with a clear conscience is usually a sign of bad memory.
  15. With sufficient thrust and an open window, SharePoint servers fly just fine.
  16. I scream the same whether I'm about to be devoured by great white shark or work with SharePoint
  17. Good SharePoint consultants are the ones that never get caught screwing it up.
  18. If Bill Gates had a penny for every time I had to watch the SharePoint wheel thing spin...oh wait, he does.
  19. Kerberos with SharePoint is sort of like a bird, it's pretty cute until it shits on your head.
  20. The secret to success as a SharePoint consultant is knowing who to blame for your failures.
  21. SharePoint Consultant to client - 'We don't have a SharePoint performance problem; You have a perception problem.'
  22. I used to be indecisive about SharePoint. Now I'm not sure.
  23. SharePoint consultant to client - 'I don't have a solution, but I do admire the problem.'
  24. Some SharePoint mistakes are too much fun to only make once.
  25. The SharePoint consultant who laughs last probably made a back-up AND tested the restore!
  26. Overheard: "This SharePoint consultant is depriving a village somewhere of an idiot."
  27. SharePoint analyst to programmer: "You start coding. I'll go find out what they want."
  28. 99 percent of SharePoint consultants give the rest a bad name.
  29. Never, under any circumstances, decide to install SharePoint and take a laxative on the same night.
  30. A computer can insult your intelligence, but nothing rubs it in like SharePoint.
  31. Client said: Most SharePoint consultants are idiots, and I just hired their King!
  32. Remember half the SharePoint consultants you know are below average. :)
  33. 3 reasons why SharePoint better then sex:
    1. You can usually find someone to do it with.
    2. A little coffee and you can do it all night.
    3. If you don't finish you won't gain a reputation as a "SharePoint teaser."


  34. Q: What's the difference between a SharePoint consultant and a computer nerd?
    • A: Sooner or later everyone needs a SharePoint consultant!


  35. How many SharePoint consultants does it take screw in a light bulb?
    • Answer: 100. 1 to do, 99 to say they could do it better.


  36. What do SharePoint Consultants use for birth control? - Their personalities.
  37. The first half of my life was ruined by my parents, and the second half by SharePoint.
  38. TIP: If you are a SharePoint admin and you think nobody cares if you're alive, try missing a couple of SharePoint service packs.
  39. I want to die peacefully in my sleep, like my grandfather.. Not screaming and yelling like SharePoint end users.
  40. I like SharePoint, It fascinates me. I sit and look at it for hours.
list from Paul Swider


What did one sharepoint site say to another sharepoint site? 
    Hey, aren't we called webs?


What did the end user say to the developer?
    Oh, I didn't create that column, I was smart, I just renamed the "title" column!


What did one sharepoint web developer say to the asp.net developer?
    Why me?


What did the production portal say to the author portal?
    I'm sorry, I can't seem to find your object!


What did the parent content type say to the child content type?
    I won't give you my jeans, but I'll buy you another pair just like them and we can share!


How many people does it take to create a web part?
    two, one to write the code, another to figure out the permissions problem in production!


How many times does it take to create a Shared Service Provider?
    3, one time to screw it up without knowing it, twice to do it because sharepoint won't do right the second time and
the third after you have blown away everything and started over!


What did the server admin say to the sharepoint web developer?
    Why can't we just do this with static html?


what did the sharepoint 2003 environment tell the sharepoint 2007 environment?
    Don't worry, reboot will still fix everything.


What did the sharepoint admin do to fix an "Unexpected Error has occured"
    Delete sharepoint and start again!


What did one w3wp process say to the other?
    Hey, can I borrow one of your SPSite's?  You have plenty!       


One day a user called the helpdesk, no one answered.  Being that he was in the helpdesk office he walked down and asked the admin why they weren't answering.
She simply stated, they quit when they heard we were implementing sharepoint!


A consultant was asked to build an estimate for a SharePoint two layer approval workflow with SharePoint Designer. 
The consultant never replied.  When asked "why", he simply stated, "Impossible".

list from Chris Givens


Legend:




BDC = Business Data Catalog and Backup Domain Controller

BI = Business Intelligence

CA = Central Administration and Certificate Authority

CMS = Content Management Server

DMZ = Demilitarized Zone

ECM = Enterprise Content Management

ECS = Excel Calculation Server

KPI = Key Performance Indicators

IIS = Internet Information Services

ISA = Internet Security and Acceleration Server

MMC = Microsoft Management Console

MOSS = Microsoft Office SharePoint Server 2007

O12 = Office 12

OFS = Office Forms Server

OSS = Office SharePoint Server, Office Server System and Open Source System

PDC = Primary Domain Controller

PKI = Public Key Infrastructure

RFC = Request for Comments

SPS = SharePoint Portal Server

SSL = Secure Sockets Layer

STS = SharePoint Team Services

SSP = Shared Services Provider

TLS = Transport Layer Security

URL = Uniform Resource Locater

URN = Uniform Resource Name

URI = Uniform Resource Identifier

VS = Virtual Server 2005, Virtual Server and Visual Studio

VSS = Visual Source Safe, Volume Shadow Copy Service

WA = Web Application

WAS = Web Application Stress tool

WCM = Web Content Management

WSS = Windows SharePoint Services, Web Storage System and Windows Server System

WWF = Windows Workflow Foundation and Worldwide Wrestling Federation

list from Bill English

02 December 2009

wspbuilder error "Could not load file or assembly 'CabLib, Version=6.9.26.0, Culture=neutral, PublicKeyToken=85376ef9a48d191a' or one of its dependencies. An attempt was made to load a program with an incorrect format."

I really love when a fix is simple.

Back story: in this case, I am in the midst of using a combination of wspbuilder and spsource to reverse engineer, package up and deploy a few custom content types. wspbuilder is a codeplex Visual Studio extension that helps package up SharePoint code into a Solution file (WSP) for deployment. spsource is another tool that tries to analyse a SharePoint site and tease out a schema.xml for a list, and column & field information for a content type.  I use the term 'tries' because depending on how clean your dev environment is, your mileage may vary. 

Problem description: when running WSPBuilder -> Build WSP, the output window in Visual Studio says

Could not load file or assembly 'CabLib, Version=6.9.26.0, Culture=neutral, PublicKeyToken=85376ef9a48d191a' or one of its dependencies. An attempt was made to load a program with an incorrect format.

It is my belief this problem is related to the installer not detecting/switching to the correct version of this DLL - there is an x86 version and an x64 version.

Fix:
[applicable to the wspbuilder.exe version 0.9.8.1029 file date apr 15 2009, 262kb] :
copy the x86 cablib.dll
from

C:\Program Files\WSPTools\WSPBuilderExtensions\Resources\x86
to:
C:\Program Files\WSPTools\WSPBuilderExtensions\

(if you can read espanol, it is in this blog: http://guatecommunity.net/blogs/jmhogua/archive/2009/05/13/wspbuilder-could-not-load-file-or-assembly-cablib.aspx )
another option is to download the latest version (> v1.0.5) of wspbuilder, which states in the release notes "Note! 22 June 2009 - x64 CabLib.dll install bug fixed."
 
Hooray for multiple fixes!

20 November 2009

dinner party download: ice breakers 17 - 18



A man and a woman are playing golf.  They are playing on this old, rustic course and they come to this old barn on the side of this course. The guy hits the ball over there, and he goes over:




Guy: You know, I'm going to take a drop and just forget about the barn, just take the stroke penalty.


Wife: Wait a minute, honey. What if you just open up the doors and hit right through?  You don't have to take the penalty. 






So he hits the ball, and it ricochets off something and ricochets off something else, hits his wife in the head, kills her dead.


One year later, the guy is playing the same course.  Comes to the same hole.  He is playing with a buddy of his.  He pushes the ball into almost the same place.  And he tells his buddy




Guy: Hey man, I'm just going to pick it up and take the stroke penalty.  


Buddy: Hey man, no, you know what you should do?  Open up the doors and hit it right through - then you won't have to take the penalty. 


Guy: Are you kidding man?  I did that last year.  I made a 5 on this hole.





Larry Wilmore, dinner party download, ep 17.








16 November 2009

Default Document Content Type always loading as Document

The problem statement is in MOSS 2007, when the user adds custom content types to an existing document library and then set them up to appear in the new document dropdown, MOSS still uses the default Document content type (though after saving, you can edit properties to set the correct content type - how undesirable!). Stephen Muller pointed me in the right direction for a fix, but mine differs slightly from his.

Solution:
Create a document library and set the default Document Template to None. i.e. do not select Microsoft Word, Microsoft Office Word 97-2003 template, etc.




After the document library is created, do this within the Document Library Settings:
  1. Create Columns or Add from existing site columns
  2. go Advanced Settings > Allow managment of Content Types=Yes,  
  3. then Add from existing site content types
  4. then Change new button order and default content type and set the new content type up as #1 (for example)



11 November 2009

Displaying workflow item information from a custom ASPX task form



When building custom workflows, often we want custom Task edit screens as well.  A custom Task Content Type allows us to collect much deeper data than 'completed'.  However, since we are ditching the default Task edit pages, we lose a couple of useful features; a link to the underlying Workflow item as well as the implied context of the Task.

Given the need to provide context to the user when overrriding the default task form, you may come across the desire to display some file information, custom columns/properties, links, etc on the task edit page.  

To accomplish this, we need to gain two pieces of understanding:

  1. How and when to modify ASPX page elements from the code-behind c# class
  2. How to extract the underlying information from the Workflow's original item

When: during the page_load() of inherited class;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {

                    ...
                    //string _paramTaskListItemID Represents the ID Task List Item being worked on 
                    this._paramTaskListItemID = Request.Params["ID"];

                    //SPListItem _TaskListItem Represents the item within the task list 
                    this._TaskListItem = this._TaskListAttachedTo.GetItemById(System.Convert.ToInt16(this._paramTaskListItemID));

                    //Guid _workflowInstanceGuid Represents the ID of the running workflow
                    this._workflowInstanceGuid = new Guid(Convert.ToString(this._TaskListItem["WorkflowInstanceID"]));

                    // SPWorkflow _activeWorkflow Represents the current workflow 
                    // Instantiate the workflow, retrieve the SPworkflow object for the web 
                    this._activeWorkflow = new SPWorkflow(this._myTeamSite , this._workflowInstanceGuid );

                    // protected System.Web.UI.WebControls.Label labelFileURL is a reference to the aspx form's label
                    ...



                    ...
                try
                {
                    labelFileURL.Text += "Job ID is: " + this._activeWorkflow.ParentItem.File.Properties["Job ID"].ToString();
                }
                catch (NullReferenceException)
                {
                    labelFileURL.Text += "Job ID is not set.";
                }
                    ...



How do we modify the aspx page in flight - insert a placeholder aspx object within the task form - choose a good candidate object like a label;

<%@ Page Language="C#" AutoEventWireup="true" EnableSessionState="true" ValidateRequest="False"  Inherits="BI_IA_NS.BI_TaskApprovalForm" %>
...
<asp:content contentplaceholderid="PlaceHolderMain" runat="server">
        <p class="subheader">Job Information 
         <div class="greytext">
            <asp:Label ID="labelJobID" runat="server"></asp:Label>
            <asp:Label ID="labelFileURL" runat="server"></asp:Label>
         </div>
        </p>

These labels are placeholders that we can manipulate based on actions or events sent to the code-behind class. Now that we have the ability to modify the form in flight, this brings us to how we extract the workflow document data while editing a task.

The key is to build the correct SPWorkflow object - as it turns out, there are two constructors for this object. If you use the constructor based on the tasks' list item, all the information within the SPWorkflow object is relative to the Task List. So we want to use the SPWorkflow constructor with the SPWeb parameter.

SPWorkflow (SPListItem, Guid)
SPWorkflow (SPWeb, Guid)


The SPWorkflow object can be created like this:

                    ...
                    //string _paramTaskListItemID Represents the ID Task List Item being worked on 
                    this._paramTaskListItemID = Request.Params["ID"];

                    //SPListItem _TaskListItem Represents the item within the task list 
                    this._TaskListItem = this._TaskListAttachedTo.GetItemById(System.Convert.ToInt16(this._paramTaskListItemID));

                    //Guid _workflowInstanceGuid Represents the ID of the running workflow
                    this._workflowInstanceGuid = new Guid(Convert.ToString(this._TaskListItem["WorkflowInstanceID"]));

                    // SPWorkflow _activeWorkflow Represents the current workflow 
                    // Instantiate the workflow, retrieve the SPworkflow object for the web 
                    this._activeWorkflow = new SPWorkflow(this._myTeamSite , this._workflowInstanceGuid );


Then, by combining the techniques of modifying the label, and extracting the document metadada, gets us to our goal:
                try
                {
                    labelFileURL.Text += "Job ID is: " + this._activeWorkflow.ParentItem.File.Properties["Job ID"].ToString();
                }
                catch (NullReferenceException)
                {
                    labelFileURL.Text += "Job ID is not set.";
                }

To help understand what properties your file has, you can enumerate the whole set of properties (as a debugging step) - bonus code:
                System.Collections.Hashtable collHashes = this._activeWorkflow.ParentItem.File.Properties;
                System.Collections.ICollection collKeys = collHashes.Keys;
                string strList = "File properties are 
";

                foreach (object oKey in collKeys)
                {
                    strList += (SPEncode.HtmlEncode(oKey.ToString())
                    + " :: " +
                    SPEncode.HtmlEncode(collHashes[oKey.ToString()].ToString())
                    + "
");
                }
                labelJobID.Text = strList;


Reference on MSDN - Item or SPWorkflowActivationProperties from SPWorkflow

10 November 2009

Security and Audit Trail of Workflow Tasks in SharePoint 2007 & Visual Studio 2008





Two requests that are probably part of every SharePoint workflow design:
  1. Permit only the users who are assigned a WF tasks to edit (i.e. complete) them
  2. Record the user name of the person who completes a task (instead of the System Account)
Not suprisingly, neither of these pretty simple, seemingly obvious design concepts can be done out of the box / without some customization.  Also, certain configuration screens might trick you into thinking you can do this directly within the SharePoint UI (you can't; more on this in the deeper blog posts).

Part 1: Security of Workflow Tasks in SharePoint 2007 and Visual Studio 2008



Part 2: Audit Trail of Workflow Tasks in SharePoint 2007 and Visual Studio 2008

 
There are a couple of good blog sources for each of these customizations, but I didn't find any of them to be thoroughly detailed with screenshots, pitfalls, etc.  So what I hope to do in this two part blog post is cover some portions I think those sources left off, and provide updates relevant to Visual Studio 2008. 

CodePlex module?

At a high level, one would like to specify these widely useful features in the Workflow Settings screen or even within the Task List settings.  I may eventually release this into an extension on codeplex so if someone might find this useful, let me know. 

E.g.
Package an extension to the content type = Workflow Task List's General Settings page that pre-packages the code and intercepts the creation of new task items by tacking on special permissions.  It'd go right here:






04 November 2009

HOWTO beautify code syntax with automatic formatting within blogger

Admittedly, I've been lazy about just dropping code into blogger (unformatted), but now I'm glad to say that I've finally gotten around to adding a bit of css and javascript magic into the blogger template.

The syntax highlighter code is created and maintained by Alex Gorbatchev and to get it up and running quickly, I more or less used Carter Cole's instructional write up.  After modifying the theme choice and putting the css and js on a host, we are cooking with a Foreman!  Note, I'm using the standard distribution which includes a smaller set of brushes, whereas there are many more out there, and others in development.




So here is exactly what I did:
  1. Download the current distribution of the sytnax highlighter above, or decide if you are okay with letting someone else host that css & javascript for you

    • if chose to downloaded it, upload/ftp/host it at your own provider (e.g. I use 01solutions.com)

  2. Log in to your blogger account (try using google's beta), look for the blog in question, click Layout
  3. The URL should read http://draft.blogger.com/rearrange?blogID=magicnumber
  4. Click Edit HTML
  5. Backup your current template to a local file, by clicking Download Full Template
  6. Edit the template: I inserted the below javascript & css declarations after the HTML tag, and Before the Head tag

<link href='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/styles/shCore.css' rel='stylesheet' type='text/css'/> 

<link href='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/styles/shThemeDjango.css' rel='Stylesheet' type='text/css'/>
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shCore.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushCpp.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushCSharp.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushCss.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushJava.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushJScript.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushPhp.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushPython.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushRuby.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushSql.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushVb.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushXml.js' type='text/javascript'/> 
<script src='http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/shBrushPerl.js' type='text/javascript'/> 
<script language='javascript'> 
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://www.01solutions.com/images/syntaxhighlighter_2.1.364/scripts/clipboard.swf';
SyntaxHighlighter.all();

So now to post something with code, while preparing the post:
  1. Click Edit HTML
  2. If you are posting HTML source itself, your results may vary (depending if you are using a beta version of blogger, etc) - but I'd recommend to escape all < and > with &lt; and &gt; which can be automatically done for you via many webpages such as the one Carter Cole points out by Accessify: http://accessify.com/tools-and-wizards/developer-tools/quick-escape/default.php
  3. Decide which brush / language you are using, and preface & postface the code you are dropping in with the appropriate pre tag (use the alias list in the first image above), e.g.:


great HTML code goes here..

<table width=100% cellpadding=0 cellspacing=0 border=0>
<tr>
<td width=143 rowspan=3>
<h1>
<a href="?">
<img src="/mail/help/images/logo1.gif"
width=143 height=59 border=0
alt="Gmail by Google">
</a>
</h1>
</td>
<td width=1 rowspan=3> </td>
<td height=25 colspan=2 align=right valign=top>



Gmail by Google

 


or


        // insert your c# code here
        public Workflow1()
        {
            InitializeComponent();
        }

        public Guid workflowId = default(System.Guid);
        public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
Easy, eh? Not sure if I'm going to go back and update old code within posts yet, but if anyone comments on whether that'd be helpful, I could be convinced. 

03 November 2009

Workflow LogToHistoryList UserID and Task Activity Executor in SharePoint

This topic is within a SharePoint 2007 workflow, how do we get the Workflow History to reflect the user who modified a task, rather than the "System Account".  I've successfully implemented the solution suggested by Julie Kramer, from the office dev blog.  Here we go:

snippet of a workflow design in VS2008 - focus on the two red activities




  1. Assign a new field to the Executor property of the OnTaskChanged activity in question (you'll see this property in the property window on the activity). Note we use this new field in a later LogToHistoryListActivity's Method_Invoking() by assigning the UserID property of the LogToHistoryListActivity's object





  2. Add a userid lookup/helper function to guarantee a valid SharePoint user id is in place
        private SPUser GetUserObject(string accountID)
        {
            try
            {
                if (accountID.IndexOf(@"\") > 0)
                {
                    SPUser user = this.workflowProperties.Web.SiteUsers[accountID];
                    return user;
                }
                else
                {
                    //replace DOMAIN 
                    SPUser user = this.workflowProperties.Web.SiteUsers[@"DOMAIN\" + accountID];
                    return user;
                }
            }
            catch
            {
                //replace DOMAIN and administrator
                SPUser adminUser = this.workflowProperties.Web.SiteUsers[@"DOMAIN\administrator"];
                return adminUser;
            }
        }
As you assign a new field to each TaskChangedEvent's executor property, you'll see this declaration inserted to the bottom of the workflow class.


public String RVPReviewTaskChangedEvent_Executor1 = default(System.String); 

Later when the LogToHistoryListActivity's Method_Invoking event is triggered, you use this new field and the helper function to modify the UserID property on the LogToHistoryListActivity's object;



        private void logRVPReviewed_MethodInvoking(object sender, EventArgs e)
        {
            SPUser executor = GetUserObject(RVPReviewTaskChangedEvent_Executor1);
            logRVPReviewed.UserId = executor.ID;

        }

19 October 2009

dosa recipe

Ingredients 
1 cup urad dhal 
2 cups rice flour



Method
Soak dhal overnight & grind the next day with rice flour.  Let it ferment in a warm place. 


After it ferments, add salt & 1/8 teaspoon methi powder.


Make dosas in a flat skillet  by using the onion to oil the skillet -- add ghee to crisp if needed

indian food camping recipes; upmav and egg masala

Upmav


Ingredients


2 cups Rava(semolina) -- roasted without oil
Oil for cooking
Mustard seeds-- 2 tspn
Onions-- 2 large chopped fine
1" piece ginger
5 green chillies-- cut up
3 sprigs curry leaves
1/2 bunch coriander leaves
Salt & lemon juice-- for later


Method

1. Roast rava in a pan till you get the aroma from it & slightly changes color-- set aside.
2. Heat 1/4 cup oil in a pan.
3. When hot -- add mustard seeds.
4. You'll hear the crackle-- & cover it as it'll splutter.
5. Add chopped onions & curry leaves. Fry onions to a deep golden brown.
6. Add ginger, chillies & coriander leaves & fry a bit.
7. Add roasted rava & continue for a bit more.
8. Turn off heat-- cool it completly before packing it for the trip.


AT THE CAMP


Boil 2 cups water. Add salt to taste & then add in the upmav mixture & simmer for a couple of minutes. Add lemon juice for flavor.


Egg Masala 

Do ahead
1 dozen eggs hard boiled with salt -- set aside


At home
Fry onions in a pan-- deep golden color.  Add a bit of cloves & cinnamon. Add ginger & green chillies & fry.  Add turmeric & chilli powder. Add tomatoes & coriander leaves. Cook dry & let it cool.


At the camp 
warm up onion masala & halve boiled eggs & cook it all together.
** Could add extra canned tomatoes if needed.

05 October 2009

SharePoint vs. File Servers

Whenever you talk to someone about the document management features of SharePoint, the question comes up; how does one differentiate and create guidance around when to use a file share versus when to use a SharePoint Document Library.  There are many levels of appreciation of SharePoint's feature set - and kind of like an onion, there are many things that are underneath the surface.  Here are some examples of features that are difficult to implement on a file share:
  • commented version history
  • file metadata / content classification
  • audit tracking
  • data retention policy implementation / enforcement
  • self-service recoverability
  • business processes / workflow
Moreover, below are some examples of when to use a file share over SharePoint:
  • audio streaming or video streaming
  • product distribution
  • server & desktop backups
  • Access database storage
  • custom tools distribution, utility executable distribution, script distribution
  • archive file storage

Table: Simplified Comparison of File Server file features and SharePoint Server file features


Windows 2003 R2 File Share 


SharePoint Server Document Center


ACL based File Security and Effective permissions (AD only)

Authorization based Item Security with user picker, supporting AD, LDAP, and .NET Pluggable providers
Opt in email based Request Access


Windows Auditing


Security and Policy based Auditing, expiration and pivot reports

Shadow Copy User Restore

(not configured by default)


User Restore with Recycle bin

2nd Stage Site Collection Recycle bin (default)


Distributed File System Replication

(not recommended with two way editing)
WAN Throttling
RDC (Remote Differential Compression) 


One Way Content Publishing paths and jobs including quick deploy
# Threads throttling and scheduling
Multi Farm Shared Services (not over WAN)

Email enabled (requires configuration)


Check in Check out w/ Forced Checkout

Snapshotted versions (not change based versions)

Version History/ Major/Minor Versions


File level Rights Management


File and Doc Library Rights Management Integration Policies

Sorting, (Grouping in Vista), Workflow Engine (requires customization)

Filtering, Grouping, Workflow (out of box), Content Types

File Service Resource Manager for Quotas or 3rd party


Site Collection Quotas, Built in Usage Reporting, Storage Manager

NTFS Compression, EFS and My Documents Redirection (client dependencies)
Database Encryption with Third Party, Backup Compression with Third Party

Non Transactional.  No Rollback without Shadow Copies


SQL Server Transaction Logs

Source (Joel Olson) reference: http://blogs.msdn.com/sharepoint/archive/2007/01/02/is-the-file-server-dead.aspx

30 September 2009

Searching your SharePoint sites with Internet Explorer 8

IE8 follows the FF path and has a customizable Search Toolbar that can be plugged into a SharePoint instance. Start by clicking on the “Find More Providers” menu item on the drop down in the IE8 search toolbar area.

On the bottom of the Providers screen you can find a link: “Create your own Search Provider”. So if you want to add your SharePoint search page to the IE toolbar, follow the on-screen directions; enter SharePoint search result URL after typing TEST - e.g. http://intranet/search/Pages/results.aspx?k=TEST .

Now you’re able to use your SharePoint search site directly from your browser

credits: this post is nearly verbatim from this blog

28 September 2009

sometimes it takes a tough man to make a tender chicken

how darwinism reflects on programming, and the concept of thriving / surviving. Darwin finds that it is not the strongest, nor the brightest, nor the prettiest of the species survives, but the ones that are most apt to adapt (change-ready).

Serendipitiously, I came across 'a 50%-good solution that people actually have solves more problems and survives longer than a 99% solution that nobody has because it’s in your lab where you’re endlessly polishing the damn thing. Shipping is a feature. A really important feature. Your product must have it.'

23 September 2009

"Failed on Start (retrying)," said the workflow

Seemingly inexplicably, SharePoint will less than always cooperate. In this case, it happened after a major round of refactoring custom workflow solutions, but ULS logs and other debugging techniques were proving fruitless. After going through the various debugging tips posted on various blogs such as:


http://blogs.msdn.com/wael/archive/2008/01/11/workflow-failed-on-start-retrying.aspx


I found the solution was don't refactor so deeply, or really know when an XML attribute is referring to a library.classname or namespace.classname (OUCH, the subtlety).

e.g. in my case, workflow.xml's attribute for

CodeBesideClass = "unbudgetedBI_InitialApprovalWF.Workflow1"

then the workflow project (called "unbudgetedBI_InitialApprovalWF") has a workflow file called "initialapproval.cs" (with corresponding .rules and .desiginer.cs). Within this c# file is the namespace "unbudgetedBI_InitialApprovalWF" and a public class "Workflow1".

When trying to launch the workflow (after watching the submit_click method of the initation / instantiation form fire successfully within a debug session), the Site.WorkflowManager.StartWorkflow() does not cause an exception within the debugger, but the workflow status becomes "Failed on Start (retrying)".

ULS logs are chock full of valuable information, but most of it is irrelevant to the problem at hand, so I recommend changing the logging settings such that All events are ignored;

Central Administration > Operations > Diagnostic Logging Event Throttling. Category= All, Least critical event to report to the trace log= None. Press OK.

then, do it again but give yourself verbose logging for 'general';
Central Administration > Operations > Diagnostic Logging Event Throttling. Category= General, Least critical event to report to the trace log= Verbose. Press OK.

Now when the workflow failure occurs, you see this:
Unknown SPRequest error occurred. More information: 0x8000ffff
Unable to locate the xml-definition for CType with SPContentTypeId '0x01080100FD8D480B48CA4A928E9D31E74A4134B1', exception: Microsoft.SharePoint.SPException: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED)) ---> System.Runtime.InteropServices.COMException (0x8000FFFF): Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
at Microsoft.SharePoint.Library.SPRequestInternalClass.GetGlobalContentTypeXml(String bstrUrl, Int32 type, UInt32 lcid, Object varIdBytes)
at Microsoft.SharePoint.Library.SPRequest.GetGlobalContentTypeXml(String bstrUrl, Int32 type, UInt32 lcid, Object varIdBytes) --- End of inner exception stack trace ---
at Microsoft.SharePoint.Library.SPRequest.GetGlobalContentTypeXml(String bstrUrl, Int32 type, UInt32 lcid, Object varIdBytes)
at Microsoft.SharePoint.SPContentTypeCollection.FillCollection(SPRequest req, SqlDataReader rdr, Boolean openWeb)

What is this contenttype that is missing, we are left to wonder. What a wild goose chase that creates! So I'll spare you more heartache and headache and tell you simply: don't refactor too much. In this case, I changed the name of the workflow file within the project. Apparently the XML attribute CodeBesideClass refers not to a namespace.classname but to libraryname.classname AND a class name within the c# file should reflect the name of the file itself (but I am no c# guru).

So I changed the filename from "initialapproval.cs" back to the default "Workflow1.cs" and my workflow ran just fine.

At least this made me laugh:


Homer: [reading screen] "To Start Press Any Key".

Where's the ANY key?

I see Esk ["ESC"], Catarl["CTRL"], and Pig-Up ["PGUP"].

There doesn't seem to be any ANY key!

Woo! All this computer hacking is making me thirsty. I think I'll order a TAB.
[presses TAB key]



Homer: Trying is the first step towards failure.

yet another online profile

To help out google search's results / where is pritish / ego surfing, I've added a google profile (seems like a GOOG toe in the water of social networking, but it isn't orkut)

Now if you type 'pritish' or 'pritish jacob' in the search box for google, you might stumble upon this
http://www.google.com/profiles/118099086105421407263

20 August 2009

the at&t hidden interface for call forwarding

  • Immediate Call Forwarding: Dial *21* plus the 10-digit number to which your calls should be forwarded and #. Press Send.
  • Busy Call Forwarding: Dial *67* plus the 10-digit number to which your calls should be forwarded and #. Press Send.
  • Call Forwarding No Reply: Dial *61* plus the 10-digit number to which your calls should be forwarded and #. Press Send.
  • Call Forwarding Not Reachable: Dial *62* plus the 10-digit number to which your calls should be forwarded and #. Press Send.

unlike this http://www.wireless.att.com/learn/basics/choosing-features-services/call-forwarding.jsp reference sheet, the above are direct ways of manipulating the call forwarding features that many of us enjoy (without knowing).

17 August 2009

the PeopleEditor and how Validation sucks in SharePoint

Just over another hurdle in the SharePoint steeplechase. This one involves the glorious PeopleEditor control and how to make sure the user has some client-side feedback before they post their selection. Through the nest of blogs and comments about the general ASP.NET versus the universe of SharePoint problem, the best solution seems to revolve around hacking the client side javascript and doing the most manual processes imaginable to get consistent validation.

Precisely, I mean that within the PeopleEditor should support simple validation out of the gate, but the AllowEmpty property doesn't work (see Karine Bosch’s comments from this blog link). Then you end up going through the following failure steps before the aforementioned hack emerges as the winner:
  1. AllowEmpty property of PeopleEditor (Karine Bosch’s link) #FAIL
  2. ValidatorEnabled property of PeopleEditor (Karine Bosch’s link) #FAIL
  3. Adding the ASP.NET RequiredFieldValidator element within the ASP form (shereen's blog link) #FAIL
  4. Calling Page.Validate() / Page.isValid within onsubmit() (Ben Cline's blog link) #FAIL (because it is really challenging to server-side redirect /repost the user data back to the second step of an association form within a workflow association)
  5. Inserting a RequiredFieldValidator by override CreateChildControls() within the code-behind-form (see link to a blog SharePoint Solutions team, the "experts and pioneers on Microsoft SharePoint") sorry, another #FAIL, though from 2006
  6. (Now we are getting closer.. ) A similar problem with a close kin of this SPControl is solved by Greg Galipeau in his post about SharePoint DateTimeControl Validation. But since it is a long day and I'm not getting any younger with all this chasing blog trails, #FAIL
Now the winning hack, by the same person Shereen (from #3 above) who got it right the second time - thanks for being an extremely passionate ninja and posting your updated solution (which I'm going to copy below incase it disappears one day into the digital ether)
This post is an update to a previous post I had written on validating the PeopleEditor control on post back. In that particular post, I described the challenges of getting a PeopleEditor control, within a custom application page, to validate correctly as a required field on the client side (I had server side validation already in place and
working correctly).

For the most part, the solution I outlined worked well,
except for some situations where other controls on the page were performing
their own post back (for example, a data grid in edit mode). I found that on
submit of the entire form, the ASP.NET required field validator for the
PeopleEditor control would kick in informing me that the field was required.
However, there was a valid entry in the control so I could only conclude that
the post back by some other control on the page was mucking up the view state
for the PeopleEditor control and on submit the form was no longer aware that
this field did in fact have a value in it.
The MSDN article found here outlines my problem exactly with the eventual solution further down in the thread. I just wanted to highlight it here because it was exactly what I needed to resolve my issue. Thank you to Jan Lange for posting his solution!
inside the script tag, in the asp.net page's header (I've got to move to a blog that I can post code in. ridiculous blog=#FAIL)

language="javascript"
function CheckProjectManager(source, arguments) {
if (aspnetForm.ctl00_PlaceHolderMain_ProjectManager_downlevelTextBox.value == "")
arguments.IsValid = false;
else
arguments.IsValid = true;
}


<SharePoint:PeopleEditor
ID="ProjectManager"
AllowEmpty="false"
ValidatorEnabled="true"
MultiSelect="false"
runat="server"
SelectionSet="User"
Width="200px"
TabIndex="2" />

<asp:CustomValidator
ID="rfvProjectManager"
runat="server"
ControlToValidate=""
ErrorMessage="Required"
Enabled="true"
ClientValidationFunction="CheckProjectManager" />

Just to outline, what Jan eventually did was create a custom validator that called a javascript function to validate the control. Within that function he checks to see if the control is empty and stores the results of the validation in the IsValid property of the ServerValidateEventArgs object. Notice that he also sets the ControlToValidate property to “”.
http://blog.qumsieh.ca/2009/02/12/validating-a-peopleeditor-control-on-postback/