Change AssociatedContentType for a pagelayout

by Håvard Hebnes 18. July 2009 11:37

If you want to change the associated contenttype for a pagelayout, you can do it like this:

// first you need a reference to a PublihingSite or PublishingWeb
var pubSite = new PublishingSite(site); 

// then we need to get all available pagelayouts
var pageLayouts = pubSite.GetPageLayouts(false); 

// try to find the pagelayout you want to update
var pageLayout = GetPageLayout(pageLayouts, "pagelayout.aspx"); 

// if pagelayout exists, update it (here you need to have a ref to the contenttype)
if (pageLayout != null)
    UpdateAssiciationContentType(contentType, pageLayout); 

/// <summary>
/// Helper method to update associated contenttype for a pagelayout
/// </summary>
/// <param name="newsContentType"></param>
/// <param name="pageLayout"></param>
private static void UpdateAssiciationContentType(SPContentType contentType, PageLayout pageLayout)
{
    // Check out the pagelayout
    pageLayout.ListItem.File.CheckOut(); 

    // set AssociatedContentType
    pageLayout.AssociatedContentType = contentType; 

    pageLayout.Update(); 

    // CheckIn, Publish and approve changes
    pageLayout.ListItem.File.CheckIn("Changed associated contenttype");
    pageLayout.ListItem.File.Publish("");
    pageLayout.ListItem.File.Approve("Change approved");
} 

/// <summary>
/// Get pagelayout by name
/// </summary>
/// <param name="pageLayouts"></param>
/// <param name="name"></param>
/// <returns></returns>
private static PageLayout GetPageLayout(IEnumerable<PageLayout> pageLayouts, string name)
{
    var layouts = from PageLayout layout in pageLayouts
                  where layout.Name == name
                  select layout; 

    return layouts.Count() == 1 ? layouts.ElementAt(0) : null;
}

Create ContentType programatically

by Håvard Hebnes 14. July 2009 21:49

Out of the box SharePoint has a few content types that you can use. If you would like to create your own that inherits from one of these you could do it like this:

// first we reference the content type we want to inherit from
SPContentType pageContentType = web.AvailableContentTypes[ContentTypeId.Page];

// create our new content type
var customContentType = new SPContentType(pageContentType, web.ContentTypes, "Name of content type");
newsContentType.Group = "Custom content type group";

// add content type to the site
web.ContentTypes.Add(customContentType);
web.Update();

To add a custom sitecolumn to our new content type:

// first we need to find our site column
SPField siteColumn = web.AvailableFields.GetFieldByInternalName("InternalSiteColumnName");

// Add column to our new content type
customContentType.FieldLinks.Add(new SPFieldLink(siteColumn));

// Update content type
customContentType.Update();

Trouble running stsadm –o migrateuser

by Håvard Hebnes 8. July 2009 10:26

Yesterday I tried to migrate a user from one domain to another domain running:
stsadm -o migrateuser -oldlogin domain1\user -newlogin domain2\user –ignoresidhistory

This resulted in the following error:
The site with the id c725736f-d942-4475-b3c1-bf1f8c8a1339 could not be found.

To find out which sitecollection this id belongs to I ran the following sql query:
SELECT [Id], [SiteId], [FullUrl]
FROM [WSS_Content_DB].[dbo].[Webs] where SiteId = 'c725736f-d942-4475-b3c1-bf1f8c8a1339'

Result:
Id    SiteId    FullUrl
99642E4D-6C53-49D0-996C-7650C494971C    c725736f-d942-4475-b3c1-bf1f8c8a1339    personal/mysiteuser

After this I ran another test which requires that SP2 is installed on your server:
stsadm -o preupgradecheck

The result from this command can be found here:
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\LOGS\PreUpgradeCheck-TIMESTAMP.htm

Look for the following section:
Failed : Orphaned site collections

An orphaned site collection is a site collection exists in the content database, but it is not in the configruation site map. Such site collections is not accessible and will not be upgraded properly.The follow orphaned site collections where found:

  • /personal/mysiteuser(Data Source=sqlserver\instance;Initial Catalog=WSS_Content_DB;Integrated Security=True;Enlist=False;Connect Timeout=15)

I then confirmed that this sitecollection was the same as the one that I had problems with.

Solution
To fix this I deleted the sitecollection with this command (Requires SP2 if you use –force or -siteid):
stsadm -o deletesite -siteid c725736f-d942-4475-b3c1-bf1f8c8a1339 -databaseserver SQLSERVER\instance
-databasename wss_content_db -force

After this I migrated the user successfully.

Links:
Deletesite- Stsadm operation

Workflow Failed On Start

by Håvard Hebnes 26. June 2009 14:48

Recently I tried to create a custom approval workflow using VS2008 with wspbuilder. I successfully deployed the wsp and added the workflow to a custom list, but when I started the workflow I got an error saying: Failed on Start (retrying)

In the SharePoint logfile I found this error:
Engine RunWorkflow: System.Workflow.ComponentModel.Compiler.WorkflowValidationFailedException: The
workflow failed validation. at System.Workflow.Runtime.WorkflowDefinitionDispenser.ValidateDefinition(Activity
root, Boolean isNewType, ITypeProvider typeProvider) at System.Workflow.Runtime.WorkflowDefinitionDispenser.LoadRootActivity(Type workflowType, Boolean createDefinition, Boolean initForRuntime) at System.Workflow.Runtime.WorkflowDefinitionDispenser.GetRootActivity(Type
workflowType, Boolean createNew, Boolean initForRuntime)
at System.Workflow.Runtime.WorkflowRuntime.InitializeExecutor(Guid instanceId,
CreationContext context, WorkflowExecutor executor, WorkflowInstance workflowInstance)

After debugging my workflow I noticed that the error occured in a while loop where I used “Declarative Rule Condition”. The solution for this problem was to edit the Visual Studio project file (using notepad) and add the second line below:

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.5\Workflow.Targets" />

Then I reloaded the project and redeployed the wsp and everything worked :)

Using LINQ with SharePoint

by Håvard Hebnes 20. June 2009 16:46

If you're looking for a specific item in a list, there are many ways you can get it.

You could go through the whole list using a loop (not recommended):

foreach (SPListItem item in list.Items) 
{ 
    if(item.Title == "Title1892") 
        return item; 
}

You could use a SPQuery:

var tmpQuery = new SPQuery 
                   { 
                       Query = 
                           @"<Where> 
                              <Eq> 
                                 <FieldRef Name='Title' /> 
                                 <Value Type='Text'>Title1892</Value> 
                              </Eq> 
                           </Where>" 
                   }; 
list.GetItems(tmpQuery);

or you could use LINQ:

Method 1:

List<SPListItem> q = (from SPListItem item in list.Items 
        orderby item.Title 
            ascending 
        where item.Title == "Title1892" 
        select item).ToList();

Console.WriteLine(q[0].Title);

Method 2:

var query = from SPListItem item in list.Items 
                      orderby item.Title 
                          ascending 
                      where item.Title == "Title1892" 
                      select item;

Console.WriteLine(query.ElementAt(0).Title);

Access is denied crawl SharePoint 2007 webapplications

by Håvard Hebnes 19. June 2009 07:35

If you're using host headers when creating new webapplications in SharePoint, you'll probably get this error when you're trying to run the search crawler:

"Access is denied. Verify that either the Default Content Access Account has access to this repository, or add a crawl rule to crawl this repository. If the repository being crawled is a SharePoint repository, verify that the account you are using has "Full Read" permissions on the SharePoint Web Application being crawled. (The item was deleted because it was either not found or the crawler was denied access to it.)"

To fix this you can create the webapplications without hostheaders or you can try this:
http://support.microsoft.com/kb/896861

I've used the first method:
- run regedit
- goto HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
- add a new Multi-String Value named BackConnectionHostNames and press enter
- edit the new key and type the host headers you would like (seperate by newline)
- exit regedit and restart the IISAdmin service

More details can be found at Tommy Segoros blog.


Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen