Skip to main content

ASP.NET Geek

Go Search
Home
  

Suman Chakrabarti
Ramblings about SharePoint and ASP.NET

MOSS/WSS SDK 1.4 - has Federated Search web part examples

Mon, 01 Sep 2008 15:54:00 GMT

In case you missed hearing about the new SDK, here's a great post on what's in it.

http://blogs.msdn.com/randalli/archive/2008/08/28/just-published-wss-and-moss-sdk-1-4-download-and-online-msdn-library-8-29-2008.aspx

Starting/Canceling a SharePoint Designer workflow programmatically

Sat, 16 Aug 2008 21:12:00 GMT

I had enough trying to find this code, so I'm putting what I've pieced together to activate a workflow programmatically (specifically a SharePoint Designer Workflow)

public static string StartWorkflow(ContractListItem contract, string workflowName) {
            SPListItem wfListItem = contract.ListItem;
            SPWorkflowAssociationCollection wfAssocs = wfListItem.ParentList.WorkflowAssociations;
            SPWorkflowAssociation activeWorkflowAssoc = null;
            string errorMessage = string.Empty;

            foreach (SPWorkflowAssociation wfAssoc in wfAssocs) {
                if (wfAssoc.Name.Equals(workflowName)) {
                    activeWorkflowAssoc = wfAssoc;
                    break;
                }
            }

            // if the workflow exists, start the workflow
            SPWorkflow activeWorkflow = null;
            if (activeWorkflowAssoc != null) {
                try {
                    activeWorkflow = SPContext.Current.Site.WorkflowManager.StartWorkflow(
                        wfListItem,
                        activeWorkflowAssoc,
                        "<Data></Data>");
                }
                catch (Exception ex) {
                    ErrorHandler.LogError(Resources.ActionBarWebPart_WorkflowNotStarted, ex);

                    if (activeWorkflow != null)
                        SPWorkflowManager.CancelWorkflow(activeWorkflow);

                    errorMessage = Resources.ActionBarWebPart_WorkflowNotStarted;
                }
            }
            else {
                ErrorHandler.LogError(Resources.ActionBarWebPart_WorkflowDoesNotExist);
                errorMessage = Resources.ActionBarWebPart_WorkflowDoesNotExist;
            }
            return errorMessage;
        }
  }

Get PublicKeyToken using external tools

Wed, 16 Jul 2008 15:15:00 GMT

I hate fishing around to get the publickeytoken for my strong named assemblies, so I fished around for a way to do it in Visual Studio. Here's what I did:

  1. Create a new External Tool - I called mine Get PublicKeyToken
  2. Map to the sn.exe file in the Windows SDK <DRIVE:\>Program Files\Microsoft SDKs\Windows\v6.0A\Bin\sn.exe
  3. Add the command you want to execute, in this case, it's -T $(TargetPath) - you can get the TargetPath monniker from the flyout.
  4. Check the Use Output window checkbox.

Get PublicKeyToken

Now, to execute it, select a *.dll file. You can select the file in the bin directory of your dev project, go to Tools->Get PublicKeyToken and the output will be rendered to the Output window.

SharePoint ReadOnly Field can be written to by workflows

Tue, 24 Jun 2008 15:16:59 GMT

So, I scoured the internet (all of it, I swear) to find some information on readonly fields in SharePoint. Apparently, SharePoint workflows can write to readonly columns. The only problem I'm having now is getting the column to show up in a columns list.

private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e) {
  SPList list = workflowProperties.List;

  if (!list.Fields.ContainsField(FIELD_NAME))
    list.Fields.Add(FIELD_NAME, SPFieldType.User, false);

  SPFieldUser field = (SPFieldUser)list.Fields[FIELD_NAME];
  field.Title = FIELD_NAME;
  field.AllowDisplay = true;
  field.ReadOnlyField = true;
  field.ShowInDisplayForm = true;
  field.ShowInEditForm = true;
  field.ShowInDisplayForm = true;
  field.ShowInEditForm = true;
  field.ShowInListSettings = true;
  field.ShowInNewForm = true;
  field.ShowInVersionHistory = true;
  field.ShowInViewForms = true;
  field.Update();
}

private void codeActivity1_ExecuteCode(object sender, EventArgs e) {
  workflowProperties.Item["restricted"] = "test: " + DateTime.Now.ToShortTimeString();
  workflowProperties.Item.Update();
}

Woo- hoo! It works!

Windows Live Cashback program ROCKS!

Thu, 29 May 2008 20:21:13 GMT

I just bought a video camera online, so I figured I'd check out the Live Cashback program and see if it would work out well. It totally rocked. I found the camera I wanted at a better price than I could find on other online shopping search sites, then I found I would get 4% back on the camera price and 4% back on the warranty to accompany it.

This deal totally rocks!

Navigon - a Windows Mobile 6 GPS

Mon, 19 May 2008 03:57:28 GMT

I just got my Navigon 7100 GPS and I have to say I'm impressed. I really like the navigation quality of the GPS, especially compared to my TomTom ONE. I like the TomTom's ease of use--in fact, I like it better than my friends Garmin nuvi, but the TomTom ONE doesn't have some really important features that I need for my weekly trek's about the east coast.

Anyway, the Navigon has icons that match the chain restaurants and hotels, Zagat ratings (including the reviews), a built-in traffic receiver, and more POIs than my TomTom.

So, here's the bad:

If you've never had a GPS before, the UI is a little cumbersome. It comes with a stylus because some of the icons/buttons are too small to hit with your finger--almost frustrating enough to send back.

In the end, I think I love it because of its actual navigation quality. It takes the same routes I would take (which neither Garmin nor TomTom would do). I also love the RealityView when you're on a major highway with a lot of lane decisions, it shows signs on a highway and an arrow for which lane you should be in. Finally, I love the fact that it allows me to extremely easily choose a POI or interim stop without making me rebuild my navigation course.

Presentation at CodeCamp Pittsburgh

Mon, 14 Apr 2008 15:47:48 GMT

I presented a Silverlight 1.0/2.0 demonstration yesterday at CodeCamp and it went quite well. Most importantly, it compiled; hey, that's half the battle.

The talk started out about how POX is not truly a ReST service because POX services are not usually provided as post-able services that control and manage information processing. With POX services, the idea is really to share the information with the user interface. So, I put together a service that provided customer order information from the AdventureWorks catalog. The information was provided in JSON format to the front end Silverlight 1.0 and 2.0 interface.

The Silverlight 1.0 portion of the demo went really fast, mainly because I kept the JavaScript in code snippets so I wouldn't end up debugging any of it. The Silverlight 2.0 piece took some time because I had to write all the code from scratch because I forgot to save the code in snippets. It did look like I knew what I was doing, though.

Anyways, thanks to Mike Snell, Craig Oaks, and Dave Hoerster for hosting CodeCamp! It was a fun time and I got to eat burritos.

Addition to Steve Peschka's PartCheck code

Wed, 26 Mar 2008 13:47:00 GMT

I ran into a problem when trying to use Peschka's PartCheck code for My Site autoconfiguration to modify some boolean fields on the Colleague Tracker web part and found some modifications you'll need to make in order to set boolean fields on controls with this code:

private object GetPropertySetterValue(string Value) {
  ...
  switch {
    ...
    default:
      bool result;
      if (bool.TryParse(Value, out result))
        return result;

      break;
  }
  ...
}

This will allow the boolean value to be passed correctly to the control.

Presenting at Pittsburgh Code Camp - WCF POX/ReST Services with Silverlight 1.0 and 2.0

Wed, 26 Mar 2008 13:37:00 GMT
I'm speaking at Pittsburgh's Code Camp on April 12th located at University of Pittsburgh's Sennott Square. I'll be presenting POX services using WCF and ReST (although many will agree that POX is not truly ReST) to supply data to a Silverlight 1.0 application and I will use the same services with a Silverlight 2.0 application.

IIS app pool limits to keep in mind for SharePoint

Tue, 25 Mar 2008 21:18:16 GMT

Depending on your hardware configuration IIS 6.0 does have a potential limit to the number of application pools. The TechNet FAQ for IIS stated here says:

The answer varies depending on the hardware and software configurations of your server as well as the types of content it hosts. If you are setting up your application pools with unique identities, depending on the applications and memory resources of your server, you will reach a limit of about 60 application pools. There are finite limits to some system resources that are allocated with each new logon session. This means that 60 processes can run concurrently as distinct accounts. IIS 6.0 supports running these processes in a single shared desktop, at a cost of sharing a single encapsulation of a user session among all parties.

There is a way to scale far beyond 60 worker processes, but why would anyone want to do that?

SharePoint Star Wars lines

Fri, 21 Mar 2008 03:41:00 GMT

I posted these to Joel Oleson's MSDN blog, but since he's moving the blog, I didn't want to lose them.

Uber-nerd SharePoint versions of Star Wars lines:

  • These aren't the content databases you are looking for. (compliments Eric Charran)
  • If you only knew the power of the stsadm -o installfeature -force.
  • There will be a substantial reward to the Site Collection Admin that finds the deleted document, but I want it restored, no disintegration's!
  • What is thy bidding, my Master page?
  • Search your index, you know it to be true.

Enjoy!

Migrating Web Part Pages to Publishing Pages

Mon, 17 Mar 2008 01:54:00 GMT

Unfortunately, you cannot natively migrate web part pages to WCM publishing pages. The benefit of publishing pages manifests itself in the centralized page layouts. Web part pages cannot be modified universally, but publishing page layouts can be thusly modified.

So, to build a utility for migrating web part pages, it's a messy recipe. The result is only publishing pages with web parts intact, but not in the proper location nor is the page layout maintained; however, it is a better deal than to have to migrate web parts individually.

Start by making sure the web is a PublishingWeb:

if (PublishingSite.IsPublishingWeb)
    return PublishingWeb.GetPublishingWeb(web);

Get all web part pages by looping through all document libraries and getting web part pages:

foreach (SPListItem item in doclib.Items) {
    if (item.File.Url.EndsWith(".aspx")) {
        WL("Adding web part page: {0}", item.File.Url);
        webPartPages.Add(item.File.Url, item);
        count++;
    }
}

Next, create a new publishing page from a selected page layout (BlankWebPartPage.aspx is a good one):

// get the blank web part page layout
List<PageLayout> layouts = new List<PageLayout>(pubWeb.GetAvailablePageLayouts());
PageLayout layout = layouts.Find(
    delegate(PageLayout l) {
        return l.Name.Equals(pageLayoutName, StringComparison.CurrentCultureIgnoreCase);
    });

// get the pages collection and add the new publishing page
PublishingPageCollection pages = pubWeb.GetPublishingPages();

// change the name of the new page if it already exists
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='Text'>" + item.File.Name + "</Value></Eq></Where>";
SPListItemCollection items = pubWeb.PagesList.GetItems(query);
string pageName = item.File.Name;
if (items.Count > 0) {
    string fileExtension = DateTime.Now.ToString("_MMddyy_hhmmss");
    pageName = pageName.Replace(".aspx", fileExtension+".aspx");
}

// create the new page
PublishingPage publishingPage = pages.Add(pageName, layout);
publishingPage.Title = item.Title;

Get a few SPLimitedWebPartManagers to read the old web parts and store them and to create new web parts on the publishing page:

SPLimitedWebPartManager wppWpm = ((SPWeb)site).GetLimitedWebPartManager(item.File.Url, PersonalizationScope.Shared);
SPLimitedWebPartManager publishingWpm = ((SPWeb)site).GetLimitedWebPartManager(item.File.Url, PersonalizationScope.Shared);

Now you've got to copy the web parts and save the publishing page:

foreach (WebPart oldWP in oldPageWpm.WebParts) {
    // don't move the Title bar, it's already built into the page
    if (oldWP.ToString().Equals("Microsoft.SharePoint.WebPartPages.TitleBarWebPart")) {
        TitleBarWebPart titleBar = (TitleBarWebPart)oldWP;

        // do steal the title bar property data, though
        publishingPage.Title = titleBar.HeaderTitle;
        publishingPage.Description = titleBar.HeaderDescription;
    }

StringBuilder sb = new StringBuilder();
try {
    // export the web part to a stream
    oldWP.ExportMode = WebPartExportMode.All;
    XmlWriter xwriter = XmlTextWriter.Create(sb);
    wppWpm.ExportWebPart(oldWP, xwriter);
    xwriter.Close();

    // import the web part from the stream
    string output = sb.ToString();
    XmlReader xreader = XmlTextReader.Create(new StringReader(output));
    string errorMessage;
    WebPart newWP = publishingWpm.ImportWebPart(xreader, out errorMessage);
    xreader.Close();

    // check for import errors
    if (!string.IsNullOrEmpty(errorMessage)) {
        UpgradeLog(errorMessage, EventLogEntryType.Error);
    }

    // add the web part to the page
    publishingWpm.AddWebPart(newWP, "Header", oldWP.ZoneIndex);
}
catch (Exception ex) {
    Debug.WriteLine(ex.ToString());
}
}
publishingPage.Update();

Joined the Community Kit for SharePoint team

Mon, 25 Feb 2008 14:50:00 GMT

I recently joined the Community Kit for SharePoint team. I'm hoping to enhance the Discussion Board features of SharePoint beyond the very basic forums we get out-of-box.

Check it out: http://codeplex.com/cks

The Planet Star

Sun, 03 Feb 2008 20:41:28 GMT

This is a diversion from the usual tech stuff I blog, but my mother just published her book--a dream she wrote over 20 years ago--through American Book Publishing. This is a long-awaited event in my family, and I really wanted to

The book is titled The Planet Star: Unfolding Prophecy by C.M. Chakrabarti and is a sci-fi, fantasy, adventure...yes, that's right. It's an interesting tale of another world.

For all you avid sci-fi readers, check it out. She's got a author setup at http://www.cmchakrabarti.com which has a forum for asking questions about the book.

Great job, Mom. We're all proud of you!

OpenSearch provider for MOSS search

Wed, 30 Jan 2008 00:13:19 GMT

It's nice to have that handy-dandy search bar in the upper right corner of your Internet Explorer browser, but how do you get that to show up with custom searches for MOSS?

Well, you'll need to build a custom opensearch provider for your MOSS site. For this instance, I will demonstrate a simple provider that you will add to your page layouts to direct searches to your main search.

First, we must make the OpenSearch XML. If you want a quick cheat, you can go here to use the IE search providers add-in. So, you'll need to create a file for each search provider you want to add to your page (i.e. All Sites, People, Intranet, Extranet, etc.).

IntranetSearch.xml

<?xml version="1.0" encoding="UTF-8" ?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1">
   <ShortName>This text appears in the IE dropdown</ShortName>
   <Description>This is the description</Description>
   <InputEncoding>UTF-8</InputEncoding>
   <Url type="text/html"
template="http://search/searchcenter/pages/results.aspx?k={searchTerms}" />
</OpenSearchDescription>

Next, you'll have to add this to a common location that you will reference with the search provider.

  1. Open SharePoint designer.
  2. Create a folder called IESearchProviders (the name is unimportant).
  3. Copy all your OpenSearchProviders in the folder.

Finally, you'll need to go to your page layout. If you're like everyone else who customizes SharePoint, then you have a custom master page as well as custom page layouts. In any page layout (*.aspx) or master page (*.master) add the following link tag to the PlaceHolderAdditionalPageHead content placeholder:

<link title="This appears in IE dropdown as a new search type"
      type="application/opensearchdescription+xml"
      rel="search"
      href="/SearchCenter/IESearchProviders/IntranetSearch.xml"
/>

Another scenario is to build an HttpHandler for the OpenSearch provider. This would allow you to programmatically modify the search results. Maybe you want to put the <link> tag on your master page so it appears on all sites, but you want the user to be able to define a search at the simplest of levels (as low as a document library).

Update:

I seemed to have forgotten to mention how to add a button to the page to provide the user an easier way of knowing that the search provider exists

window.external.AddSearchProvider(http://search/SearchCenter/IESearchProviders/IntranetSearch.xml)