May 2009 - Posts

I was reading the forums the other day and saw another post in the MOSS Search forum about someone wanting to be able to specify a custom sort order with the CoreResultsWebPart.  WildcardSearchWebPart will allow you to specify a static full text sql query or it builds one of its own.  The problem is, the CoreResultsWebPart that it inherits from has logic in it to go and add an ORDER BY clause based on data modified or relevance.  This causes an issue because if you specify your own order by clause, it causes a syntax error. This post had a rather simple solution to solving the issue.  The answer is to simply add your own ORDER BY clause followed by a -- (SQL comment).  This causes the syntax to be valid and everything works.

After seeing this, I immediately knew I wanted to add this to the WildcardSearchWebPart.  I added a new property called SortOrder which would allow you pass any valid ORDER BY clause.  For example:

  • Title
  • Author DESC
  • ContentSource, Author DESC, Title

You should be able to sort on any manager property that you have returned in the Select Columns XML field.  Give it a try and see how it works.  My next step to research is to see if I can implement this with a keyword query.  Try it out and post any issues you run into on CodePlex.

Wildcard Search Version 1.0 Release 4

Follow me on twitter.

I’ve seen a few people asking about this in the Crawl Logs and thought I would take a few minutes to address it.  First and foremost this is a warning and not an error message.  Sometimes when you receive this message, it is the crawler behaving normally.  Other times it is because of an issue.  I’ll first talk about when it is a normal behavior.  When an item is deleted, it is perfectly normal to see this in your logs the next time a crawl occurs.  This is simply indicating that SharePoint is removing the record from the search index.  If you see an occasional one of these, then you can assure your administrator that things are probably fine.

Other times it can indicate another issue.  In the situation where you already have your index built and your crawl log is filled with nothing but this warning, that is usually indicative of a problem (not to mention your index is empty).  Before you do anything, the first thing I always recommend is just try crawling again.  It might just fix it.  If it doesn’t then more than likely you have a permissions problem.  If you are dealing with a SharePoint content source, verify that the crawl account can still access SharePoint, the password hasn’t expired, it isn’t locked out, etc.  Get the credentials for your crawl account and actually make sure you can log into a SharePoint site.  While I am here, I’ll remind you again to never give this account administrator level privileges as it causes your search index to have deleted an unapproved files in it.  After you make any necessary changes, try to crawl again (twice if necessary) and see if that resolves your issue. 

If you are crawling a Business Data Catalog content source, make sure that the content access account has access to the BDC itself first by going to the Business Data Catalog permissions page on your SSP.  Then also verify that the content access account also has permissions to the BDC application itself as well as its child entities.  If you make any changes, be sure and crawl again.

If none of this has helped, my recommendation of course it to go to the 12 hive’s LOGS folder.  You will need to sift through this file and see if you can find anything potentially permissions related with Search.  Don’t follow any advice to reset your index unless absolutely necessary.  More than likely your index is already effectively reset and doing this probably won’t get you any where.  There are some other causes of this in your logs I am sure, but hopefully this will give you a good start in resolving this issue (if there is one to begin with).

The other day I saw that @mrackley was looking for a way to deploy a .UDCX file to a data connection library.  Having CAML still fresh in my mind from the talk Kyle Kelin and I did on Monday, I decided to see if I could get the job done using the Module and File elements.  Sure enough, I found a simple way to deploy the .UDCX file.  Here is what it looks like.  For the purpose of my example, I am going to deploy a file test.udcx to a data connect library at the /Data Connections path in my current site.  Adjust your paths accordingly.  I have a simple Feature.xml.

<Feature

    xmlns="http://schemas.microsoft.com/sharepoint/"

    Id="{CE871E99-B9E8-4b3e-AF2B-D715C8AD08F0}"

    Scope="Web"

    Hidden="False"

    Title="UDCX Deployment"

    Description="This feature deploys a UDCX file to a data connection library."

    >

  <ElementManifests>

    <ElementManifest Location="elements.xml" />

  </ElementManifests>

</Feature>

I then have an elements.xml file like the one below.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Module Name="DataConnections" Url="Data Connections" Path="">

    <File Url="test.udcx" Type="GhostableInLibrary" IgnoreIfAlreadyExists="FALSE">

      <Property Name="Title" Value="test.udcx"></Property>

    </File>

  </Module>

</Elements>

The Name attribute of the Module element really doesn’t matter, but the Url does.  Set this to the relative path of your data connection library.  I then use a File element and set the Url attribute to the name of my file.  Here you will notice I tried to set a property on the file and although it was not successful in setting the Title property of the form, simply having it there allowed the data connection library to properly read the file as a universal data connection file instead of an Office data connection file.

This is what my data connection file looks like.  It’s a simple file that controls where the submit action goes to.

<?xml version="1.0" encoding="UTF-8"?>

<?MicrosoftWindowsSharePointServices ContentTypeID="0x010100B4CBD48E029A4ad8B62CB0E41868F2B0"?>

<udc:DataSource MajorVersion="2" MinorVersion="0" xmlns:udc="http://schemas.microsoft.com/office/infopath/2006/udc">

  <udc:Name>SharePoint Library Submit</udc:Name>

  <udc:Description>Format: UDC V2; Connection Type: SharePointLibrary; Purpose: WriteOnly; Generated by Microsoft Office InfoPath 2007 on 2009-05-14 at 9:29:23 by MOSS-SERVER\croth.</udc:Description>

  <udc:Type MajorVersion="2" MinorVersion="0" Type="SharePointLibrary">

    <udc:SubType MajorVersion="0" MinorVersion="0" Type=""/>

  </udc:Type>

  <udc:ConnectionInfo Purpose="WriteOnly" AltDataSource="">

    <udc:WsdlUrl/>

    <udc:SelectCommand>

      <udc:ListId/>

      <udc:WebUrl/>

      <udc:ConnectionString/>

      <udc:ServiceUrl UseFormsServiceProxy="false"/>

      <udc:SoapAction/>

      <udc:Query/>

    </udc:SelectCommand>

    <udc:UpdateCommand>

      <udc:ServiceUrl UseFormsServiceProxy="false"/>

      <udc:SoapAction/>

      <udc:Submit/>

      <udc:FileName>Specify a filename or formula</udc:FileName>

      <udc:FolderName AllowOverwrite="1">http://moss-server/MyFormLibrary</udc:FolderName>

    </udc:UpdateCommand>

    <!--udc:Authentication><udc:SSO AppId='' CredentialType='' /></udc:Authentication-->

  </udc:ConnectionInfo>

</udc:DataSource>

Here is what it looks like once the feature was activated.

UDCX

As you can see the title field is blank but other than that it seems to work fine.  I’ll also point out that the file is automatically set to Approved status when uploaded this way.  Here are the properties.  You can see that it correctly picked up that it was a WriteOnly connection for a SharePointLibrary.

UDCX2

Kyle and I debated in our talk if CAML or the API was better for provisioning sites and what not on Monday night.  I certainly think this solution is a lot better than writing code.  It’s simple and very quick to implement.  The Module and File elements are very powerful and you can use them to deploy just about any kind of file.  I’d like to figure out how to get the Title field set properly, but it’s not a deal breaker for me right now.

Follow me on twitter.

with 10 comment(s)
Filed under: , ,

Last night, Kyle Kelin and I had the opportunity to debate SharePoint provisioning methodologies at the Tulsa SharePoint Interest Group.  We each had to deploy a custom site with site columns, a content type, a list, and pages.  Kyle chose the API approach and I went with the CAML approach.  We ended up having a good interactive discussion with the group on the pros and cons of going with either approach.  I also took a minute to show how @jthake’s SPSource can generate CAML for you and the response was great.  As promised here is the code samples from the demo last night.  Thanks for coming.

Follow Kyle and I on twitter.

Kyle Kelin and I are doing our first joint talk together at the Tulsa SharePoint Interest Group this Monday, May 11th.  We’re going to be talking about Site Provisioning and let the audience decide what they like better: CAML or the API.  I also plan on demonstrating the use of the SPSource tool recently release on CodePlex by @jthake.  We start at 6pm at TCC Northeast (3727 N. Apache).  We hope to see you there.

Kyle Kelin on twitter.

Corey Roth on twitter.

As I have mention in the past LINQ to XML is a great way to manipulate the XML data out of an InfoPath form.  I thought I would show how you can also use the same technique to work with the data of a form saved to a form library which launches a workflow (although you could apply this technique to the association or task forms as well).  The first thing we need to do is get the XML of the InfoPath initiation form, before we can work with it.

For the purpose of my example, my OnWorkflowActivated activity writes to a public SPWorkflowActivationProperties property called workflowProperties.  In my Invoked event handling method of my OnWorkflowActivated activity, we use the Item object on my workflowProperties to open the file and get the XML.  You can then use the File object along with OpenBinary() to get the raw bytes of the XML.

byte[] xmlBytes = workflowProperties.Item.File.OpenBinary();

You can then takes those bytes and read them into a regular string.

string xmlString = System.Text.Encoding.UTF8.GetString(xmlBytes);

if (xmlString[0] == (char)0xfeff)

    xmlString = xmlString.Substring(1);

If you are curious about the 0xfeff business that is used to deal with the byte-order mark character in Unicode.  I picked up this trick from another post somewhere, but I can’t remember where currently. 

Now we need to get the XML string into an XDocument class so that we can query it and manipulate it.  Since we have a string, we will need to create a StringReader to read it.

XDocument documentsXml = XDocument.Load(new System.IO.StringReader(xmlString));

If you wanted to work with the Association form instead of the form that started the workflow, you would use a line like the following.  The InitiationData property of the SPWorkflowActivationProperties object provides XML that can be loaded into the XDocument class.

XDocument documentsXml = XDocument.Load(workflowProperties.InitiationData);

InfoPath documents always have a namespace defined for my so we need to use the XNamespace object for any future references inside the InfoPath form.

XNamespace documentNamespace = "http://schemas.microsoft.com/office/infopath/2003/myXSD/2098-05-03T16:48:38";

At this point you can start using LINQ to XML to get the data you need out of the InfoPath form.  For example, if I had a field called my:FirstName at the root of the document.  I could use something like the following to get the value.

string firstName = documentsXml.Root.Element(documentNamespace + "FirstName").Value;

If you are working with other data types, you can always cast it like this.

int customerId = int.Parse(documentsXml.Root.Element(documentNamespace + "CustomerId").Value);

In my example from last week, you saw how you could use LINQ to XML to iterate through a repeating table.  As another example to iterate through a repeating table called Items with an element of Item, you could do something like the following:

var items = from item in documentsXml.Root.Element("Items").Elements("Item")

            select item;

 

foreach (var item in items)

{

    Console.WriteLine(item.Element("Field1").Value);

    Console.WriteLine(item.Element("Field2").Value);

}

In this case, I use LINQ to return an IEnumberable<XElement> representing each repeating item.  I can then use this in a foreach loop to print out the results.  Yes I know you wouldn’t use Console.Writeline in a workflow, but you get the point here.  LINQ to XML really offers a lot of flexibility to manipulate the XML data inside a form.  Hopefully, it will make your experience with InfoPath and workflow a better one.

I am kind of getting into the iPhone development thing so I joined the developer program a while back.  I ran Beta 3 for a while and I am not running Beta 4 on my iPhone.  I found Beta 3 to be quite stable, but Beta 4 I have had more issues with.  Before starting out with Beta 4, you will need to download iTunes 8.2 Pre-Release.  The install didn’t go as smooth as Beta 3 did and I seemed to have a minor issue restoring my phone but everything appears to be working ok.  As with the other Betas, the phone is noticeably faster in places.  However, about once a week, I will find that my phone is off.  After attempting to turn it back on, it will give me the Connect to iTunes screen.  This can be a big pain.  Connecting it to iTunes will make it magically start working again.  However, it happened to me today at work and iTunes was not an option.  I tried multiple times shutting it off and turning it back on again and eventually it started working again.  Other issues to note is that sometimes it doesn’t seem to pull down mail even though its scheduled to push on some and retrieve others every 30 minutes.  It doesn’t do this always, but it definitely does happen from time to time.  All in all, Beta 4 is usable (much better than 1 or 2), but it is not perfect.  My recommendation is to stay on Beta 3 if you want a beta and wait and see what we get with Beta 5 (which I am sure will be pretty soon).

with no comments
Filed under:

If you pay attention to twitter at all, today you might have heard about a new tool on CodePlex called SPSource.  SPSource is a tool that reverse engineers existing Content Types, Site Columns, Lists and more on an existing SharePoint site.  This isn’t just a re-tweet style post that tells you its out there.  I actually took a few minutes today to try it out and so far I am very impressed.  Kyle Kelin and I have often talked about the need for a better tool that worked better than VSeWSS Solution Generator.  Already, I think this tool is it.  Finally you can design a content type in the UI and be able to extract it easily as a feature.

Downloading the tool from CodePlex, gives you an installer for the SPSource executable.  The tool is a command line app designed to be executed in a batch file.  To get started with the tool, you need to create a local 12 hive folder.  You can do this inside Visual Studio manually or with a tool like wspbuilder.  For my test purposes, I just created a 12 hive folder in a temp directory and started working.  Before you begin, you will need to create a folder to hold your feature as well as a simple feature.xml file.  The contents of the file don’t need to contain much, just some XML for deploying a simple feature.  The next thing you need to do is identify what you want to extract from your SharePoint.  In my case I wanted to extract some content types and a list template.  You then create a special XML file with the .spsource extension.  This uses the same syntax as any elements.xml file, but it is used to specify which items to extract from SharePoint.  The only thing you need to specify is an element such as ContentType or ListTemplate and the name.  It then uses this name to look up the resource in SharePoint and extract it.  Here is an example of what it looks like.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <ContentType Name="My Test Content Type" />

  <ListTemplate Name="My Custom List" />

</Elements>

SPSource will take this information and generate the XML files I need to deploy these items elsewhere.  You run SPSource with the following syntax.

spsource.exe –designsite http://my-moss-server/site

When the tool is executed, it will iterate through any subfolders looking for .spsource files.  When it finds them, it will create XML files representing the type of items you request (in my case a ContentType and a ListTemplate).  It will also update the Feature.xml file in that folder to point to any new .XML files it creates.  So far I have found the XML it generates to be very usable and way more accurate than what SPSolGen gives you. 

This tool is really nice.  I would like to see some more documentation for it, but I am sure that will come as the tool is developed more.  When you first install it, all you are given is a link to the CodePlex site in your start menu, so you are left a little bit wondering what to do next.  I would love to see more command line options such as just passing it a URL and it extracts the list template.  One thing I noticed is that it didn’t extract the ItemEventReceivers definition I had on my content type.  I am not complaining though since this tool already has the power to save me a ton of time in the future.

Great work @jthake and everyone else that worked on it.  Microsoft should have provided a better tool to do this years ago.  I am glad you all stepped up to fill in the gap.

Follow me on twitter.

with no comments