UpdateProjectWorkspaceAddress fails with WSSWebIsNotProjectWorkspace error


So, I am working on a Proof of Concept that integrates TFS 2008, Project Server 2007 and MOSS.

After I create a site based  upon a custom site template I then create a project using the PWA web services (UpdateProjectWorkspaceAddress).  The project is created but when I try and update the project workspace URL using the wssinterop web service it fails with a WSSWebIsNotProjectWorkspace error. 

The template has the correct features activated and if I manually (through the PWA Admin UI) set the project workspace to the same web it works. 

I don't know why it fails since everything looks good but I did discover a workaround after looking at it for many hours. 

Call the same method twice.  Catch the first error and ignore it.  On the second call it returns sucessfully and sure enough it does update the URL.

I figured I would share that and save someone a few hours of frustration.

Example ( string projectName, Guid projectId, projectSvc which is reference to the webservice: http://servername/pwa/_vti_bin/psi/Project.asmx are passed in )

 

private void SetWSSURL(string projectName, Guid projectId, PWA.Project projectSvc)
{

WssInterop.

#region

WssInterop wssInterOpSvc = new WssInterop.WssInterop();
wssInterOpSvc.Url =
http://servername/pwa/_vti_bin/psi/wssinterop.asmx;
wssInterOpSvc.Credentials = CredentialCache.DefaultCredentials; Get workspace info
// Get the admin settings necessary for site linkage
WssInterop.WssSettingsDataSet dsCurrentWssInfo = wssInterOpSvc.ReadWssSettings();
WssInterop.WssSettingsDataSet.WssAdminRow adminRow = dsCurrentWssInfo.WssAdmin[0];
Guid wssWebAppUid = adminRow.WADMIN_CURRENT_STS_SERVER_UID;

//I am not using the default site collection.  I am using the TFS one (Sites/)
//if (!adminRow.IsWADMIN_DEFAULT_SITE_COLLECTIONNull())
//{
//        siteCollection = adminRow.WADMIN_DEFAULT_SITE_COLLECTION;
//}
#endregion
#region
Change Workspace Address
//try it once and ignore the output -- always fails the first time.
try
{
     projectSvc.UpdateProjectWorkspaceAddress(projectId,
"Sites/" + projectName, wssWebAppUid);
}
catch{ }
//do it again and it works. Don't ask me it's microsofts interface.
projectSvc.UpdateProjectWorkspaceAddress(projectId, "Sites/" + ProjectName, wssWebAppUid);
#endregion

}

author: CMD | Posted On Monday, February 09, 2009 1:08 PM | Feedback (1)

Rough draft finished.


I haven't posted through the holidays.  I have been working but nothing intersting enough to post about. 

I have been on another writting kick.  The book is done...at least the rough draft is as of this evening.  175,000 words.  I'm sure that will swell as I edit it but I really like how it has turned out.  The question is:  will anyone else?  

I have turned parts over to someone who is reviewing it for me, kind of a personal editor.  It is always very different (and unnerving) to have someone else read what you have written.  The story is alive in your head, things that make perfect sense to you may not make sense to someone else that is reading it.  All part of the process I suppose.

I am going to take a break for a week or so and then go back through it editing it.  I have spent so much time on this over the holidays that other things have been left untouched...the Christmas lights come down tomorrow...I promised my wife.

One of the goals I set for myself this year is to start looking for a literary agent by mid-year.  It will need to be hammered into shape if I am going to accomplish that.  Goals a are a good thing.

 

author: CMD | Posted On Friday, January 09, 2009 6:12 PM | Feedback (0)

CQWP, QueryOverride and Columns of type 'User'


I figured I would share an interesting thing I discovered today that appears to be amazingly undocumented.

If you use U2U CAML Query Builder to build your CAML queries it creates queries that look like this when querying against columns of type 'User':

 <property name="QueryOverride" type="string">
      <![CDATA[<Where><Eq><FieldRef Name='Author' /><Value Type='User'>[Me]</Value></Eq></Where>]]>
 </property>

And that query will not work.  It will return zero results.

So queries like this:

<property name="QueryOverride" type="string">
          <![CDATA[<Where><Eq><FieldRef Name="Index_x0020_Number" /><Value Type="Number">7</Value></Eq></Where>]]>
</property>

and this:


<property name="QueryOverride" type="string">
          <![CDATA[<Where><Contains><FieldRef Name="Title" /><Value Type="Text">testapp</Value></Contains></Where>]]>
</property>

will work fine but using the token '[me]' like it is used everywhere else in MOSS will not work.

The solution ends up being this:

<property name="QueryOverride" type="string">
        <![CDATA[<Where><Eq><FieldRef Name='Author'  /><Value Type="User"><UserID /></Value></Eq></Where>]]>
</property>

 

author: CMD | Posted On Monday, December 15, 2008 11:46 AM | Feedback (4)

A Novel Marathon


How much can you write in a weekend?  I couldn't have answered that question prior to this weekend but now I can.

This is in regard to this other post I made:  Programming vs. Writing a Novel

Now I don't want any hate mail from all you jealous guys because I will get all the babes being as cool as I am (just kidding honey) BUT I did crank out close to 20,000 words this weekend...and that is just plain awesome...or sick depending upon your perspective.
 
I got into a groove Friday night and stayed up until about 4AM, I didn’t really want to go to sleep at that point but the coffee stopped working at about 3AM and my eyelids rebelled.  I picked it back up at noon on Saturday and stayed at it until about 2AM.  After dragging my sorry backside out of bed Sunday I worked on it until about 1AM this morning.  Total time:  ~31 hours.  That equates to about 645 words/hour or just under 11 words/minute.  Hmmm…that doesn’t really sound very fast does it?

What did all this require?

  1. Coffee -- lots and lots of coffee
  2. An open weekend with the wife and kids off doing stuff that didn't require my presence.
  3. Tylenol for the sore hands.
  4. Hot pockets – the breakfast, lunch and dinner of champions.
  5. Some really good music (Eroica Trio, YoYoMa\Morricone, Coldplay, U2 etc, etc)
  6. Did I mention coffee?

I generally don't believe in quantity over quality but frankly this is good stuff even if I have to pat my own back.  I reread what I had written late last night to make sure it worked with what I had prior to this weekend.  Frankly I am pretty jazzed about how things are going.  At this rate I might actually finish before the turn of the century. 

Since I was asked to post this stuff:  I spoke to an friend who happens to be an attorney (yes some attorneys actually have friends) who asked a colleague about copywriting for me.  Evidently in the US and Europe just by writing something down it is copywrited by definition.  It is your intellectual property.  The purpose for registering your copywrite with the Library of Congress is simply to make it easier to sue someone for infringing upon your copywrite. 

He also told me that it costs ~$50 US as a filing fee with Library, a one page form and a copy of your work (whatever it might be).  He also told me that if I was incompetent and couldn't read simple instructions he would be happy to fill out the form and file it for me for $500 US – their firm does it all the time.

One last bit of information.  He also said unless I was going to be distributing it prior to its completion there really was no reason to register the copywrite until it was done.  I haven't been handing out copies (takes forever to print) and the only person who has read any significant portion of it is a friend who is acting as an editor. 

You learn something every day.  With all that said I won't be posting any excerpts for awhile since I am a cheap dude.  Women love cheap dudes don’t they?

author: CMD | Posted On Monday, November 24, 2008 12:02 PM | Feedback (0)

WSS vs Portal Server Service Pack mismatch


Ok.  I have dealt with mismatched version numbers between servers countless times in both SharePoint 2003 and 2007 when transferring data between two environments.  What I had not run into (until today) was the fact that WSS 2.0 can be updated (SP3) while Sharepoint Portal Services was bone-stock-out-of-the-box.  It took me a bit to figure out what was going on. 

I was attempting to restore a 2003 site into a test environment but was getting the dreaded "Your backup is from a different version of Windows SharePoint Services and cannot be restored to a server running the current version" which is always good for a case of heartburn.

SOP is to go pull up the control panel\add remove programs and pull up the support information for Microsoft Office SharePoint Portal Server 2003 (in this case) on both machines and compare the version numbers.  Unfortunately they both matched.  Didn't expect that.  Twenty minutes of thought and looking at DLL's and I thought about the "other" service installed Windows Sharepoint Services 2.0 (in this case).  Sure enough someone had updated WSS to SP3 but had neglected to update the Portal Server to SP3.

I'm still not sure why the previous owner decided to update the server half-way.

 

author: CMD | Posted On Thursday, November 20, 2008 12:34 PM | Feedback (0)

Programming vs Writing a Novel


Besides programming I am working on a personal project -- writing a novel.
 
This is a project I started in 1994 and dropped shortly after due to other things in my life at the time.  I have recently picked it back up. 
 
I have always enjoyed writing and the exercise has been strangely cathartic.  Basically the rough draft is around 75,000 words, slightly less than half done.  I'm a little worried about getting everything into 200,000 words but I will burn that bridge when I get to it.
I don't know the first thing about getting a book published but I assume if it is good that will happen naturally -- of course it can be like everything else in my life and not happen whether it is good or not.
So, I have no plan for getting it published and frankly I don't even want to think about it at this time. When I told that to my ever-forbearing wife she asked me why I was writing it which is a good question.  I guess I just feel like it.
 
Actually when I think about it, it is somewhat like programming in that when you are done and everything works you get that satisfied feeling of having created something of value. When I finish a chapter and re-read it and I like what I read, I get the same feeling. It is slightly different, writing a novel is a different type of creativity after all, but it is very rewarding.

author: CMD | Posted On Tuesday, November 18, 2008 11:29 AM | Feedback (2)

List Does Not Exist


In working through an issue with workflow I stumbled across an interesting 'feature' of workflow and MOSS.

Essentially I have a "Project Sites" root web where I am creating child sites via a workflow:

Project Sites
          Child Site 1
                    List 1
                    List 2

In these child sites I am creating some lists and setting alerts on them based upon things that happen in the workflow.

In attempting to create an alert on a list, I received a "List does not exist" error.  In stepping through the code and inspecting all the objects everything seemed valid.  SPList is a valid list in the site, SPUser is a valid user.

I went down the path of it being a security issue because that would make sense but security was set correctly, the process account of the timer service and the iis process account is an owner of the list.   I have struggled with this for awhile before figuring it out.  I even thought this might have something to do with the fact that I just created the site from workflow so I put a delay in to dehydrate the workflow and then rehydrate it again before trying to set the alerts.

The relevant lines of code:

 ...

SPUser user = workflowproperties.Web.EnsureUser("...");
this.SetAlert(user,list,evtType,evtFreq,alertType, true);   
private void SetAlert(SPUser sPUser, SPList sPList, SPEventType eType, SPAlertFrequency frequency, SPAlertType aType, bool omitFromMe) 
{  
    if (!HasAlert(sPUser, sPList))  
    {  
 
         SPAlert sPAlert = sPUser.Alerts.Add();  
         sPAlert.AlertType = aType;  
  
         sPAlert.Title = sPList.Title;  
         sPAlert.EventType = eType;  
         if (omitFromMe)  
         {  
             sPAlert.Filter = "<Query><Neq><Value type='string'>" + sPUser.Name + "</Value><FieldRef Name='Editor/New'/></Neq></Query>";  
         }  
 
         sPAlert.AlertFrequency = frequency;  
         sPAlert.User = sPUser;  
         sPAlert.List = sPList;  
         sPAlert.Status = SPAlertStatus.On;  
         sPAlert.AlwaysNotify = false;  
         sPAlert.Update(true);  
    }  
}
 

Very straightforward really.

It turns out that the issue was where I got the SPUser object from.  Like most programmers I tend to do things consistently and I usually use workflowproperties.Web.EnsureUser(...) to get my SPUser objects.  As it turns out if you get your User Object from a different web then the parent of the list you are attempting to create an alert on you will get this error.  Go figure.

What worked:

SPUser user = list.ParentWeb.EnsureUser("...");
this.SetAlert(user,list,evtType,evtFreq,alertType, true);   



 

author: Duden | Posted On Tuesday, November 18, 2008 10:34 AM | Feedback (1)