My reading List

There are two good ways you can update the web.config using a feature. The first way that I will write about today is by adding an xml file to the %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\CONFIG folder and use a feature receiver to apply the modifications.

This method will apply web.config modifications to all web applications excluding the central admin web application.

Here is the link to the MSDN article: http://msdn.microsoft.com/en-us/library/ms439965.aspx

image

So the first thing I did in Visual studio is to create a mapped folder to the config folder under the 14 hive. After that I created an xml file in the format webconfig.*.xml (replace * with your own text).

This is the contents of my xml file:

<actions>
  <add path="configuration/appSettings" id="{F890379B-C989-457B-A350-26D4C8909FA9}">
    <add key="MySetting" value="MyValue" />
  </add>
</actions>

 

In the xml file I have added an add action that points to the appSettings in the web.config. The child of that element is the element that I want to add under appSettings.

IMPORTANT!!! Now the one thing the MSDN article does not explain is the role of the id attribute. If you do not include an id attribute with a GUID as a value, the modification will be added multiple times to the web.config.

So you see this can be anything from a safeControl Entry to a Custom sitemap provider.

So the next question to ask is “How do you apply the settings?”. Well the answer is quite easy. First I created a farm scoped feature that contains an event receiver.  This event receiver contains one line of code in the FeatureActivated event.

 public override void FeatureActivated(SPFeatureReceiverProperties properties)
 {
     SPWebService.ContentService.ApplyApplicationContentToLocalServer();
 }

 

At this point you can deploy your solution and make sure your feature is activated. Here is a snippet of my web.config after the feature has been activated.

 

image

 

Advantages:

  • Easy set up.
  • Hardly any code.
  • You do not lose any custom web.config entries when SharePoint is updated.
  • An easy way to deploy custom web.config modifications to all web applications (excluding the central admin web application)

 

Disadvantages

  • All web applications receive the modifications and may not be the best way if you want to limit your modifications to one web application. You should use another method. See Part 2

 

In the next couple of days I will have another post (part 2) about modifying the web.config in SharePoint 2010 by using a feature.

I was trying to modify the navigation in a portal I was developing and for some reason it could not be modified. And like any good developer I checked my logs and I found the following error:

“Unable to retrieve TopNavigationBar SPNavigationNodeCollection from Web at: http://server. The SPNavigation store is likely corrupt.”

image

I found out it was because NavBar element was missing in the onet.xml. Once I put this element in the onet.xml I deleted the site collection and created it again and I was able to edit the top navigation.

image

Every once in awhile I need to check the property bag on a SPWeb object. I have made a quick PowerShell script to view all the properties on the root web. You can check other webs in the site collection by adding the relative Url to the OpenWeb Method.

Here is the 4 lines of code.

Add-PSSnapin "Microsoft.SharePoint.Powershell" -ErrorAction SilentlyContinue
$site = spsite "http://server"
$web = $site.OpenWeb()
$web.AllProperties

I found this really cool tool to create Regular JavaScript from C#. You can find it here Script#.

Other then that there is not much more to say other then trying out this cool tool. It has been mentioned that Microsoft has used this tool to create some of the JavaScript found in SHarePoint2010.

The title says it all folks. Microsoft SQL Server 2008 R2 has now been released to manufacturing. The article says it will be available by download within the next couple of weeks.

However I went to the SQL 2008 R2 home page and clicked the try now button. I’m downloading something. I hope its not the CTP. I guess we will see when its done.

Hers the link the the SQL Server Blog

http://blogs.technet.com/dataplatforminsider/archive/2010/04/21/sql-server-2008-r2-released-to-manufacturing.aspx

As I am normally on my development machine I want to be able to run any PowerShell scripts as I need. By default I cannot do this because the Execution Policy for PowerShell is set to Restricted By Default.

There are 4 policies:

  1. Restricted
  2. AllSigned
  3. RemoteSigned
  4. Unrestricted

To see the current policy of your machine use the following command:
Get-ExecutionPolicy

To set the policy so you can run your all your scripts use the following command.
Set-ExecutionPolicy Unrestricted

By switching to this policy you make your system less secure. Probably not recommended for production machines.

See the Following URL for more information: http://technet.microsoft.com/en-us/library/ee176961.aspx

Today when I was trying to do a FullTextSqlQuery and I got the following error. It was very strange.

“Microsoft.SharePoint.SPException: Your search cannot be completed because this site is not assigned to an indexer. Contact your administrator for more information. at Microsoft.SharePoint.Search.Query.Query.CreateQueryProxy(SPSite site) at Microsoft.SharePoint.Search.Query.Query..ctor(SPSite site)”

After some research I found that I needed to change the reference Microsoft.SharePoint.Search.Query to Microsoft.Office.Server.Search.Query. After I did that the problem was fixed.

Microsoft.SharePoint.Search.Query must be for SharePoint Foundation 2010 and Microsoft.Office.Server.Search.Query for SharePoint Server 2010. So it makes sense.

A while back I created a post about SPMetal.

http://www.spdavid.com/post/2010/02/18/Using-SPMetal-to-gernerate-code-for-a-specific-List.aspx

In this post I will expand a little bit on SPMetal and write about how to use it with Visual Studio 2010 in a way that I have found effective.

Create an empty SharePoint 2010 Solution with VS 2010. (Make sure it is .NET 3.5)

  1. Create a Folder called SPMetal
  2. Add 3 files to the folder and the following contents
    • GenerateSPMetalCode.bat
      "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN\SPMetal" 
      /web:http://SPDavid /namespace:SPDavid.SPMetal /code:SPMetal.cs /language:csharp 
      /parameters:SPMetal.xml 
    • SPMetal.xml

    <?xml version="1.0" encoding="utf-8"?>
    <Web AccessModifier="Internal"
    xmlns="http://schemas.microsoft.com/SharePoint/2009/spmetal">
    <List Name="Documents">
    <ContentType Name="Document" Class="Document" >
    <Column Name="Title" Member="Title" />
    <Column Name="Author" Member="CreatedBy" />
    <Column Name="Created" Member="Created" />
    </ContentType>
    </List>
    <List Name="Announcements">
    <ContentType Name="Announcement" Class="Announcement">
    <Column Name="Body" Member="Body" />
    <Column Name="Title" Member="Title" />
    <Column Name="Author" Member="CreatedBy" />
    <Column Name="Created" Member="Created" />
    </ContentType>
    </List>
    <ExcludeOtherLists></ExcludeOtherLists>
    </Web>

     

    • And an empty SPMetal.cs
  3. It should now look like the following
    image
  4. Make sure the lists exist in the site that you specified in the bat file. 
  5. Open the SPMetal directory in Windows Explorer and run the GenerateSPMetalCode.bat file.
  6. After a successful run open up the SPMetal.cs file and confirm that the code has been generated.
  7. You can now use the generated code with LINQ.

 



To use LINQ on a list in SharePoint 2010 you can generate some code using SPMetal. By default by running SPMetal on a site you will get a code generated file for most of the lists and probably more. Here is a MSDN link for some info on SPMetal.

http://msdn.microsoft.com/en-us/library/ee538255(office.14).aspx

But what if you want only to generate the code for one list. Well it is quite simple once you figure it out. You need to add an xml file to override the default settings of SPMetal and specify it in the /parameters option. I will show you how to do this.

First create a Folder that will contain two files (GenerateSPMetalCode.bat and SPMetal.xml).

Below is the content of the files:

GenerateSPMetalCode.bat

"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN\SPMetal" /web:http://YourServer /code:OutPutFileName.cs /language:csharp /parameters:SPMetal.xml
pause

 

SPMetal.xml

<?xml version="1.0" encoding="utf-8"?>
<Web AccessModifier="Internal" 
     xmlns="http://schemas.microsoft.com/SharePoint/2009/spmetal">
    <List Name="ListName">
      <ContentType Name="ContentTypeName" Class="GeneratedClassName" />
    </List>
  <ExcludeOtherLists></ExcludeOtherLists>
</Web>

 

You will have to change some of the text in the files so that it will be specific to your SharePoint Server Setup. In the bat file you will have to change http://YourServer to the url of the web where your list is. In the SPMetal.xml file you need to change ListName to the name of your list and the ContentTypeName to the name of the content type you want to extract. The GeneratedClassName can be anything but perhaps you should rename it to something more sensible.

So now when you run it the SPMetal command will read the SPMetal.xml list and override its commands. ExcludeOtherLists element makes it so that only the code for the lists you specify will be generated. For some reason I got an error if I had this element above the List element.

You sould now have a code file called OutPutFileName.cs that has been generated. You can now put this in your SharePoint project for use with your LINQ queries against that list.

I will soon write a LINQ example that uses the generated class.

 

UPDATE: Add the /namespace parameter to add a namespace to the generated code.

 

"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN\SPMetal" /web:http://YourServer /namespace:MySPMetalNameSpace /code:OutPutFileName.cs  /language:csharp /parameters:SPMetal.xml

At the top of the v4 masterpage just before the ribbon I found this great Delegate Control called GlobalNavigation.  This control can be used to add content to the top of the page by using a user control.

<sharepoint:delegatecontrol runat="server" controlid="GlobalNavigation" />

If we look at the my profile pages, you can see that it uses this control to add the content on the top of the ribbon menu.

image

 

So if you want to create your own content to add on one of your SharePoint sites You simply have to create a user control and a feature that connects it to the GoblalNavigation Delegate control. You can scope your feature to the farm, web application, site collection or specific site.

1. Create a SharePoint 2010 Project and map a folder to the CONTROLTEMPLATES directory in the 14 hive.

2. Add a new user control to that folder and add your desired content. Below is the HTML markup i added to my user control

<div>
    <h1>
        Hello World
    </h1>
</div>

 

3. Create a feature and a new element.xml. Below is the xml in the element.xml. Inside you see a control element that contains information for SharePoint to implement your control. The Id is the same id as the delegate control. If several controls are targeting the same delegate control the one with the lowest sequence will be used. ControlSrc is the path to your new user control.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <Control Id="GlobalNavigation" 
             Sequence="90" 
             ControlSrc="~/_ControlTemplates/DemoNavigation.ascx" />
</Elements>

4. Deploy your solution to see your changes.

 

image

Here is a screenshot of my solution setup.

 

image