in

Dot Net Mafia

Group site for developer blogs dealing with (usually) .NET, SharePoint 2010, and other Microsoft products, as well as some discussion of general programming related concepts.

This Blog

Syndication

Corey Roth - DotNetMafia.com - Tip of the Day

Bringing you the latest time saving tips for SharePoint 2010, MOSS 2007, ASP.NET, LINQ, and Visual Studio 2010
  • It’s easy to configure an External List with Business Connectivity Services (BCS) in SharePoint Foundation 2010

    One of my favorite features in SharePoint 2010 is External Lists.  If you haven’t heard by now, the MOSS 2007 Business Data Catalog (BDC) has become Business Connectivity Services (BCS) in SharePoint 2010.  The ever better part is that it is included in SharePoint Foundation and does not require SharePoint Server.  One new concept that we get from this is the External List.  To the end user, these look like regular lists in SharePoint, however they really are reaching out to external systems such as databases and web services.  Whereas the BDC only “officially” supported read operations, the BCS supports full CRUD operations on your external data source. 

    The title of the article mentions how easy it is to set up.  As you will see shortly, it really is quite easy using SharePoint Designer.  In fact, if you have a database table, you can have it exposed in SharePoint in under 10 minutes.  If you worked with the BDC before, you know that we had to manipulate huge XML files that represented the application definition.  We relied on third party tools to make this easier, but it was never a clean experience until now.  Before we get started with SharePoint Designer though, first make sure that you have the Business Data Connectivity (likely to be renamed) Service Application started.  To verify this go to Central Administration –> Manage Service Applications.

    BCSServiceApplication

    You can tell this is SharePoint Foundation since there are only a few Service Applications (SA).  Ok, admittedly it could be server with very few installed, but you get the point.  If you click the Manage button, you can manage any application definitions you have created already.  Although, we’ll skip this since we’ll be using SharePoint Designer.  If the SA is not started for some reason, go to Central Administration –> Services on Server and click Start next to the appropriate service.  Also remember if you are using Windows Server 2008 R2, you will need to have the WCF hotfix installed before any SA works.

    Now let’s take a look at our table.  In my case I have a table of products with a few columns.  I want to expose this table to SharePoint and make it editable.

    BCSTable

    Now open SharePoint Designer 2010 and connect to your SharePoint site.  My server is called sp2010, so I would click open site and then enter http://sp2010.  SharePoint Designer is redesigned and has a new item on the left-hand tab called External Content Types.  This is where we want to go.  Click the External Content Type button in the New section of the ribbon.

    BCSNewECT

    It will take a minute, but then you will get some details about your new External Content Type.  Here is what mine looks like after I gave it a name of Products.

    BCSECTTab

    We’re then going to click the link Click here to discover external data sources and define operations.  This is where we pick that we want to pull data from my database table.  We can also use this to connect to a web service or talk to a custom .NET object.

    BCSAddDataSource

    I’m just going to go with the defaults on the next screen for my data connection.  I gave it my database name of bcs_test as well as my SQL Server name.  You can also configure out which identity is used here to talk to the database.  Remember that you may need to grant permissions on the SQL Server itself for the appropriate user.  It will then iterate your data source and display it to you.  Pick out the table you want, and then right click on it.  This gives you a list of operations you can add as you can see below.

    BCSDataSourceAddOperations

    As you can see, you can add individual operations such as Read Item, Read List, Create, Update, and Delete.  You can also create an association if you have multiple tables related to each other.  However, I want everything, so I am going to choose Create All Operations.  This starts a wizard.  The most important part for you will be the Parameters configuration.  Here you set what field to show in a picker control as well as what the id is.  Usually, you don’t need to configure much.  Here I am setting that the name field should show up in the picker.

    BCSWizardParametersName

    It automatically detects my primary key and maps it to the identifier for me.

    BCSWizardIdentifier

    You can also specify an Office Property to allow you to map things into existing types such as an Outlook Contact or Task.  This lets you use Office to edit things directly in the BCS.  I won’t cover that today though since that is a little bit more involved.  The next step in the wizard allows you to do some filtering.  In my case, I am skipping it. 

    When that is finished, go back to the main tab for your External Content Type and you should see something like this.  It has the operations you have chosen as well as what fields are in the type.

    BCSTabComplete

    Now, we want to save out External Content Type, by pressing the Save (Disk Icon) in the top left corner.  On to the fun part.  Let’s use SharePoint Designer to create an External List by using the Create Lists & Form button in the ribbon.

    BCSCreateListsFormButton

    Clicking it you will get the following screen asking about your list.  I’m calling my lists Products and I just use default values for the rest.  If you are using server, you can click the Create InfoPath Form checkbox and you will be able to customize the InfoPath form for the list right there.  Since we are using Foundation today, I’ll leave that unchecked.

    BCSExternalList

    You can also create the list directly through SharePoint as well.  Once the list is created, go to your SharePoint site, navigate to the list, and you should see something that looks like this.

    BCSExternalListView

    Comparing it to my table from the SQL Server, you can see that it matches.  You can see that it looks a lot like a regular list in SharePoint.  Now, what if I want to change the price on the Plush Bear?  Not a problem.  Click on the item and select edit, change the value in the form and save it.

    BCSEditItem

    Now what does the data in SQL look like?

    BCSSQLEdit

    It has the new price of course.  You can also add and delete rows and perform bulk operations, but screenshots really don’t do it justice.  It’s this simple to set up, you should go out and try it for yourself.  One reminder, I will give you is that even though this looks like a list, it doesn’t always quite act like a list.  You won’t find it in SPWeb.Lists for example.  There are a also a number of other things that do and don’t work.  Be on the lookout for a follow-up post on what you can and can’t do with an external list.  This is a great new feature in SharePoint 2010 and I hope you will like it as much as I do.

  • Avoid the SPListItem.Properties HashTable

    One thing is a lot of confusing to new SharePoint developers is that there are so many ways to use the API to get to the same data.  When it comes to getting or setting the value of a field on a list item, there is at least 2 ways I can think of immediately (we all know there is more).  One way to do this is use SPListItem.Properties.  This is a Hashtable that allow you to get and set values as you please.  If all of your properties are strings, you are pretty safe to use this, however where you might start running into issues is when you start dealing with other types.  If I remember correctly from an error I received once, when assigning to this, you can only use a string, int32, or DateTime.  The problem is you never know what underlying type is going to be there when you try to assign it. 

    I ran into this problem again recently in an event receiver which was copying data from one list item to another.  The code was for some simple metadata inheritance if you were curious.  We had no issue copying strings.  However, the source item thought property MyField was a string and the destination item thought property MyField was an int32.  Here is what it looked like.

    destionationItem.Properties["MyField"] = sourceItem.Properties["MyField"];

    Now you might be thinking that you can just cast it or that I have some other issue because they should be the same type.  This really wasn’t the case though.  In my case, I had stored a value of 2, but when I retrieved the value I received back “2.0000000000”.  This makes things quite a pain, since int.Parse can not handle that.  All of this was just simply not worth the hassle.

    The one thing you need to remember is that using the indexer on SPListItem is not the same as using SPListeItem.Properties.  To repeat.

    SPListItem[“MyField”] != SpListItem.Properties[“MyField”]

    Both will return a type of object by default, but when you retrieve the value using the indexer you actually get the type of double (in my case above).  Better yet, the type matches on both the source and the destination field.  I then can simplify my code to copy the properties as shown below.

    destinationItem["MyField"] = sourceItem["MyField"];

    Now I am no expert on the SharePoint API by any means.  I’m sure there might be a reason you might prefer using the Hashtable (maybe it performs better), but for now I am going to stay away from it.  At the minimum, I’ll avoid it when I am copying data.

  • Silverlight in SharePoint 2010 (#sp2010)

    One misconception I have heard is that SharePoint 2010 is completely based on Silverlight.  While SharePoint does use Silverlight now in various places, I would say most of it is still based upon regular ASP.NET pages.  I haven’t seen anything that actually requires Silverlight yet, but it does make things prettier when you have it.  This is just a brief overview of some things you might see.  For example, one of my favorite new things is the Create page.  If you don’t have Silverlight installed, you get something that looks like this.

    CreatePage

    As you can see it looks a lot like the traditional Create page in previous versions of SharePoint.  However, one thing you might notice that’s new on this page is the Improve the Creation Experience - Install Microsoft Silverlight link.  It gives you a link to install it and the next time you go to the create page, you get a modal window, that looks like this.

    CreatePageSilverlight1

    As you can see the experience is much nicer.  When you hover over each time, you get an effect and all that pretty stuff.  You have various ways to filter and categorize what you can create as well.  If you are worried about your settings when creating a site, don’t worry they are neatly tucked away under the More Options button.  Here is what that looks like.

    CreatePageSilverlight2

    This is just one place where things have changed.  You are going to find Silverlight in other areas as well of course.  The most notable areas would be the PowerPoint preview in the FAST search results as well as in Office Web Apps.  I’m going to talk about Office Web Apps more soon, but the main thing I will point out is that they do not require Silverlight.  So if you are editing a Word Document directly in the browser, you can do that with just HTML and JavaScript.  Now if you do have Silverlight, you gain some things such as how well the document zooms, but for the most part the experience is largely the same.

    The last thing to mention is that there is a Silverlight web part included now (which I am sure you have already heard about).  This is nice because it makes it easy to include your own Silverlight applications without having to rely on third party web parts or writing your own.

  • SPQuery Error: Microsoft.SharePoint.SPException was unhandled by user code. Cannot complete this action. Please try again.

    When I get an error, I like to blog about it.  Especially when the error gives you no useful information whatsoever.  Now, you can get the above error in a variety of ways, but the one I am going to discuss today is when using SPQuery.  I inherited some code that had some CAML queries in it and I could not figure out what the cause was at first.  When I called SPList.GetItems(SPQuery), I would receive something like the following.

    Microsoft.SharePoint.SPException was unhandled by user code
      Message="Cannot complete this action.\n\nPlease try again."
      Source="Microsoft.SharePoint"
      ErrorCode=-2147467259
      StackTrace:
           at Microsoft.SharePoint.Library.SPRequest.GetListItemDataWithCallback(String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback, ISPDataCallback pSchemaCallback)
           at Microsoft.SharePoint.SPListItemCollection.EnsureListItemsData()
           at Microsoft.SharePoint.SPListItemCollection.get_Count()
           at Samson.P2S.SharePoint.Services.Synchronization.P2S_SynchronizationService.<>c__DisplayClass6.<GetInventoryChecklist>b__4() in C:\Projects\SamsonTFS\P2S\P2S_V0\Samson.P2S.SharePoint.Services.Synchronization\P2S_SynchronizationService.asmx.cs:line 166
           at Microsoft.SharePoint.SPSecurity.CodeToRunElevatedWrapper(Object state)
           at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.<RunWithElevatedPrivileges>b__2()
           at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
      InnerException: System.Runtime.InteropServices.COMException
           Message="Cannot complete this action.\n\nPlease try again."
           Source=""
           ErrorCode=-2147467259
           StackTrace:
                at Microsoft.SharePoint.Library.SPRequestInternalClass.GetListItemDataWithCallback(String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback, ISPDataCallback pSchemaCallback)
                at Microsoft.SharePoint.Library.SPRequest.GetListItemDataWithCallback(String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback, ISPDataCallback pSchemaCallback)
           InnerException:

    The cause is actually simple.  My CAML query was malformed.  Specifically my where clause was not nested properly.  The previous developer put three conditions in an and clause and that simply does not work.  A COM exception though?  Really? Wouldn’t it have just been better if it validated the query first and gave us a nice error message such as the following?

    CAML query is malformed.

    That would be too nice I guess.  Anyhow, if you get this when querying, start looking at that query.  While, I am here, I’ll remind you if you copy the query from CAML Query Builder, to remove the Query element.  If you can’t figure it out and first, go back to the CAML query building tool of your choice and start executing the query there and comparing it to the one you have.  You should be up and running in no time.

  • Introduction to querying lists with REST and ListData.svc in SharePoint 2010

    What I really like about SharePoint 2010 is all of the new ways we can get at list data.  You can always use the Client Object Model, Linq to SharePoint, or the existing object model, but one neat new way to get at list data is with listdata.svc.  ListData.svc provides a way of getting information from a list (or lists using joins) using REST.  What you end up with is a nice RSS feed of list data, that you can consume with whatever client you would like.  You can construct URLs in various manners to get specific records, do joins, or perform simple queries.  I won’t go through everything that you can do with it today, but I’ll point you towards resources to do the more advanced things.

    When you are getting started, the first thing you want to do is check and see if you have ListData.svc up and running.  Like any SharePoint web service, it’s located in the _vti_bin folder of any existing site, so it will work with items relative to that site.  Here is what a typical URL might look like.

    http://<sharepoint-server>/_vti_bin/ListData.svc

    Try hitting that URL on your SharePoint 2010 server and see if it works.  There is a good chance that you will get a 404 error.  This happened to me, so I did some searching and found Rob Garret’s post stating to go out and install ADO.NET Data Services 1.5 CTP 2.  There are a few choices, but I have seen others recommend you go with the runtime only.  I had issues installing the full package.  Once you have it installed, it still didn’t work for me, so I rebooted my server and everything worked fine when it booted back up.  My guess is you probably could just reset IIS though.

    Once you have a working ListData.svc, hitting it you should get results like this. 

    ListDataSvcNoParameters

    You get an XML document of all lists available to be queried.  If you notice the href on each collection it gives you an idea of how you can construct subsequent URLs to get data.  In today’s example, we’re going to work with a simple task list.  We’ll look at the various ways we can get data from this list.

    ListDataSvcTaskList

    To get the data for this list via REST we simply just add the list name to the URL.  In my case the name of the list is called Tasks.  Here is what the URL would look like.

    http://<sharepoint-server>/_vti_bin/ListData.svc/<ListName>

    In my case:

    http://sp2010/_vti_bin/ListData.svc/Tasks

    Here is what the results look like.

    ListDataSvcTasksAll

    As you can see we get an RSS feed and this is how Internet Explorer renders it.  However, if we look at the actual XML of the feed, we’ll find that we get quite a bit of data back about the list.  Here is a snippet of the XML.

    <feed xml:base="http://sp2010/_vti_bin/ListData.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">

      <title type="text">Tasks</title>

      <id>http://sp2010/_vti_bin/ListData.svc/Tasks</id>

      <updated>2010-01-21T19:21:27Z</updated>

      <link rel="self" title="Tasks" href="Tasks" />

      <entry m:etag="W/&quot;1&quot;">

        <id>http://sp2010/_vti_bin/ListData.svc/Tasks(1)</id>

        <title type="text">Test 1</title>

        <updated>2010-01-21T09:26:51-06:00</updated>

        <author>

          <name />

        </author>

        <link rel="edit" title="TasksItem" href="Tasks(1)" />

        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Attachments" type="application/atom+xml;type=feed" title="Attachments" href="Tasks(1)/Attachments" />

        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Predecessors" type="application/atom+xml;type=feed" title="Predecessors" href="Tasks(1)/Predecessors" />

        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Priority" type="application/atom+xml;type=entry" title="Priority" href="Tasks(1)/Priority" />

        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Status" type="application/atom+xml;type=entry" title="Status" href="Tasks(1)/Status" />

        <category term="Microsoft.SharePoint.DataService.TasksItem" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />

        <content type="application/xml">

          <m:properties>

            <d:ID m:type="Edm.Int32">1</d:ID>

            <d:ContentTypeID>0x01080085FF0E1548B7414787A693232497B24E</d:ContentTypeID>

            <d:ContentType>Task</d:ContentType>

            <d:Title>Test 1</d:Title>

            <d:Modified m:type="Edm.DateTime">2010-01-21T09:26:51</d:Modified>

            <d:Created m:type="Edm.DateTime">2010-01-21T09:26:51</d:Created>

            <d:CreatedByID m:type="Edm.Int32">1</d:CreatedByID>

            <d:ModifiedByID m:type="Edm.Int32">1</d:ModifiedByID>

            <d:Owshiddenversion m:type="Edm.Int32">1</d:Owshiddenversion>

            <d:Version>1.0</d:Version>

            <d:Path>/Lists/Tasks</d:Path>

            <d:PriorityValue>(2) Normal</d:PriorityValue>

            <d:StatusValue>In Progress</d:StatusValue>

            <d:Complete m:type="Edm.Double" m:null="true" />

            <d:AssignedToID m:type="Edm.Int32" m:null="true" />

            <d:TaskGroupID m:type="Edm.Int32" m:null="true" />

            <d:Description>&lt;div&gt;Test 1 Task&lt;/div&gt;</d:Description>

            <d:StartDate m:type="Edm.DateTime">2010-01-21T00:00:00</d:StartDate>

            <d:DueDate m:type="Edm.DateTime" m:null="true" />

          </m:properties>

        </content>

      </entry>

    As you can see in the content element, we can see the various site columns on a particular list item.  Of course, there is more we can do with REST than just view everything in a list.  If you want a specific item, you can use parenthesis and specify an indexer.  Note that it is unit-indexed, not zero-indexed.

    http://<sharepoint-server>/_vti_bin/ListData.svc/<ListName>(<Index>)

    In my case:

    http://sp2010/_vti_bin/ListData.svc/Tasks(3)

    However, when you do this, Internet Explorer will give you an error that it cannot display this feed.

    ListDataSvcTaskListIndexerIeError

    Not to worry though, if you view source, you still have a working XML document.  It will pretty much look like the one above minus the initial feed information.  You can take the query above and go one step further.  Say, you just want to know the status for a specific task (note that the site column is actually called StatusValue here), you can simply add it to the URL like this.

    http://<sharepoint-server>/_vti_bin/ListData.svc/<ListName>(<Index>)/(<Field>)

    In my case:

    http://sp2010/_vti_bin/ListData.svc/Tasks(3)/StatusValue

    You’ll get an even simpler XML document that looks like this.  It will create an element named after whichever site column you passed to it.

    <?xml version="1.0" encoding="utf-8" standalone="yes" ?>

    <StatusValue xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">Completed</StatusValue>

    The last thing I will cover is simple queries.  You can do this with $filter.  There are a number of operators you can use here, but the one I will start with today is eq (or equals).  For example, say I want to see all tasks that are completed, I would use a URL like this.  Put any literals inside quotes.

    http://sp2010/_vti_bin/ListData.svc/Tasks?$filter=StatusValue eq 'Completed'

    This returns results that look like this and of course the content element in the XML has the complete data on each list item returned.

    ListDataSvcTaskListQuery

    You can also use various other types of predicates, such as ne, gt, ge, lt, le, and, or, not, etc.  What each one does is probably pretty obvious, but if its not take a look at this MSDN reference for more information on the various filters and parameters you can use.  Skip the code stuff at the begging and scroll down a bit to find the good stuff.  This is a good start to working with REST in SharePoint, but this really is just the tip of it.  What you are learning here isn’t really just specific to SharePoint but it applies to anything you do with ADO.NET Data Services, so it might be useful elsewhere later.

    One thing I will point out is that I was not able to use this with an external list.  I am guessing this is by design (which sucks), but it doesn’t look like it’s going to work.  Of course, my install could just be broken or this could be subject to change.

  • Linking Files in Visual Studio

    I saw this feature in Visual Studio again the other day and honestly I had kind of forgotten about it.  After discussing it with some colleagues, most of them didn’t even know the feature existed.  What I am talking about is the ability to create a link between files in Visual Studio.  What this allows you to do is actually create a link to a file instead of just making a copy.  Now, I don’t want to get into a discussion of why you would never want to do this or how this is not a proper way to implement code reuse.  Keep in mind though that you can use it to link other types of non-code files such as an XML file.  However, for today’s purpose, I’m just going to link a class into another project.  Consider my following example with two class libraries. I want to reuse Class1.cs inside ClassLibrary2.

    FileLinkingSolution

    I have a simple class that looks like this.

    using System;

     

    namespace ClassLibrary1

    {

        public class Class1

        {

            public Class1()

            {

            }

     

            public void DoSomething()

            {

                int x = 5;

            }

        }

    }

    This class clearly has so much valuable code in it that I have to reuse it in ClassLibrary2, but not make a reference to ClassLibrary2.  This is where the Add as Link functionality comes in.  The process is simple, using the Add Existing Item menu on the project’s context menu.  Navigate to the existing item in the other class library and then make note of the arrow next to the Add button, click on it and choose Add as Link instead.

    FileLinkingAddExistingItem

    Once you do that you will have a link to the file in your other class library.  You can open it and edit it as normal from the linked location, but it will actually edit the file link.  You can tell it is linked in Solution Explorer by the icon.

    FileLinkingSolutionLinkIcon

    Notice the link icon on Class1.cs in ClassLibrary2.  If you click on the linked file, you can see the path to the file it has linked in the properties (although its cut off here in my screenshot).

    FileLinkingProperties

    Once you are done here, you can make changes to the file from either class library and the original file gets updated.  Keep in mind though, if you delete the original file, the link will be broken and you will get an error when trying to view any links.  I don’t know how useful this feature will be to all of you, but I think there is a time and place for everything.  I can definitely see this being useful in some cases.  This isn’t a new feature either.  I think its been around since at least Visual Studio 2003, but I could be wrong.

  • Feature Versioning and Upgrades in SharePoint 2010

    One new feature in SharePoint 2010 is the ability to version and upgrade features.  I haven’t seen a lot of people talking about it yet, so I thought I would take a few minutes to talk about it today.  It’s an interesting new feature and I’ll be curious to see how much people use it and when.  The versioning aspect of features is interesting, but specifically what we’ll be talking about today are what kinds of things we can do when we perform a feature upgrade.  Unfortunately, by the time you read all of this, it will probably leave you with more questions than you started with.  You will probably be asking yourself a lot of questions like “well, what happens when I upgrade a feature and it has X in it?”.

    The first thing to know is that SharePoint 2010 makes use of the Version attribute on the Feature element now.  We can then use this version to execute code or do various things in an element manifest.  This is also an easy way to add a new site column to a content type which we’ll talk about in a bit.  It all starts with the UpgradeActions element in your feature.xml.  It takes a ReceiverAssembly and ReceiverClass attribute just like the Feature element takes.  Here is what it would look like.

    <UpgradeActions ReceiverAssembly="MyFeatureReceiver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3e1b35c83d6e53f4"

      ReceiverClass="MyFeatureReceiver.MyFeatureReceiver">

    If you’re not going to be executing custom upgrade action code, you can leave that part out the assembly.  You can then optionally add a VersionRange that takes BeginVersion and EndVersion attributes.  You can specify multiple VersionRange elements to handle upgrades across multiple versions with one file.  You can then specify what you want to occur on the feature upgrade. 

    <VersionRange BeginVersion="1.0.0.0" EndVersion="1.9.9.9">

    One of the most common things you can do is to specify a separate element manifest file which deploys various things to SharePoint when the solution is upgraded.  This file will have the same syntax as any other elements.xml file you have used.  Here is what that would look like.

    <ApplyElementManifests>

      <ElementManifest Location="WebPart1\UpgradeManifest.xml"/>

    </ApplyElementManifests>

    Another thing you can do is rename a file.  So if you deployed a file called default.aspx and now you want to be called default2.aspx, you can have your upgrade make the change.  I have no idea if it would actually update anything that references the file.  I would guess not, but it’s there to try out if you ever need it.

    <MapFile FromPath="OldFilename.aspx" ToPath="NewFilename.aspx" />

    One thing, that is pretty interesting is the ability to add new site columns to an existing content type.  The syntax is pretty similar and it will even push down changes to content types that inherit from it.  Just specify the ContentTypeId, FieldId, and whether or not you want it to PushDown

    <AddContentTypeField ContentTypeId="0x010100F15ADB2FA333AD49848E7E01BC79C9750202"

                         FieldId="{b63c6371-f774-451d-b4fb-5679625fafd5}"

                         PushDown="TRUE" />

    The last thing to mention is that, you can execute custom code when a feature is upgrading.  If you have some complex upgrade logic this is the way to go.  It works by overriding the FeatureUpgrading event handling method.  It passes the UpgradeActionName and an IDictionary of parameters.  I’m not going to go into what the code looks like on a feature upgrade today, but I will cover it in a future post soon.  Here is what a complete UpgradeActions element might look like in your feature.xml.

    <UpgradeActions ReceiverAssembly="MyFeatureReceiver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3e1b35c83d6e53f4"

      ReceiverClass="MyFeatureReceiver.MyFeatureReceiver">

      <VersionRange BeginVersion="1.0.0.0" EndVersion="1.9.9.9">

        <ApplyElementManifests>

          <ElementManifest Location="WebPart1\UpgradeManifest.xml"/>

        </ApplyElementManifests>

        <AddContentTypeField ContentTypeId="0x010100F15ADB2FA333AD49848E7E01BC79C9750202"

                             FieldId="{b63c6371-f774-451d-b4fb-5679625fafd5}"

                             PushDown="TRUE" />

        <CustomUpgradeAction Name="MyCustomUpgradeAction">

          <Parameters>

            <Parameter Name="Parameter1">Some Value</Parameter>

            <Parameter Name="Parameter2">Some Other Value</Parameter>

          </Parameters>

        </CustomUpgradeAction>

        <MapFile FromPath="OldFilename.aspx" ToPath="NewFilename.aspx" />

      </VersionRange>

    </UpgradeActions>

    I’ll be really curious to see how and if people use feature upgrades.  It definitely seems like it can be useful, but I don’t know if I will want to have my feature broken out into a bunch of different manifest files when I start having lots of upgrades.

  • Slides and Code Samples from SharePoint Saturday Kansas City

    I had a great time at SharePoint Saturday Kansas City.  @MossLover and @SharePointKevin as well as many others did a great job organizing this event.  I met a bunch of great new people and I got to see some familiar faces again.  I had the privilege of speaking about Code Access Security again using Visual Studio 2010 and SharePoint 2010.  As promised, I am posting my slides and code samples from the talk.  You can find them at the bottom of this post.

  • Enterprise Search Web Parts are still Sealed! Unseal them! (SP2010)

    I am pretty passionate about Enterprise Search and with MOSS 2007 I saw customers really struggle because wildcard search was not offered out of the box and most of the web parts in Microsoft.Office.Server.Search.WebParts are sealed.  Luckily, the most important one CoreResultsWebPart was in fact not sealed and I was able to hack together a wildcard search solution by inheriting it and using some hacky reflection.  Since SPC09, we’ve been hearing “the search web parts are no longer sealed”, this unfortunately is not true at all.  What they mean to say is that they have added a couple of override to CoreResultsWebPart that allow you to affect the query going in and the results going out.  This is a nice win, but there is still more desired.

    It took me asking a lot of people at SPC09 to finally get a straight answer.  It was in the session, Customizing Search in SharePoint: Building Great Sites with Search, where I asked Harneet Sidhana at the microphone to get the story on why most web parts are still sealed.  The answer? The remaining web parts are currently still sealed by design.  The audience “booed”.  Seriously, they did.  I then asked to have the web parts unsealed and the audience applauded.

    Let’s take a look at the web parts between MOSS 2007 and SP2010 Beta 2 and see what is sealed.

    Web Part

    MOSS 2007

    SP2010 Beta 2
    AdvancedSearchBox Sealed Sealed
    CoreResultsWebPart Unsealed Unsealed
    FederatedResultsWebPart Unsealed Unsealed
    HighConfidenceWebPart Sealed Sealed
    PeopleCoreResultsWebPart Sealed Sealed
    PeopleRefinementWebPart   Unsealed
    QuerySuggestionsWebPart   Unsealed
    RefinementWebPart   Unsealed
    SearchPagingWebPart Sealed Sealed
    SearchStatsWebPart Sealed Sealed
    SearchSummaryWebPart Sealed

    Sealed

    TopFederatedResultsWebPart Unsealed Unsealed

    Looking at this list, I don’t really see anything that has changed from sealed to unsealed. Do you?  I will point out that CoreResultsWebPart has always been unsealed, but this is because PeopleCoreResultsWebPart inherits from it.  Did you notice that anything built since the Infrastructure Update of MOSS 2007 has been unsealed?

    Now I admit, the main reason we wanted to inherit from these controls was to do wildcard search.  The Enterprise Search did a great job with the new keyword query improvements and this will be a non-issue now.  However, can they really say we will never want to extend their web parts?  Are they going to say that they have thought of every possible thing that the web part might possibly do and no one will ever extend it?  As a programmer, I don’t think I would ever have the guts to make a claim like that.  I know these web parts will require customization in the future.  Give us the ability to do it.

    I know you might be thinking, “We just wanted to inherit from these web parts because we wanted wildcard search.  We have that now.”  This is true and I am very thankful.  This eliminates the need a lot, but more than likely we might need to make a change to something else though.  Want to customize people search?  What about best bets or the advanced search box?  Most web parts in SharePoint are unsealed, so why are the search web parts sealed?

    The PeopleCoreResultsWebPart still being sealed is a huge deal.  For one, it doesn’t appear to support the new QueryManager class which means you can’t customize how it does queries or builds the results.  I need to confirm this though.  Take a look at the forums.  They speak for themselves.  Fifty results for the term wildcard in the Search forum.  I am passionate about this topic because I have seen the needs of my customers.  The fact that I might be stuck with another set of sealed web parts for another 3+ years is absolutely scary to me.

    So what can we do?  Please post a reply in the forum or leave a comment on the blog.  We need to let them know our concerns while there is still time to make a change.  Please, unseal the web parts.  This post is cross posted to the SharePoint 2010 forums.

  • Getting by with bare minimum hardware in a SharePoint 2010 development environment (sp2010)

    Let’s face it.  A lot of companies would rather you be unproductive and waste hours a day rather than spend a couple of hundred bucks on some more memory.  I don’t get it, but that’s the world so many of us are forced to live in.  You have to beg and plead, write justification, get approval from a handful of VPs only to get some guy at the help desk to tell you that you don’t need any additional hardware.  If that’s your case, I sympathize with you as I have been there plenty of times.  When people starting seeing the hardware recommendations for SharePoint 2010, many were in shock.  Most people were recommending 4 GB to 8 GB of memory just for the virtual machine itself.  They are significantly higher than what you could get away with in MOSS 2007.  After all with MOSS, I could get by with only 1 GB of memory allocated to a virtual machine.  It wasn’t ideal, but it did work ok.  If I had 2 GB of memory, things usually ran pretty smoothly.  Maybe you will disagree, but that was the case for me at least.  Keep in mind that we’re not talking about production here.  We’re talking about a development virtual machine.

    Today, I will focus primarily on memory since this is where the bottleneck is going to be.  When it comes to developing, I have found that any modern CPU seems to do fine when it comes to performance.  A faster hard disk is always nice, but really, it’s always lack of memory that causes issues.  To date, I have set up three virtual machines on Beta 2: one with SharePoint Foundation, one with SharePoint Server 2010, and one with SharePoint Server 2010 with FAST Search installed.  The memory requirements I have seen on these has varied vastly (as you would expect).  For today’s post, I am considering a complete self-contained SharePoint 2010 environment on a virtual machine that includes Windows Server 2008 R2, Active Directory, and SQL Server 2008.  Let’s start by looking at a summary of my findings.

    Configuration SharePoint Foundation SharePoint Server 2010 SharePoint Server 2010 with FAST
    Bare Minimum 2000 MB 3000 MB 4100 MB*
    Visual Studio Running 2300 MB 3300 MB 4400 MB

    Now, I’ll say these numbers are completely unofficial.  You may have different results.  If you have results you would like to share, please leave a comment.  I quoted numbers for Visual Studio separately because you may not have Visual Studio running or you might be an admin or something.  Obviously, the memory requirements of Visual Studio vary vastly at times depending on what you are doing, but this is just a guideline.  These numbers will also vary depending on what services you have running in SharePoint.  In this case, I have every service I can see to start running.

    As you can see installing FAST adds considerable demand to your memory requirements.  The reason I add the asterisk here is that I think it will probably consume more memory if I make it available.

    So what you can take from this is if you just want a quick development environment and you don’t need the full SharePoint Server, you can use SharePoint Foundation to do some development work with relatively “low” memory requirements.  You can further use even less memory by using an external SQL Server.  On most of my installations, I have found SQL Server using 500 MB – 600 MB of memory.  By moving that off to another server, you can really trim down your memory requirements.  If you don’t need a domain controller on your server, you can shave a bit more off too (but don’t expect to gain a lot here).

    Now, the last thing I will point out is this is what you can get by with.  It’s not necessarily ideal.  You may find that your hard drive is churning a lot as it is probably doing a lot of swapping.  You may find yourself waiting a lot just for the SharePoint site to spin up or to compile and deploy something.  It’s better than nothing though.  Again, these are just some of the numbers I was seeing on my installations.  If you have any numbers you would like to share, please leave a comment.

  • PowerShell basics for SharePoint 2010 (sp2010)

    I’m not expert in PowerShell, but I thought I would share a few basics I picked up at Ignite and various other places along the way when it comes to getting started with PowerShell.  The easiest way to issue SharePoint commands with PowerShell is by running the SharePoint 2010 Management Shell located under Microsoft SharePoint 2010 Products in your Start Menu.  However, it is good to understand what this shortcut actually does.  PowerShell works by using the concepts of snapins.  A snapin is simply a DLL installed with gacutil and installutil that implements a particular interface.  This means you can write your own snapins to do whatever you want.  All of the SharePoint commands are found in Microsoft.SharePoint.PowerShell.dll.  So what this shortcut does, is it runs PowerShell with a script located at the path below.

    C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\CONFIG\POWERSHELL\Registration\\sharepoint.ps1

    This script simply uses the Add-PSSnappin command to load the SharePoint commands.  If you started PowerShell by using some other link, you can also load the SharePoint comamnds by using this command.  Note that the name is always specified without .DLL.

    Add-PSSnapin Microsoft.SharePoint.PowerShell

    Working with PowerShell is in a lot of ways similar to working with a regular command prompt, it is just a lot more powerful.  All of your familiar DOS commands will work because they have been aliased to child items.  For example, Get-ChildItem is how you display the contents of the current folder in PowerShell, but you can also just type in dir to get the same results.

    PowerShellDir

    Knowing the name of the snappin lets us do a few things.  First, we can get a list of all of the commands contained in it by using the Get-Command command with the –PSSnapin parameter.  For example:

    Get-Command –PSSnapin Microosft.SharePoint.PowerShell

    PowerShellGetCommand

    Of course, there are 500+ SharePoint PowerShell commands returned so it makes that list difficult to deal with.  So you can use some old school command prompt tricks to make the list more manageable.  You can issue the command and hit the Pause key (lol).  You can, use the | more technique to view one page at a time.

    Get-Command –PSSnapin Microosft.SharePoint.PowerShell | more

    You can also redirect the output to a text file like this.

    Get-Command –PSSnapin Microosft.SharePoint.PowerShell > commands.txt

    Then you can just open the file in notepad or the editor of your choice.  If you want a more verbose description of how each command is used, you can use the Format-List command and pass it specific property names.  Notice the properties I specified (Name, Definition) I just got from the table above.

    Get-Command –PSSnapin Microosft.SharePoint.PowerShell |  Format-List Name, Definition

    PowerShellGetCommandList

    This is great, but then you might want to know more about the specific syntax of a command.  For this you can use the Get-Help command.  Just execute it followed by the name of the command you want information on.  For example if I want to know about Get-SPWeb, I would issue.

    Get-Help Get-SPWeb

    It would return something that looks like this.

    PowerShellGetHelp

    Once nice thing about PowerShell is that you can use tab to help you complete commands.  For example you can type “Install-SP” and then press tab and it will cycle through the available commands.  What is even better is that you can also use the tab key to add the parameters to the command.  This is useful for when you can’t remember the exact parameter name.

    Another thing I really like about PowerShell is that many times if you leave off a parameter, instead of just giving you an error, it will prompt you for the value.  For example, if I want to create a new site collection, I use the New-SPSite command.  I don’t remember the parameters, but it starts prompting me for things like the URL and owner name.  And of course you can always use Ctrl+C to break out of the command if you change your mind.

    PowerShellPrompt

    There is a ton you can do with PowerShell and I won’t be able to cover it all in this one post.  The power is that it allows you to string together complex commands together to get things done.  If you want to build a script, you simply start by creating a .ps1 file.  You can build this in notepad.  There is also a PowerShell Integrated Scripting Environment (ISE) that will allow you to actually debug your scripts.  One thing to be aware of is that to execute scripts, it requires an execution policy to be set.  Chances are this is already set appropriately, but if its not, your script will not run.  The three possible settings are restricted, unrestricted (prompt to run), and bypass.  I think most people set this to bypass (although I am sure there are security considerations) with the following command.

    Set-ExecutionPolicy bypass

    There is so much to say about PowerShell.  I hope this post serves as a good starting point to start exploring what you can do with it.  I’ll be covering more advanced PowerShell topics in the future.

  • Adding and Deploying Solutions with PowerShell in SharePoint 2010

    Visual Studio 2010 makes it really easy to add and deploy solutions when you are developing, but you may eventually want to deploy those solution packages elsewhere right?  We can still use stsadm, but that is effectively considered deprecated now in favor of PowerShell.  In the past to add a solution, we used an stsadm command like the one below.  In today’s example, we’ll be working with a package called SharePointProject2.wsp on my server named sp2010.

    stsadm –o addsolution –name SharePointProject2.wsp

    To get started with PowerShell, run the SharePoint 2010 Management Console located in your Microsoft SharePoint 2010 Products folder on your start menu.  This automatically loads the Microsoft.SharePoint.PowerShell snappin so that we can execute SharePoint commands.  To install a solution we use the Add-SPSolution command.  If you are using a Sandboxed solution you would use Add-SPUserSolution instead.  It takes just one parameter, –literalpath, which is the path to the solution file.  One thing that is different is that you must specify the full path to the file for some reason.  I haven’t been able to get it to take a path to the solution in the current folder even if I make use of .\ before the filename.  Here is an example.

    Add-SPSolution c:\code\SharePointProject2\bin\debug\SharePointProject2.wsp

    In this case you don’t actually have to type –literalpath before the parameter.  This is what it looks like when executed.  You can see that it displays the id of the solution along with its deployment status.

    PowerShellAddSolution

    Now we need to deploy the solution.  In the past, we used an stsadm command like the following.

    stsadm –o deploysolution –name SharePointProject2.wsp –url http://moss-server –allowCasPolicies –immediate

    We would also follow this up with a call to stsadm with the execadmsvcjobs operation.  To do the same operation in PowerShell, we use the Install-SPSolution command (again use Install-SPUserSolution for Sandboxed solutions).  You can use the Get-Help command (i.e.: Get-Help Install-SPSolution) to get more information on a command but it’s not always obvious what it is expecting as you can see below.  That is why I am writing the post today.

    PowerShellGetHelpInstallSolution

    The first parameter you need is the –Identity parameter.  This is the name of the solution package (i.e.: MySolution.wsp).  Depending on if you are using the GAC or Code Access Security, you will specify either –GACDeployment or –CASPolicies.  You then need to specify a specific web application using the –WebApplication parameter or –AllWebApplications to deploy it to all web applications (assuming the manifest allows it).  If you need to force the deployment, you can still use the –Force command.  Here is what an install command might look like.

    Install-SPSolution –Identity SharePointProject2.wsp –WebApplication http://sp2010 -GACDeployment

    I’ll point out that executing this command actually does do the deployment operation.  You don’t have to fire off something to execute a job later like you did with stsadm.

    You might want to update your solution, so we’ll talk about how to do that as well.  Here is what your stsadm command might have looked like in WSS3.  Which would also be followed up with an execadmsvcjobs operation.

    stsadm –o upgradesolution –name SharePointProject2.wsp –filename SharePointProject2.wsp –immediate –allowCasPolicies

    The upgrade solution syntax is similar to the others.  We just have to specify an identity and a literalpath with the Update-SPSolution command.  The identity is the name of the package on the server to upgrade and the literalpath is the full path to the new solution package on the file system.  Here is what that might look like.

    Update-SPSolution –Identity SharePointProject2.wsp –LiteralPath c:\code\SharePointProject2\bin\debug\SharePointProject2.wspGACDeployment

    We’ve talked about everything else, so we’ll finish it up by talking about retraction and removal.  To retract a solution we use the Uninstall-SPSolution command.  By now you are probably noticing a pattern in the way things are named.  Install –> Deploys, Uninstall –> Retracts.  It also just uses the -Identity parameter and the –WebApplication parameter.  You can also use the –AllWebApplications parameter to retract it from all web applications. Many of these commands may prompt you with an “Are you sure?” type prompt.  You can skip this prompt by adding a –confirm parameter.  Here is what it looks like.

    Uninstall-SPSolution –Identity SharePointProject2.wsp –WebApplication http://sp2010

    Lastly, to remove the package from the solution store, we use the Remove-SPSolution command.  It just takes the name of the package.

    Remove-SPSolution –Identity SharePointProject2.wsp

    I hope this helps.  If you’re like me, it’s one thing to see the docs on something, but I like to see real examples.  There aren’t any examples in the Get-Help command yet.  This should cover all of the common commands that you probably used to used with stsadm in regards to solution deployment.  The nice thing is that you can script these things together very easily and create highly flexible PowerShell scripts.  Expect a few more posts soon on the basics of working with PowerShell and SharePoint 2010.

  • Error: System.IO.FileNotFoundException: The web application at <servername> could not be found (Console Applications with SP2010)

    If you have tried to build a quick console application using Visual Studio 2010 to work with SharePoint 2010, you might find that you run into the following error.

    Unhandled Exception: System.IO.FileNotFoundException: The Web application at http://sp2010 could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application. 

    Consider the following console application.

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using Microsoft.SharePoint;

     

    namespace ConsoleApplication1

    {

        class Program

        {

            static void Main(string[] args)

            {

                using (SPSite siteCollection = new SPSite("http://sp2010"))

                {

                    Console.WriteLine("Site Title: {0}", siteCollection.RootWeb.Title);

                }

     

                Console.ReadLine();

            }

        }

    }

    All this console application does is display the title of the root web of the site collection.  However, when I run it, I get the FileNotFound error. 

    ConsoleApplicationFileNotFoundException

    You first might think to check your path or something like that, but this is actually caused by a completely different issue.  As you know by now, SharePoint 2010 is a 64 bit application.  However, when you create a new Console Application, it does not default to x64, it defaults to x86 as shown below.

    ConsoleApplicationBuild

    View your project properties, go to the Build tab and change the platform target to x64.  Run your console application again and everything should work as expected now.

    ConsoleApplicationWorking

    This doesn’t just apply to Console applications, but could also apply to any other type of external application you might build.  Just make sure it is set to x64.  Technically Any CPU would work as well, but SharePoint only runs on x64 so you might as well just use that.

  • Troubleshooting Sandboxed Solutions in SharePoint 2010

    I have a talk coming up on Code Access Security at SharePoint Saturday Kansas City next month so I have been investigating sandboxed solutions quite a bit.  After all, sandboxed solutions are just another flavor of using CAS with some additional things thrown in.  However, after I got my SharePoint server installed and configured, I found that sandboxed solutions were not working.  When I configured my solution to use the sandbox and tried to deploy it, I got the following error.

    Error occurred in deployment step 'Activate Features': Cannot start service SPUserCodeV4 on computer 'servername'.

    I found that to be odd, so I decided to do some looking around.  I ended up in the Windows Services MMC snapin and found that the service called Windows SharePoint Services UserCode Host v4 was in fact set to disabled.  I changed this to automatic and started the service up.  I tried to deploy again, but unfortunately thing still weren’t working.  Here is the error I got this time.

    Error occurred in deployment step 'Activate Features': This feature cannot be activated at this time. The contents of the feature's solution requires the Solution Sandbox service to be running.

    This one took a little bit more digging, but I ended up going to Central Administration and looking at the Services on Server page.  I thought what I needed would be under Service Applications, but that was not the case.  I took a look at Services on Server and quickly discovered that the Microsoft SharePoint Foundation User Code Service had not been started.  I started the service and then I tried to deploy again and the errors went away and my sandboxed web part worked as expected.  I’m not sure why neither of these started.  It could be because I don’t have enough memory allocated to the virtual machine or maybe it’s always disabled by default.  Anyhow, be sure and check these two things before you try to work in the sandbox.

    UPDATE: @MSwannMSFT confirmed for me that this is by design.  It’s disabled for performance and security since it spins up three new processes.

  • Programmatically Changing the UI Version in SP2010

    In SharePoint 2010, there is the concept of a UI Version and it has a value of 3 or 4.  When you upgrade your existing site, it will leave you at Version 3 which looks just like WSS3.  However, you have the capability to upgrade to the new SharePoint 2010 visualizations which is version 4.  If the administrators have the options enabled, you can change your UI version using the UI itself.  It provides the capability to run on Version 3 but get a preview of 4 and then ultimately they can convert to version 4 completely.  However, you may want to do this programmatically or you may want to revert back to version 3 after you have turned off preview mode.  This quick snippet of code is how you do it. 

    using (SPSite siteCollection = new SPSite("http://sp2010-server"))

    {

        SPWeb site = siteCollection.OpenWeb()

        {

            site.UIVersion = 3;

            site.UIVersionConfigurationEnabled = true;

            site.Update();

        }

    }

    Here, we are using the new UIVersion property and we are reverting back to Version 3.  I’m also enabled the Version Configuration in the User Interface.

More Posts Next page »
2009 dotnetmafia.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems