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.
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.
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.
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".
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\
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.
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:
Create Columns or Add from existing site columns
go Advanced Settings > Allow managment of Content Types=Yes,
then Add from existing site content types
then Change new button order and default content type and set the new content type up as #1 (for example)
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:
How and when to modify ASPX page elements from the code-behind c# class
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;
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.
...
//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:
Two requests that are probably part of every SharePoint workflow design:
Permit only the users who are assigned a WF tasks to edit (i.e. complete) them
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:
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:
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)
Log in to your blogger account (try using google's beta), look for the blog in question, click Layout
The URL should read http://draft.blogger.com/rearrange?blogID=magicnumber
Click Edit HTML
Backup your current template to a local file, by clicking Download Full Template
Edit the template: I inserted the below javascript & css declarations after the HTML tag, and Before the Head tag
So now to post something with code, while preparing the post:
Click Edit HTML
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 < and > 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
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.:
// 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.
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
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
Add a userid lookup/helper function to guarantee a valid SharePoint user id is in place
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;
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.
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
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.
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.'
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:
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).
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]
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)
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:
AllowEmpty property of PeopleEditor (Karine Bosch’s link) #FAIL
ValidatorEnabled property of PeopleEditor (Karine Bosch’s link) #FAIL
Adding the ASP.NET RequiredFieldValidator element within the ASP form (shereen's blog link) #FAIL
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)
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
(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; }
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 “”.