March 2009 - Posts
In Enterprise Search, I often find it useful to create a scope around a specific list template. This gives users added flexibility in searching only specific lists of documents, list items, pages or whatever. I think there are a few ways to do this, but one way I have found to do this is by using the List Template Id. Say you have a simple list template like the following.
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ListTemplate
Name="MyDocumentLibrary"
Type="10003"
BaseType="1"
OnQuickLaunch="TRUE"
SecurityBits="11"
Sequence="110"
DisplayName="My Document Library"
Description="My Custom Document Library"
Image="/_layouts/images/itdl.gif"
DocumentTemplate="101"
DisallowContentTypes="false"
MultipleTypes="true"
VersioningEnabled="true"
FolderCreation="false"
/>
</Elements>
To create a scope to only return items that are in this type of list, we use the contentclass managed property. For built-in list types, you can create a rule in your scope, specifying a property query with a contentclass value of STS_List_Tasks or STS_List_Links for example. This post has a list of the various built-in values you can use for out-of-the-box list template types. Configuring a scope for a custom list template type is also pretty easy assuming you know the syntax. You simply append the type id to STS_ListItem_. For example, in the case of my list template above, my contentclass would be.
STS_ListItem_10003
Just go to your SSP –> Search Administration –> Scopes. Create a new scope and a new rule and then set the Scope Rule Type to Property Query. Pick contentclass from the box and enter a value like the one above. Also be sure and select the Require behavior to require items to have that content class. Here is what it would look like.
EDIT: I need to update the image to show ContentClass instead of Author.
It’s pretty simple. I am not sure how I figured out how to do this, but it does work. It might be buried in the SDK somewhere. I think you could also specify built-in lists using their list template id’s as well.
Follow me on twitter.
This Saturday, I had the opportunity to give my talk on Deploying Code in SharePoint at SharePoint Saturday Tulsa (School of Dev) put together by David Walker. That day a freak snowstorm came through but the event still had quite a few people attend. I had an opportunity to catch SharePoint Cowboy’s talk on Custom Site Definitions as well as Kyle Kelin’s talk on TypeMock.
Unfortunately, the code demo for this talk didn’t work perfectly on me (despite having done it successfully in Kansas City and fine the day before). For some reason, the solution package wasn’t copying out the assembly. I retracted the solution and deployed only to one web application and it worked correctly. I also had a cut and paste issue in my .webpart file. For the record I looked in the logs (12 hive \ logs) folder to troubleshoot my issue. I’ve attached the corrected code and slides to this post.
Here is a brief list of posts that I have written about various topics relating to deployment. Many of which I mentioned in my talk.
DotNetMafia also had our second Beer and Code (SharePint) event. Despite the snow, we still had some people turn out and we had a good time with plenty of food and beverages. Our next event will be during Tech Fest 2009. Thanks again to TekSystems for sponsoring the event.
As Kyle Kelin and I mentioned we are doing another “Beer and Code” meetup after SharePoint Saturday (School of Dev) this Saturday on 3/28. The event will start immediately after prizes (around 6ish) at Dirty’s Tavern located at 325 E 2nd St (2nd and Elgin – Downtown Tulsa). TekSystems has graciously offered to sponsor food and beverages. So come join DotNetMafia for a beer and some pizza to talk about SharePoint, .NET, iPhone Development, the economy, or whatever. It’s sure to be a great time! Also special thanks to Isocentric Networks for hosting this blog for all these years.
This is kind of a strange error that I sometime receive when trying to startup a crawl in Enterprise Search. I have only received it on MOSS servers with the Infrastructure Update applied, but it might occur on other versions as well. The issue is when I try to start a crawl (on a BDC content source for me in this case), I get the following JavaScript alert.
Of course, I know a new query server isn’t currently being added. Sometimes, you can just try the crawl again and it will work. Eventually, I noticed that this only seems to occur when other crawls are running. For example, my main SharePoint sites content source was doing an incremental crawl as shown below.
When that crawl finishes, I can start my crawl without any issues on the other content source. As a workaround, I have also discovered that I can start the crawl by editing the content source and checking the Start full crawl of this content source checkbox. Quite the weird issue. I didn’t see much on Google about it, so I figured I better post something on it.
Don’t forget SharePoint Saturday Tulsa this weekend as well as DotNetMafia’s Beer and Code social afterwards.
Follow me on twitter.
Internet Explorer on Windows Server 2003 and 2008 is configured to run in a more secure manner than on client machines. This is a good practice, but when developing on a virtual machine, this extra layer of security can prove to be quite annoying when working with SharePoint. This is because you will be prompted for credentials every time you hit the site. If you are debugging, you certainly don’t want to have to enter your credentials every time you make a change.
Luckily, this is quite easy to fix. In Internet Explorer, log into your SharePoint site and then go to Tools –> Internet Options –> Security. Most likely the SharePoint site you are dealing with is in the Intranet or Trusted Sites zone. Click on the Custom Level button and then scroll all the way to the bottom of the list. Under User Authentication, Logon change the selection to Automatic logon with current username and password.
Once you have set that, you should no longer be prompted for credentials when visiting your SharePoint site. I probably wouldn’t use this on a production server, but for development, it is definitely the way to go.
I am excited to see that SharePoint Saturday is coming to Tulsa this Saturday 3/28. We look to have a lot of good local speakers plus several from out of town as well. I am giving my talk on deployment that I gave at SharePoint Saturday Kansas City. I recommend this talk for anyone starting out with SharePoint since deployment is one of the most difficult concepts to grasp.
For those of you that were at Tech Fest last year, you might have heard about the epic Beer and Code event brought to you by DotNetMafia. Well the godfather himself has declared that the DotNetMafia is doing it again for SharePoint Saturday. Beer and Code will be at Dirty’s Tavern (just like last time) located at 325 E 2nd St (2nd and Elgin – Downtown Tulsa). There is even a pizza place next door now, so if I can pick up a sponsor by the end of the week, I’ll get us some to bring over to Dirty’s. We’ll see you all there.
I try to stay away from posts like these that don’t stick to how to do something, but I do entitle myself to one or two a year, so here it is. My rant today is about organizations that don’t allow developers to develop using the latest technology. Visual Studio 2008 has been out for well over a year, has had one service pack already and Visual Studio 2010 is well on its way. This means, you could be well on your way to being two versions behind. Telling a developer that they have to develop with Visual Studio 2005 (or older) is like asking him or her to program with one hand tied behind the back. So what do I account for being the most common reasons for not upgrading? I’ve listed the ones I can think of below. Let’s see how we can mitigate some of these issues.
Fear and being uninformed
In my opinion, I would say this is the most common reason. Fear of the unknown.
“If I install Visual Studio 2008, all of my code will break, and I’ll spend days fixing it.”
Possible but not likely. If you were informed about the project, you would know that Visual Studio 2008 supports compiling to multiple frameworks. This means, that your Visual Studio 2005 project can be compiled in Visual Studio 2008 and target .NET Framework 2.0. It does make a slight change to your project and solution file, but that is the only thing that is changed. All of your code will remain untouched. Then when you are feeling adventurous, you can make the move and target .NET Framework 3.5. If it compiled and works as 2.0, I am 99% certain that it will also work against 3.5.
Why am I so certain? Well let’s review the changes to the .NET Framework. The fact that it is called .NET Framework 3.5 is pure marketing fluff. You are still using .NET 2.0, it just has things like WCF, WPF, LINQ, and C# 3.0 added. It essentially lets you call assemblies such as System.Core which contains LINQ and various other things.
“When I upgraded to ASP.NET 2.0, the migration was difficult.”
I agree, sometimes, the migration wasn’t smooth to ASP.NET 2.0. However, ASP.NET 2.0 was a complete overhaul of ASP.NET 1.1. However, Visual Studio 2008, still uses ASP.NET 2.0, so your code is still going to work great. Plus, they added cool things like the LinqDataSource and the ListView control (which is awesome by the way).
Cost
Ok, we are in a recession, I understand that. However, most companies buy Visual Studio in multi-year agreements, which does entitle you to upgrades. Admittedly, I have seen some bigger companies, not buy Microsoft products in volume and buy retail boxes of Visual Studio (which is just throwing money away). I am no expert on licensing, but there is a good chance you may be entitled to the to an upgrade and don’t even know it.
Laziness
Yes, it does take some time to install Visual Studio 2008 and can take even longer to apply Service Pack 1 (which you really want btw). However, how much time are you losing on your project by not upgrading? Have a task where you need to find some values buried in an XML document? In Visual Studio 2005, you muddle with an XPathNavigator and get the task done in 15 to 30 minutes or so assuming you are good with XPath. In Visual Studio 2008, you LINQ to XML to query your XML document and have the values you need in a convenient anonymous type in less than 30 seconds. That is only one example, but the choice seems obvious to me.
IT Administrator or Help Desk won’t allow it
I feel for you if this is the case. It should be the development lead or architect of a project that determines what tools you use, not someone else that doesn’t even use the project. If a manager, director, CIO says which tools you have to develop with, I encourage you to push for change. These people tend to be the most conservative when it comes to change, so they are almost always going to be against it. However, if you can show him or her how upgrading can save the company time and money, they are going to listen.
Client won’t allow it
When this happens, it is usually one of the above reasons. If you are a consulting company or a staff aug, you are there to bring you professional recommendation. If you think a newer version of Visual Studio will save them time, don’t be afraid to recommend it. I even recommend stating which version of the tools you intend to use in the statement of work. It’s been my experience, that when I express to a client how much time can be saved by upgrading, they have been more than ok with it.
Get on the Cutting Edge
I always thing good companies and developers stay on the cutting edge of the Visual Studio release cycles. These people are installing betas of the products, looking to see how new features can make their upcoming projects go faster, and even deploying things on production on betas when the Go Live license hits. Now is that for everyone? Certainly not, there is the right spot on the edge that is appropriate for every company. However, staying on the cutting edge, can make companies look more attractive to clients as well as make developers more attractive to companies. Think about it. Do you want the developer that knows you can use LINQ to SQL (or Entities) to bust out data access code or the developer that is still reading things into a dataset the way you did in .NET 1.0 (not that I am saying ADO.NET is dead by any means)?
So what are some of my favorite features in Visual Studio 2008 (some of these require SP1)?
- LINQ – I find new ways to use it everyday – whether it is querying a list, string[], or whatever.
- LINQ to XML – Anytime I need to read something out of an XML file, this is the way to go. Great for dealing with repeating sections of InfoPath forms too!
- LINQ to SQL – I deal with a lot of projects which don’t need a big elaborate DAL. LINQ to SQL makes this really easy.
- Anonymous Types – Use them with LINQ all of the time. Great way to get typed access to XML documents.
- Automatic Properties – Wasn’t that excited about them at first, but I use them more and more now.
- Property Initializers – Reduces code since you don’t have to create a bunch of constructors to initialize different combinations of properties
- Dynamic Data Web Applications – These seem pretty neat, but I have yet to make full use of one
- Improved WPF Designer
- Better JavaScript debugging
- Silverlight support
The list goes on and on, but you get the point. Of course, this is just my opinion on all of these things, but hopefully, I might have convinced a few of you out there that it is time to upgrade. Some developers may be ok with developing with old tools, but many developers find it particularly frustrating. There is nothing worse than the feeling you get when you find yourself reinventing the wheel by manually coding something that was added to a later version of the tool.
Sometimes, you want to make absolutely sure that someone can’t go in and change your content type via the Windows SharePoint Services user interface. If an administrator were to delete or rename columns in your content type this can cause all sorts of issues as things may or may not be prorogated down to the child types. You might also want to ensure that a content type is only created / modified by using a feature and CAML. To solve this, a content type can be marked as sealed and it can only be marked as sealed through the object model. This prevents any casual changes to the content type via the user interface.
The code to seal a content type is pretty simple. Just get a reference to the particular content type you want to change, set Sealed to true and update the content type. In my example, I am just changing a content type off the root of the site collection called Test Content Type. Here is the code.
14 using (SPSite currentSiteCollection = new SPSite("http://moss-server"))
15 {
16 SPContentType contentType = currentSiteCollection.RootWeb.ContentTypes["Test Content Type"];
17 contentType.Sealed = true;
18 contentType.Update();
19 }
Of course there are some things you should know before sealing a content type. As mentioned before, you will not be able to make any changes in the user interface as you can see below. You also have to be a site collection administrator to seal the content type. This means your code has to be executed by a user with appropriate permissions (a console app works fine). You also need to know that sealed content types are not updated through push-down operations. So if a change is made in a SPWeb’s content type and a list’s content type beneath it is sealed, that child content type won’t be updated. You just have to remove all of your seals first.
That is what your content type will look like once it is sealed. This concept also applies to the SPField object (for Site Columns) as well, the code would be quite similar and also makes use of the Sealed property. You can also seal content types at the list level as well. To unseal your content type, just set the sealed property to false and update it again.
It’s been a while since I have done a how to post, so I thought it was due time. I see request all of the time for people wanting to provide very specific custom advanced search capabilities. The AdvancedSearchWebPart is ugly and bit lacking, but luckily it is quite easy to build your own. For simplicity of today’s example, I built my custom search as a web user control. You can easily host this inside a web part by building your own SmartPart (or by using the one on CodePlex). In my example, I want a search page which lets me do normal keyword searches as well as search by product number and color. I also want to filter by results using specific scopes. This search control will go on a page inside the search center and use the existing results.aspx page to display the results.
However, before we begin, we must review a few concepts. First, to be able to search on a specific field, you must have a managed property mapped to the field. This applies if you are mapping to a site column or if you are mapping to some column in the database exposed via BDC. Secondly, you must take note of how the URL Syntax works for Enterprise Search. The reason for this is that we are simply redirecting the user to the results.aspx page via query string. This gives us custom functionality while keeping the out of the box search results. The URL syntax works similarly to the Keyword Syntax using the ‘k’ query string parameter.
Let’s first review the keyword syntax. For example, I want to search for anything with the word “Shirt” that is colored red in our “Online Products” scope. This is what the keyword syntax looks like.
Shirt Color:”Red” Scope:”Online Products”
This same query would be passed to results.aspx, using the ‘k’ query string parameter as such. You can URL encode it of course if necessary.
results.aspx?k=Shirt Color=”Red” Scope=”Online Products”
Pretty simple, right? So what does the user control look like? In my case, I have managed properties called Color and ProductNumber. Scope already has meaning in keyword syntax so it does not have to be accounted for.
It’s pretty simple, but allows me to use DropDownLists or whatever user control I want to use on each step. The code to generate the URL string is quite simple. You may need to take into account the proper URL to your results.aspx page in your Search Center.
protected void SearchButton_Click(object sender, EventArgs e)
{
Response.Redirect(GetQueryUrlSyntaxString());
}
/// <summary>
/// Returns a string in the url query syntax.
/// </summary>
/// <returns></returns>
private string GetQueryUrlSyntaxString()
{
System.Text.StringBuilder queryString = new System.Text.StringBuilder();
// append the path to results.aspx here
queryString.Append("results.aspx?k=");
// append the generic search term, followed by managed properties
// for example: shirts ProductNumber:"01232"
// for example: coats Color:"Red" Scope:"Retail Products"
if (!string.IsNullOrEmpty(SearchTextBox.Text))
queryString.Append(SearchTextBox.Text);
// write a space followed by the managed property and the value in quotes i.e.: ProductNumber:"01232"
if (!string.IsNullOrEmpty(ProductNumberTextBox.Text))
queryString.AppendFormat(" {0}:\"{1}\"", "ProductNumber", ProductNumberTextBox.Text);
if (!string.IsNullOrEmpty(ColorDropDownList.SelectedValue))
queryString.AppendFormat(" {0}:\"{1}\"", "Color", ColorDropDownList.SelectedValue);
// scope can also be passed on the 's' query string parameter
if (!string.IsNullOrEmpty(ScopeDropDownList.SelectedValue))
queryString.AppendFormat(" {0}:\"{1}\"", "Scope", ScopeDropDownList.SelectedValue);
return queryString.ToString();
}
It simply uses a StringBuilder to assemble a query string as we saw in the above query string syntax. I’ve also attached the code to this post as a starting point for you. Hopefully, you will find it useful. If you are not familiar with how to deploy a user control, use this post.
I have been working on creating a new Windows Server 2008 virtual machine lately, so I decided to grab the latest version of VSeWSS 1.3. I immediately encountered the following error when trying to install.
Please wait while the installer finishes determining your disk space requirements.
The only option is to click the “Return” button and wait. Unfortunately, it never stops. After doing a quick Google search, I came across this post which describes the issue with MSI packages. It wasn’t related to SharePoint but put me in the right direction. This applied to an MSI file though and the VSeWSS download is not an MSI file its an EXE. I figured there was a command line option to extract the MSI and in fact there is.
VSeWSSv13_x86_Feb2009CTP_Build_429.exe /extract <workingfolder>
Just specify a folder you want the extracted file to go into there. Then you can execute the MSI file as such with msiexec and the issue does not occur.
msiexec /i VSeWSS_v13_x86_Build-429.msi
Not sure why I ran into this issue, but in case you do, hopefully this helps.
On a side note, I’m on twitter now.
This is kind of a weird issue and I ran into it the last two times I setup a MOSS virtual machine, so I thought I would take a moment to tell about it today. I am a Windows Server 2008 virtual machine. This server is a DC and also has SQL Server 2008 installed. In my particular case I have the setup files for MOSS extracted onto a folder on my external hard drive so that I can do a slipstream install of SP1 and the Infrastructure Update. To access the files I am using Virtual PC’s Share Folder feature to provide access to the install files inside the virtual machine.
I created a setup account for MOSS to do the install since that seems to be a best practice. This account has administrator privileges. Here is where the issue comes in. When I login with my setup account and try to run setup.exe for MOSS, I get the following error.
Setup.exe. The Parameter is Incorrect.
In attempting to troubleshoot the issue, I noticed that if I ran it with the actual administrator account, everything works fine. However, this is not the account I wanted to install on. No matter what I could do, I could not get setup to run as a shared folder. Instead, what I ended up having to do was map a folder over the network to the host machine and install the files that way. Not sure what would cause this, but I assume it has something to do with Virtual PC. Anyhow, if you run into this issue, it’s easy to work around.