SharePoint 2010 Help doesn’t work after migration

I had to migrate a MOSS 2007 farm to SharePoint 2010. – After migration the SharePoint Help did not work. (It’s the button upper right on a SharePoint site.)

A popup window appeared and I got an empty site with the message “Help not available” (or something like that: It was a german site so the error message was german…)

I tried a new created web application with a Team Site collection. There the help does work as expected.

Then I had a look into the Windows Event Log. There I found a related error. The web application pool account of my migrated web application did not has access to the Admin Content database. But the application pool account of the new created web application was enabled to access this database. – After adding the application pool account of my migrated web application as “db_owner” the help was shown as expected.

(I have no screenshots of that. Sorry. But I think, that can be reproduced easily by removing the application pool account from the Admin Content database.)

Missing “View in Browser” and “Edit in Browser” in the context menu of Excel files in a SharePoint 2010 document library…

You have installed the Office Web Apps on your SharePoint 2010 server. Now you are missing the menu entries “View in Browser” and “Edit in Browser”.

You create a new Excel file in Excel 2007 or 2010, upload it and… there are the menu entries… maybe…

This was the situation of my customer yesterday. He tried to open documents in the Office Web Apps after migration from MOSS to SharePoint 2010. Everything seems to work: Word Web App, PowerPoint Web App, OneNote Web App…

I created a new site collection and uploaded a Excel file (XLSX). – The menu entries appeared.

Then I uploaded a document I’ve downloaded before from the migrated site collection. The menu entries were gone… – THEN I REALIZED: To new document was in OpenXML format (Excel 2007, Excel 2010), the migrated documents in native Excel format of Excel 97…2003. Thats the problem: Only OpenXML Excel files can be viewed an edited in the browser!!! – Thats diffrent from Word Web App and PowerPoint Web App.

I’m looking around on the Microsoft web site, but till now I’ve not found an official comment on that. But this seems to be “behavior by design”… Don’t waste as much time as I’ve wasted with that!

Error while connecting to a SharePoint 2010 web site in SharePoint Designer 2010

 

Today I got this error:

SPDError-3

(“The server could not complete your request. For more specific information, click the Details button.”)

I clicked the “Details” button as commanded.

SPDError-4

(“Below is the message that the server returned. For more information, contact your Internet service provider or web server administrator.”)

I asked myself (because I’m the web server administrator in this case) – I had no answer for me.

I clicked: “OK” and “OK” and got:

 SPDError-5

(‘An error occurred while trying to fetch data from your SharePoint site. Unexpected response from the server. The content type type of the response is “” This status code is “OK”.’)

“OK”??????????? Okay…

I read the event viewer log:

SPDError-1

WebHost failed to process a request.
 Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/64923656
 Exception: System.ServiceModel.ServiceActivationException: The service '/_vti_bin/client.svc' cannot be activated due to an exception during compilation.  The exception message is: Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service.. ---> System.NotSupportedException: Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service.
   at System.ServiceModel.Channels.HttpChannelListener.ApplyHostedContext(VirtualPathExtension virtualPathExtension, Boolean isMetadataListener)
   at System.ServiceModel.Channels.HttpTransportBindingElement.BuildChannelListener[TChannel](BindingContext context)
   at System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener[TChannel]()
   at System.ServiceModel.Channels.MessageEncodingBindingElement.InternalBuildChannelListener[TChannel](BindingContext context)
   at System.ServiceModel.Channels.WebMessageEncodingBindingElement.BuildChannelListener[TChannel](BindingContext context)
   at System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener[TChannel]()
   at System.ServiceModel.Channels.Binding.BuildChannelListener[TChannel](Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters)
   at System.ServiceModel.Description.DispatcherBuilder.MaybeCreateListener(Boolean actuallyCreate, Type[] supportedChannels, Binding binding, BindingParameterCollection parameters, Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, ServiceThrottle throttle, IChannelListener& result, Boolean supportContextSession)
   at System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff, ServiceHostBase serviceHost, Uri listenUri, ListenUriMode listenUriMode, Boolean supportContextSession, IChannelListener& result)
   at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost)
   at System.ServiceModel.ServiceHostBase.InitializeRuntime()
   at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(String normalizedVirtualPath)
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)
   --- End of inner exception stack trace ---
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)
   at System.ServiceModel.ServiceHostingEnvironment.EnsureServiceAvailableFast(String relativeVirtualPath)
 Process Name: w3wp
 Process ID: 7248

…………….. It was my mistake. ………………………….

An hour before I configured my SharePoint Site to use KERBEROS. – In the IIS I configured the Web application “Authentication” settings: I choose the provider “Negotiate” but I also removed “NTLM”. This was my fault.

This is the correct setting:

SPDError-6

The definitive guide of How to configure the SharePoint 2010 User Profile Service Application

I took me hours and hours to get to User Profile Service Application working.

These are the steps I’ve done in some scenarios.

Especial to migrate an SharePoint 2007 profile database to SharePoint 2010.

0. The databases for the User Profile Service Application must run on the standard instance of SQL Server. NEVER use a named instance. – Always use SQL Aliases instead!!!

1. (Skip this next step if you don’t need to migrate.) Backup the Shared Service Provider Database of your MOSS farm.

2. Restore the farm to your destination SQL Server instance and with the destination database name, e.g. “SP_SvcApp_UserProfile_Profiles”.

(In the MOSS farm the database was named “MOSS_SSP_Config” !!! –> It’s the configuration database of the Shared Service Provider.)

3. Create the User Profile Service Application with this PowerShell script:

#region Check x64 host
if( [System.IntPtr]::Size -ne 8) {
  Write-Error "Please use a x64 PowerShell host!"
  return
}
#endregion

#region Load SharePoint SnapIn and DLL
  Remove-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
  Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

  [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")  | out-null    

  #Check available SharePoint Cmdlets
  if( (Get-Command -Noun SPWeb*) -eq $null ) {
    Write-Error "SharePoint SnapIn not loaded. SharePoint cmdlets missing!"
    return
  }
#endregion

cls

######################################################################################################

# Profile database in my MOSS farm : MOSS_SSP_CONFIG 

#---------------------------------------------------------------------------
# Settings

$farmname = "SP"

$spfarmuser='DOMAINsp_farm'
$spfarmpwd='passwort1#'
$mysiteHostLocation = "http://mysite.sharepoint.local"
$mysiteManagedPath = "/personal"

#---------------------------------------------------------------------------

$spfarmcredentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $spfarmuser, (ConvertTo-SecureString $spfarmpwd -AsPlainText -force)
$userprofileAppProfileDBName =("{0}_SvcApp_UserProfile_Profiles" -f $farmname)
$userprofileAppProfileSyncDBName =("{0}_SvcApp_UserProfile_Sync" -f $farmname)
$userprofileAppProfileSocialDBName =("{0}_SvcApp_UserProfile_Social" -f $farmname)
$svcAppPool=("{0}_AppPool_UserProfile" -f $farmname)

# Create application pool
$appPool = (Get-SPServiceApplicationPool -Identity $svcAppPool -ErrorAction SilentlyContinue)
if( $appPool -eq $null ) {
  $appPool = (New-SPServiceApplicationPool -Account $spfarmuser -Name $svcAppPool)
}

$userProfileSvcApp = (Get-SPServiceApplication  | ? { $_.TypeName -eq "User Profile Service Application" })

# Create service application
if( $userProfileSvcApp -eq $null ) {
  $userProfileSvcApp = (New-SPProfileServiceApplication -ApplicationPool $appPool -MySiteHostLocation  $mysiteHostLocation `
                          -MySiteManagedPath $mysiteManagedPath -ProfileDBName $userprofileAppProfileDBName `
                          -ProfileSyncDBName $userprofileAppProfileSyncDBName -SocialDBName $userprofileAppProfileSocialDBName `
                          -Name "User Profile Service Application" -SiteNamingConflictResolution "None" -Verbose)
}

# Create application proxy
$proxy = (Get-SPServiceApplicationProxy | ? { $_.Name -like "User Profile Service Application Proxy" } )
if( $proxy -eq $null ) {
  $proxy = (New-SPProfileServiceApplicationProxy -DefaultProxyGroup -Name "User Profile Service Application Proxy" -ServiceApplication $userProfileSvcApp)
}

 

During the creation of the User PRofile Service Application the MOSS database will be migrated!!

If you did no restore previously the profile database will be created in this step.

4. The farm account must be local admin on the farm server.

5. Go into the SQL Server Management Studio.

6. Set the farm account – in my example “sp_farm” – as SYSADMIN in your SQL Server instance.

7. Edit the User Logins for the (migrated) profile database.

The farm account should exist as login. – If not: add the account as “db_owner”.

Important: Set the schema for the farm account to “dbo”!

8. In the Windows Services Manager (Server Manager): restart a services that has the farm account as identity. OR restart the server!

9. Now: Log on locally with the farm account!! – Yes: logon with the farm account!

10. As farm account: go into the Central Administration –> Manage Services on Server –> Start the User Profile Synchronization service!

11. WAIT!

12. Press F5 on the “Managa Services on Server” page. Maybe wait some more Smile. Have a look into the the SharePoint log. You should find lots of message. Search for “ILM” (using ULSViewer of course).

13. Sometimes – if you are a lucky person – the “User Profile Synchronization” service is startet. – Maybe not. In this case: Start over! – Last time it took me three times to get it working!

14. At the end: remove the farm account from the SYSADMIN group!

[Update / 01/26/2011]

15. Don’t forget to reset the Security Settings (“Administrators”) for the User Profile Service Application after you recreated them. – Go into the Central Administration -> Manage Service Applications -> select your User Profile Service Application -> click “Administrators” in the Ribbon. – You may find this empty!!! This is not correct. Insert here at least the farm account with “Full Control” permissions. And don’t forget to insert the search crawl account with “Retrieve People Data for Search Crawlers” permissions. Otherwise your People Search will not work!

Please give me feedback on this! – The configuration of the User Profile Services Application is a incredible mess.

(Another) error opening a document in a Office Web App of SharePoint 2010: “PowerPoint Web App encountered an error. Please try again.”

… on the SharePoint 2010 with german system language of my customer the message text was “Fehler bei PowerPoint Web App. Wiederholen Sie den Vorgang.”

PowerPointWebAppError-1

In the SharePoint log I found this lines:

PowerPointWebAppError-2

First: “Could not find default ServiceProxy or it does not implement IWacServiceApplicationProxy”

Second: “Unhandled exception caught when executing web method handler: System.NullReferenceException”

The Solution:

There was a missing setting for the Service Application Default Proxy Group

Go to: Central Administration –> Application Management –> Configure service application association  ==> click the link (e.g. “default”) in column “Application Proxy Group” of your web application.

You should see something like that:

PowerPointWebAppError-3

Check the missing proxy. Click OK. That’s it…

Failed to open a document with a Office Web App in SharePoint 2010

Today I got this error while opening a Word document stored in a SharePoint library. This document should be opened in the Word Web App. – IT WAS A DOCUMENT IN A MIGRATED CONTENT DATABASE…

WordWebApp-Error-01

(“Word Web App cannot open this document for viewing because of an unexpected error. To view this document, open it in Microsoft Word.”)

I looked into SharePoint log and found this error message:

WordWebApp-Error-02

(“Requesting item that was not generated”)

Then I looked into Windows Event Viewer and found this critical error event:

(“SQL Database ‘…’ on SQL Server instance ‘…’ not found. Aditional error information from SQL Server is included below.” … Followed by some messages in german (because the SQL Servers language is german)… “Fehler bei der Anmeldung” which means: “Access Denied”

WordWebApp-Error-03

Solution:

The Service Account of the SharePoint Web Services System needs “db_owner” rights on the migrated content databases!!! (You see this account in the event log message!!!)

Sample Visual Studio 2010 project for creating a custom SharePoint 2010 Ribbon tab on runtime (!)

The related articles on my blog are:


I wanted to create a sample project to show you who you can create a custom SharePoint 2010 Ribbon tab at runtime! – Especially: How to active the custom ribbon tab on “page loaded” (no need to click it!) So this article is an addition to my explanations in my previous article “How To Activate SharePoint Ribbon Tab by JavaScript Code”.

You can download the project from Codeplex:

http://spcustomribbondemo.codeplex.com

You are invited to download / update / improve the project! – I’d like to insert more samples in the project about how to deploy Ribbon customizations. In the sample I created a ribbon in a custom list view web page. (You’ll see in the code).

To use the project you need a SharePoint web application named “http://sharepoint.local” and a site collection named “ribbon”.

Deploy the project.

Open the SharePoint site and it’s list in your browser.

image

You’ll see:

image

This tab is actived automatically on page load!!!

The source code of my project is inspired by some blog post of this people:

These are the steps of development I’ve done:

1. Create an empty SharePoint 2010 project in Visual Studio 2010

2. Create an “List Definition” project item.

3. Add a “Application Page” project item.

4. Move the new application page to the “List Definition” project item.

5. Change the base class to “WebPartPage”

6. Modify the “Page” tag of the aspx page: replace “DynamicalMasterPageFile” with “MasterPageFile”

7. Replace the content of the aspx file with this code:

 

1: <asp:Content  ContentPlaceHolderID="PlaceHolderAdditionalPageHead"  runat="server"> 

2: </asp:Content> 

3:

4: <asp:Content  ContentPlaceHolderID="PlaceHolderMain"  runat="server"> 

5:     <WebPartPages:WebPartZone  runat="server"  FrameType="None"  ID="Main2"  Title="loc:Main"> 

6:         <ZoneTemplate> 

7:         </ZoneTemplate> 

8:     </WebPartPages:WebPartZone> 

9: </asp:Content> 

10: <asp:Content  ContentPlaceHolderID="PlaceHolderPageTitle"  runat="server"> 

11: </asp:Content> 

12: <asp:Content  ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea"  runat="server"> 

13: </asp:Content>

14:

8. Insert the following code into the CS file of the ASPX file. This code will create the custom Ribbon tab. (The Ribbon tab XML definition code could be created dynamically!!!)

 

1: using  System;

2: using  System.Security.Permissions;

3: using  Microsoft.SharePoint.Security;

4: using  Microsoft.SharePoint.WebPartPages;

5: using  Microsoft.SharePoint;

6: using  Microsoft.SharePoint.WebControls;

7: using  System.Web.UI.WebControls.WebParts;

8: using  System.Diagnostics;

9: using  System.Xml;

10: using  System.Collections.Generic;

11: using  System.Reflection;

12: using  System.Text;

13:

14: namespace  ik.SharePoint2010.SPCustomTabRibbonDemo.Layouts.SPCustomTabRibbonDemo

15: {

16:     public  partial  class  AllItems  : WebPartPage 

17:     {

18:         protected  void  Page_Load(object  sender, EventArgs  e)

19:         {

20:         }

21:

22:         private  string  tab = @" 

23:           <Tab Id=""ik.SharePoint2010.Ribbon.CustomTab"" Title=""ik-ribbon"" Description=""Ingo's Command Group"" Sequence=""501""> 

24:             <Scaling Id=""ik.SharePoint2010.Ribbon.CustomTab.Scaling""> 

25:               <MaxSize Id=""ik.SharePoint2010.Ribbon.CustomTab.Group1.MaxSize"" 

26:                        GroupId=""ik.SharePoint2010.Ribbon.CustomTab.Group1"" 

27:                        Size=""OneLarge""/> 

28:               <Scale Id=""ik.SharePoint2010.Ribbon.CustomTab.Group1.Scaling.CustomTabScaling"" 

29:                      GroupId=""ik.SharePoint2010.Ribbon.CustomTab.Group1"" 

30:                      Size=""OneLarge""/> 

31:               <MaxSize Id=""ik.SharePoint2010.Ribbon.CustomTab.Group2.MaxSize"" 

32:                        GroupId=""ik.SharePoint2010.Ribbon.CustomTab.Group2"" 

33:                        Size=""OneLarge""/> 

34:               <Scale Id=""ik.SharePoint2010.Ribbon.CustomTab.Group2.Scaling.CustomTabScaling"" 

35:                      GroupId=""ik.SharePoint2010.Ribbon.CustomTab.Group2"" 

36:                      Size=""OneLarge""/> 

37:               <MaxSize Id=""ik.SharePoint2010.Ribbon.CustomTab.Group3.MaxSize"" 

38:                        GroupId=""ik.SharePoint2010.Ribbon.CustomTab.Group3"" 

39:                        Size=""OneLarge""/> 

40:               <Scale Id=""ik.SharePoint2010.Ribbon.CustomTab.Group3.Scaling.CustomTabScaling"" 

41:                      GroupId=""ik.SharePoint2010.Ribbon.CustomTab.Group3"" 

42:                      Size=""OneLarge""/> 

43:             </Scaling> 

44:             <Groups Id=""ik.SharePoint2010.Ribbon.CustomTab.Groups""> 

45:               <Group Id=""ik.SharePoint2010.Ribbon.CustomTab.Group1"" 

46:                      Description=""Ingo's Custom Ribbon Demo 1"" 

47:                      Title=""Ingo's Custom Ribbon Demo 1"" 

48:                      Sequence=""10"" 

49:                      Template=""ik.SharePoint2010.Ribbon.Templates.OneLarge""> 

50:                 <Controls Id=""ik.SharePoint2010.Ribbon.CustomTab.Group1.Controls""> 

51:                   <Button Id=""ik.SharePoint2010.Ribbon.CustomTab.Group1.Button1"" 

52:                           Command=""ik.SharePoint2010.Command.Button1"" 

53:                           Description=""Do something"" 

54:                           Sequence=""10"" 

55:                           LabelText=""Do something"" 

56:                           Image16by16=""/_layouts/images/DOC16.GIF"" 

57:                           Image32by32=""/_layouts/images/DOC32.GIF"" 

58:                           TemplateAlias=""cust1""/> 

59:                 </Controls> 

60:               </Group> 

61:               <Group Id=""ik.SharePoint2010.Ribbon.CustomTab.Group3"" 

62:                      Description=""Ingo's Custom Ribbon Demo 3"" 

63:                      Title=""Ingo's Custom Ribbon Demo 3"" 

64:                      Sequence=""30"" 

65:                      Template=""ik.SharePoint2010.Ribbon.Templates.OneLarge""> 

66:                 <Controls Id=""ik.SharePoint2010.Ribbon.CustomTab.Group3.Controls""> 

67:                   <Button Id=""ik.SharePoint2010.Ribbon.CustomTab.Group3.Button3"" 

68:                           Command=""ik.SharePoint2010.Command.Button3"" 

69:                           Description=""Do more"" 

70:                           Sequence=""10"" 

71:                           LabelText=""Do more"" 

72:                           Image32by32=""/_layouts/images/PPEOPLE.GIF"" 

73:                           TemplateAlias=""cust1""/> 

74:                 </Controls> 

75:               </Group> 

76:               <Group Id=""ik.SharePoint2010.Ribbon.CustomTab.Group2"" 

77:                      Description=""Ingo's Custom Ribbon Demo 2"" 

78:                      Title=""Ingo's Custom Ribbon Demo 2"" 

79:                      Sequence=""20"" 

80:                      Template=""ik.SharePoint2010.Ribbon.Templates.OneLarge""> 

81:                 <Controls Id=""ik.SharePoint2010.Ribbon.CustomTab.Group2.Controls""> 

82:                   <Button Id=""ik.SharePoint2010.Ribbon.CustomTab.Group2.Button2"" 

83:                           Command=""ik.SharePoint2010.Command.Button2"" 

84:                           Description=""Do nothing"" 

85:                           Sequence=""10"" 

86:                           LabelText=""Do nothing"" 

87:                           Image32by32=""/_layouts/images/PPEOPLE.GIF"" 

88:                           TemplateAlias=""cust1""/> 

89:                 </Controls> 

90:               </Group> 

91:             </Groups> 

92:           </Tab> 

93:

94: " ;

95:         private  string  tabTempl = @" 

96:           <GroupTemplate Id=""ik.SharePoint2010.Ribbon.Templates.OneLarge""> 

97:             <Layout Title=""OneLarge"" LayoutTitle=""OneLarge""> 

98:               <Section Alignment=""Top"" Type=""OneRow""> 

99:                 <Row> 

100:                   <ControlRef DisplayMode=""Large"" TemplateAlias=""cust1"" /> 

101:                 </Row> 

102:               </Section> 

103:             </Layout> 

104:           </GroupTemplate> 

105: " ;

106:

107:         protected  override  void  OnPreRender(EventArgs  e)

108:         {

109:             //Debugger.Break(); 

110:             SPRibbon  r = Microsoft.SharePoint.WebControls.SPRibbon .GetCurrent(this .Page);

111:             XmlDocument  rx = new  XmlDocument ();

112:             rx.LoadXml(tab);

113:             r.RegisterDataExtension(rx.FirstChild, "Ribbon.Tabs._children" );

114:             rx.LoadXml(tabTempl);

115:             r.RegisterDataExtension(rx.FirstChild, "Ribbon.Templates._children" );

116:

117:             List <IRibbonCommand > commands = new  List <IRibbonCommand >();

118:             commands.Add(new  SPRibbonCommand ("ik.SharePoint2010.Command.Button1" , "ikSharePoint2010CommandButton1Action()" , "true" ));

119:             commands.Add(new  SPRibbonCommand ("ik.SharePoint2010.Command.Button2" , "ikSharePoint2010CommandButton2Action()" , "ikSharePoint2010CommandButton2Enable()" ));

120:             commands.Add(new  SPRibbonCommand ("ik.SharePoint2010.Command.Button3" , "ikSharePoint2010CommandButton3Action()" , "ikSharePoint2010CommandButton3Enable()" ));

121:

122:             SPRibbonScriptManager  rsm = new  SPRibbonScriptManager ();

123:

124:             ScriptLink .RegisterScriptAfterUI(this .Page, "SP.Runtime.js" , false , true );

125:             ScriptLink .RegisterScriptAfterUI(this .Page, "SP.js" , false , true );

126:             ScriptLink .RegisterScriptAfterUI(this .Page, "CUI.js" , false , true );

127:             ScriptLink .RegisterScriptAfterUI(this .Page, "SP.Ribbon.js" , false , true );

128:             ScriptLink .RegisterScriptAfterUI(this .Page, "ik.SharePoint2010.SPCustomTabRibbonDemo/ikactions.js" , false , true );

129:             ScriptLink .RegisterScriptAfterUI(this .Page, "ik.SharePoint2010.SPCustomTabRibbonDemo/ikribbon.UI.js" , false , true );

130:

131:             rsm.RegisterGetCommandsFunction(this .Page, "getGlobalCommands" , commands);

132:             rsm.RegisterCommandEnabledFunction(this .Page, "commandEnabled" , commands);

133:             rsm.RegisterHandleCommandFunction(this .Page, "handleCommand" , commands);

134:

135:             string  script = @" 

136:                 <script language=""javascript"" defer=""true""> 

137:                 //<![CDATA[ 

138:                    function ikribbonInit1() {  

139:                      ikribbonInit(); 

140:                    } 

141:                    ExecuteOrDelayUntilScriptLoaded(ikribbonInit1,'); 

142:                 //]]> 

143:                 </script>" ;

144:             ClientScript.RegisterClientScriptBlock(this .GetType(), "InitPageComponent" , script);

145:

146:             r.MakeTabAvailable("ik.SharePoint2010.Ribbon.CustomTab" );

147:             r.SetInitialTabId("ik.SharePoint2010.Ribbon.CustomTab" , "" );

148:             base .OnPreRender(e);

149:         }

150:

151:         protected  override  void  OnInitComplete(EventArgs  e)

152:         {

153:             base .OnInitComplete(e);

154:         }

155:     }

156: }

157:

158:

9. You need two JavaScript files in the project’s sub folder in the SharePoint’s hive folder “Layouts”.

This file contains code for the Ribbon:

 

1: function  ULS_SP() {

2:     if  (ULS_SP.caller) {

3:         ULS_SP.caller.ULSTeamName = "Windows SharePoint Services 4" ;

4:         ULS_SP.caller.ULSFileName = "ikribbon.UI.js" ;

5:     }

6: }

7:

8: Type.registerNamespace(< span> );

9:

10: //  Page Component 

11: ikribbon.UI.PageComponent = function  () {

12:     ULS_SP();

13:     ikribbon.UI.PageComponent.initializeBase(this );

14: }

15: ikribbon.UI.PageComponent.initialize = function  () {

16:     ULS_SP();

17:     ExecuteOrDelayUntilScriptLoaded(Function.createDelegate(null , ikribbon.UI.PageComponent.initializePageComponent), < span> );

18: }

19: ikribbon.UI.PageComponent.initializePageComponent = function  () {

20:     ULS_SP();

21:     var  ribbonPageManager = SP.Ribbon.PageManager.get_instance();

22:     if  (null  !== ribbonPageManager) {

23:         ribbonPageManager.addPageComponent(ikribbon.UI.PageComponent.instance);

24:         ribbonPageManager.get_focusManager().requestFocusForComponent(ikribbon.UI.PageComponent.instance);

25:     }

26: }

27: ikribbon.UI.PageComponent.refreshRibbonStatus = function  () {

28:     SP.Ribbon.PageManager.get_instance().get_commandDispatcher().executeCommand(Commands.CommandIds.ApplicationStateChanged, null );

29: }

30: ikribbon.UI.PageComponent.prototype = {

31:     getFocusedCommands: function  () {

32:         ULS_SP();

33:         return  [];

34:     },

35:     getGlobalCommands: function  () {

36:         ULS_SP();

37:         return  getGlobalCommands();

38:     },

39:     isFocusable: function  () {

40:         ULS_SP();

41:         return  true ;

42:     },

43:     receiveFocus: function  () {

44:         ULS_SP();

45:         return  true ;

46:     },

47:     yieldFocus: function  () {

48:         ULS_SP();

49:         return  true ;

50:     },

51:     canHandleCommand: function  (commandId) {

52:         ULS_SP();

53:         return  commandEnabled(commandId);

54:     },

55:     handleCommand: function  (commandId, properties, sequence) {

56:         ULS_SP();

57:         return  handleCommand(commandId, properties, sequence);

58:     }

59: }

60:

61: var  ikribbonActiveInterval = null ;

62:

63: function  ikribbonActiveRibbonTab() {

64:     try  {

65:         window.clearInterval(ikribbonActiveInterval);

66:

67:         if  (typeof  (_ribbonStartInit) == "function" ) {

68:             _ribbonStartInit(< span> , false , null );

69:         }

70:

71:         if  (true  && typeof  (_ribbonReadyForInit) == < span>  && !_ribbonReadyForInit()) {

72:             ikribbonActiveInterval = window.setInterval("ikribbonActiveRibbonTab()" , 100);

73:         }

74:     } catch  (e2) {

75:     };

76: };

77:

78: function  ikribbonInit() {

79:     alert(< span> );

80:     ikribbon.UI.PageComponent.registerClass(< span> , CUI.Page.PageComponent);

81:     ikribbon.UI.PageComponent.instance = new  ikribbon.UI.PageComponent();

82:     ikribbon.UI.PageComponent.initialize();

83:

84:     ExecuteOrDelayUntilScriptLoaded(ikribbonActiveRibbonTab, < span> );

85: }

86:

87: NotifyScriptLoadedAndExecuteWaitingJobs("ikribbon.UI.js" );

88:

89:

90:

91:

This file contains code for the actions executed on clicking the custom Ribbon buttons:

 

1: function  ikSharePoint2010CommandButton1Action() {

2:     alert("Button 1 pressed" );

3: }

4:

5: function  ikSharePoint2010CommandButton1Enable() {

6:     return  true ;

7: }

8:

9: function  ikSharePoint2010CommandButton2Action() {

10:     alert("Button 2 pressed" );

11: }

12:

13: function  ikSharePoint2010CommandButton2Enable() {

14:     return  true ;

15: }

16:

17: function  ikSharePoint2010CommandButton3Action() {

18:     alert("Button 3 pressed" );

19: }

20:

21: function  ikSharePoint2010CommandButton3Enable() {

22:     return  true ;

23: }

24:

25:

10. Modify the list definitions “schema.xml” file: Edit the following line:

<View BaseViewID=”1″ Type=”HTML” WebPartZoneID=”Main2″ DisplayName=”$Resources:core,objectiv_schema_mwsidcamlidC24;”

DefaultView=”TRUE” MobileView=”TRUE” MobileDefaultView=”TRUE” ImageUrl=”/_layouts/images/generic.png” Url=”AllItems.aspx”>

Remove the SetupPath attribute!

11. Set the view pages “DeploymentType” property to “NoDeployment”:

image

12. That’s all Hot smile

How to upload user profile pictures in SharePoint 2010 using PowerShell

I’ve created a script for uploading user pictures to the SharePoint 2010 User Profile system.

For me it worked very well. But: Use it at your own risk!

Here is the script:

#written by ingo karstein
#region Check x64 host
    if( [System.IntPtr]::Size -ne 8) {
      Write-Error "Please use a x64 PowerShell host!"
      return
    }
#endregion

#region Load SharePoint SnapIn and DLL
  Remove-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
  Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

  [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")  | out-null
  Add-Type -AssemblyName System.DirectoryServices
  Add-Type -AssemblyName System.DirectoryServices.AccountManagement 

  #Check available SharePoint Cmdlets
  if( (Get-Command -Noun SPWeb*) -eq $null ) {
    Write-Error "SharePoint SnapIn not loaded. SharePoint cmdlets missing!"
    return
  }
#endregion

cls

#region Config Section
    $dom = "sharepoint.local"
    $dom2 = "dc=sharepoint, dc=local"
    $ad = @("ou=Users,dc=sharepoint,dc=local",
            "ou=Users2,dc=sharepoint,dc=local")
    $ldapFilter = "(&(objectcategory=user))"
    $testuser = $null
    #for testing purpose uncomment the following line and add the sAMAccountName of the test user
    #$testuser="ikarstein"

    #the web application url of the profile system
    $personalSiteHost="http://sharepoint.farm/mysitehost"
    #the intranet/homepage web application url
    $intranetSiteHost="http://sharepoint.farm"

    #the path to the user profile pictures. the files must be named like the sAMAccountName and with extension .jpg
    #  example: ikarstein.jpg
    $imagePath="\servershareuser_pictures"
#endregion

$ErrorActionPreference = "Stop"

#This function reads name of the folder where the pictures will be stored
function GetProfilePicturesFolderName {
  try {
    $a = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Portal")
    $name = $a.GetName()
    $assemblyRef = new-object System.Reflection.AssemblyName
    $assemblyRef.Name = "Microsoft.Office.Server.intl"
    $assemblyRef.Version = $name.Version
    $assemblyRef.SetPublicKey($name.GetPublicKey())
    $assemblyRef.CultureInfo = [System.Globalization.CultureInfo]::InvariantCulture
    $assembly = [System.Reflection.Assembly]::Load($assemblyRef)
    $s_rmLocStrings = new-object System.Resources.ResourceManager ("Microsoft.Office.Server.Strings", $assembly)
    $s_rmLocStrings.GetString("UserProfile_UploadPicture_FolderName")
  } catch {
    $null
  }
}

#This function reads name of the SharePoint list where the pictures will be stored
function GetProfilePicturesListName {
  try {
    $a = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Portal")
    $name = $a.GetName()
    $assemblyRef = new-object System.Reflection.AssemblyName
    $assemblyRef.Name = "Microsoft.Office.Server.intl"
    $assemblyRef.Version = $name.Version
    $assemblyRef.SetPublicKey($name.GetPublicKey())
    $assemblyRef.CultureInfo = [System.Globalization.CultureInfo]::InvariantCulture
    $assembly = [System.Reflection.Assembly]::Load($assemblyRef)
    $s_rmLocStrings = new-object System.Resources.ResourceManager ("Microsoft.Office.Server.Strings", $assembly)
    $s_rmLocStrings.GetString("MyPage_MyLists_ProfilePicture_Text")
  } catch {
    $null
  }
}

#This function returns the object for the profile picture list
function GetProfilePicturesList {
  try {
    $profilePicturesListName = GetProfilePicturesListName
    $profileWeb.Lists | ? { $_.get_BaseTemplate() -eq 0x6d -and $_.get_Title() -ieq $profilePicturesListName }
  } catch {
    $null
  }
}

#This function removes special characters from the file name  
function ConvertToLegalFileName($inputName, $replacementChar) {
    $l = $inputName.Length;
    $builder = New-Object System.Text.StringBuilder($inputName)
    for ($i = 0; $i -lt $l; $i++) {
        if ([Microsoft.SharePoint.Utilities.SPUrlUtility]::IsLegalCharInUrl($inputName[$i]) -ne $true)
        {
            $builder.set_chars($i, $replacementChar)
        }
    }
    return $builder.ToString()
}

#This function returns the sub folder for pictures in the picture list
function GetSubfolderForPictures {
  $folderName = GetProfilePicturesFolderName
  try {
      $subfolder = $profilePicturesList.get_RootFolder().Get_SubFolders().get_Item($folderName)
      if( $subfolder -eq $null ) {
        $subfolder = $profilePicturesList.get_RootFolder()
      }
  } catch {
    try {
        $subfolder = $profilePicturesList.get_RootFolder().get_SubFolders().Add($folderName)
    } catch {
        $subfolder = $null
    }
  }
  return $subfolder
}

#this function returns *multiple* objects:
# 1. the MethodInfo object for "CreateThumbnail"
# 2. the size of the large thumbnal picture
# 3. the size of the medium thumbnail picture
# 4. the size of the small thumbnail picture
function InitializeUserProfilePhotosType {
    $a = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles")
    $userPofilePhotosType = $a.GetType("Microsoft.Office.Server.UserProfiles.UserProfilePhotos")

    #outputs:
    $userPofilePhotosType.GetMethod("CreateThumbnail", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Static -bor  [System.Reflection.BindingFlags]::NonPublic))
    $userPofilePhotosType.InvokeMember("LargeThumbnailSize", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Public -bor [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::GetProperty  ), $null, $null, @() )
    $userPofilePhotosType.InvokeMember("MediumThumbnailSize", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Public -bor [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::GetProperty  ), $null, $null, @() )
    $userPofilePhotosType.InvokeMember("SmallThumbnailSize", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Public -bor [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::GetProperty  ), $null, $null, @() )
}

#this function returns a MethodInfo object for "EnsureTrailingSlash" method
function InitializePersonalSpaceGlobalType {
    $a = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles")
    $personalSpaceGlobalType = $a.GetType("Microsoft.Office.Server.WebControls.UserProfileHelper.PersonalSpaceGlobal")

    #outputs:
    $personalSpaceGlobalType.GetMethod("EnsureTrailingSlash", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Static -bor  [System.Reflection.BindingFlags]::NonPublic))
}

#thid function returns a MethodInfo object for "GetSmallThumbnailUrl" method
function InitializeUserProfileGlobalType {
    $a = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles")
    $userProfileGlobalType = $a.GetType("Microsoft.Office.Server.UserProfiles.UserProfileGlobal")

    #outputs:
    $userProfileGlobalType.GetMethod("GetSmallThumbnailUrl", [System.Reflection.BindingFlags]([System.Reflection.BindingFlags]::Static -bor  [System.Reflection.BindingFlags]::NonPublic))
}

#this function creates an absolute url for the given relative url
function MakeFullUrl {
  param($url)
  return "$($temp)$($Url)"
}

#this function reads the users from the Active Directory
function GetUsers {
    $ctype = [System.DirectoryServices.AccountManagement.ContextType]::Domain
    $context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $dom, $dom2

    $l = @()

    $ad | % { $domain = [ADSI]("LDAP://"+$_)
              $filter = $ldapFilter
              $ds = new-object System.DirectoryServices.DirectorySearcher($domain,$filter)
              $users = $ds.Findall()
              $users | % { $l = $l + $_ }
        }

    $identityParam = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName

    $m = @()

    if( $testuser -ne $null ) {
      Write-Host "Test mode!" -ForegroundColor Red
    }

    $l | % {
      $san = $_.properties["samaccountname"]
      if( $testuser -eq $null -or $testuser -ieq $san) {
        $m = $m + $san[0]
      }
    }

    #output:
    $m
}

$profileSite = (Get-SPSite $personalSiteHost)
$profileWeb = $profileSite.RootWeb

$site=(Get-SPSite $intranetSiteHost)
$sc = [Microsoft.Office.Server.ServerContext]::GetContext($site)

$upm = New-Object "Microsoft.Office.Server.UserProfiles.UserProfileManager" -ArgumentList ($sc)
$mysiteHostUrl = $upm.MySiteHostUrl

$ensureTrailingSlashMethod = (InitializePersonalSpaceGlobalType)
$mysiteHostUrl = $ensureTrailingSlashMethod.Invoke($null, @(, $mysiteHostUrl))

$createThumbnailMethod, $largeThumbnailSize, $mediumThumbnailSize, $smallThumbnailSize = (InitializeUserProfilePhotosType)
$getSmallThumbnailUrlMethod = (InitializeUserProfileGlobalType)

$profilePicturesList = GetProfilePicturesList
$profilePicturesFolder = GetSubfolderForPictures

$users=(GetUsers)

$users | % {
  $currentUser = $_
  Write-Host "Processing user $($currentUser)"
  $up=$null
  try {
    $up = $upm.GetUserProfile($currentUser)
  } catch {
    #this exception handler may be called for "renamend" users: In the AD the account name was changed but not in the SharePoint User Profil system
    $e=$upm.GetEnumerator()
    $e.reset()
    while( $e.movenext() ) {
      $u = $e.current
      if( $u["UserName"] -ieq $currentUser ) {
        $up = $u
        break
      }
    }
  }

  if( $up -ne $null ) {
    Write-Host "  User found in profile store"
    $picture = [byte[]](Get-Content -path "$($imagePath)$($currentUser).jpg" -Encoding Byte -ErrorAction SilentlyContinue)
    if( $picture -ne $null ) {
        Write-Host "  User picture found: ""$($imagePath)$($currentUser).jpg"""

        $dstFileName = (ConvertToLegalFileName $up["AccountName"].Value.ToString() "_")

        $flag = $profileWeb.get_AllowUnsafeUpdates()
        try
        {
          $profileWeb.set_AllowUnsafeUpdates($true)

          try
          {
            $stream = $bitmap = $ps = $null

            try {
              $stream = New-Object System.IO.MemoryStream @(, $picture)
              if( $stream -ne $null ) {
                  $bitmap = New-Object System.Drawing.Bitmap ($stream, $true)
                  if( $bitmap -ne $null ) {
                     Write-Host "  starting photo creation..."
                     $p = ([System.Drawing.Bitmap]$bitmap, $largeThumbnailSize, $largeThumbnailSize, [Microsoft.SharePoint.SPFolder]$profilePicturesFolder, "$($dstFileName)_LThumb.jpg")
                     $file = $createThumbnailMethod.Invoke($null, $p )
                     Write-Host "    large thumnail created..."
                     $p = ([System.Drawing.Bitmap]$bitmap, $smallThumbnailSize, $smallThumbnailSize, [Microsoft.SharePoint.SPFolder]$profilePicturesFolder, "$($dstFileName)_SThumb.jpg")
                     $file = $createThumbnailMethod.Invoke($null, $p )
                     Write-Host "    small thumnail created..."
                     $p = ([System.Drawing.Bitmap]$bitmap, $mediumThumbnailSize, $mediumThumbnailSize, [Microsoft.SharePoint.SPFolder]$profilePicturesFolder, "$($dstFileName)_MThumb.jpg")
                     $file = $createThumbnailMethod.Invoke($null, $p )
                     Write-Host "    medium thumnail created..."

                     $mediumUrl = $profileSite.MakeFullUrl( (MakeFullUrl $file.get_Url()) )

                     $smallThumbUrl = $getSmallThumbnailUrlMethod.Invoke($null, ([string]$mediumUrl))

                     [Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges( {
                         $ps = $up.PersonalSite
                         if( $ps -ne $null ) {
                             $ps.get_RootWeb().set_SiteLogoUrl($smallThumbUrl)
                             $ps.get_RootWeb().Update()
                         }

                         $up["PictureURL"].Value = $mediumUrl
                         $up.Commit()
                     } );
                  }
              }
            } catch {
              Write-Host "    error occured!"
              Write-Error $Error[0]
            } finally {
              if( $bitmap -ne $null ) {
                $bitmap.dispose()
              }
              if( $stream -ne $null ) {
                $stream.close()
                $stream.dispose()
              }
            }
          } catch {
          }
        } finally{
          $profileWeb.set_AllowUnsafeUpdates($flag)
        }
    } else {
      Write-Host "  Users picture not found" -ForegroundColor Red
    }
  } else {
    Write-Host "  User not found in profile store" -ForegroundColor Red
  }
}

How to have a look behind the data source of the XsltListViewWebPart of SharePoint 2010

I want to create a custom field type in a SharePoint 2010 development project (which I want to publish as as “walkthrough” on this blog Smile )

Therefore I need to inspect the source XML data that is used for XSLT rendering on a lists view page, e.g. “AllItems.aspx”

This is the result:

image

You see here for each field (column): The source XML and the items field value behind the XML data.

For the demo above I created a new custom list. It has some fields:

  • Title : Single line of text
  • Choice Field : Choice field with 3 choice values
  • Date Field : Date only field
  • Lookup Field: Lookup field to the “Start Time” field of the standard Team Site “Calendar” list. (Additional field in view: “End Time”)
  • People Picker Field: People or Group field with “People only”.

I added a single item.

That’s the set.

For the lookup field you get this result XML data:

<FieldRef Name="Lookup_x0020_Field" Type="Lookup" FieldType="Lookup" Encoded="TRUE" DisplayName="Lookup Field" ID="da1fb516-3300-47e9-8734-33db5479876e" />

For the “Title” field you get this result XML data:

<FieldRef Name="LinkTitle" ListItemMenu="TRUE" Type="Computed" FieldType="Computed" DisplayName="Title" ID="82642ec8-ef9b-478f-acf9-31f7d45fbc31" ClassInfo="Menu" ListItemMenuAllowed="Required" LinkToItemAllowed="Prohibited" />Test Text

(This field is “Computed”. In the view you do not see the “Title” field itself. You see a “computed” field named “LinkTitle” instead.)

If I want to develop a custom field type I need to create a XSL transformation for the field data. Therefore I need to refer to the source XML data. But at development time I do not know the exact structure and content of the XML data. So I modified a file in the SharePoint hive….

NEVER do the following in a productive SharePoint 2010 farm! 

1. Look for the file “C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions14TEMPLATELAYOUTSXSLfldtypes.xsl”

2. Open it.

3. Look for this line:

  <xsl:template name="PrintField" ddwrt:dvt_mode="body" ddwrt:ghost="always">

4. Before this line insert this XSLT code:

1:   <xsl:template name= "ikarstein_nodes "> 
2:     <xsl:element name= "{name()} "> 
3:       <xsl:text><![CDATA[<]]></xsl:text> 
4:       <xsl:value-of select= "name() "/> 
5:       <xsl:text><![CDATA[ ]]></xsl:text> 
6:       <xsl:for-each select= "@* "> 
7:         <xsl:call-template name= "ikarstein_attrib "/> 
8:       </xsl:for-each> 
9:       <xsl:choose> 
10:         <xsl:when test= "count(child::*)>0 "> 
11:           <xsl:text><![CDATA[>]]></xsl:text> 
12:           <xsl:for-each select= "child::*"> 
13:             <xsl:call-template name= "ikarstein_nodes "/> 
14:           </xsl:for-each> 
15:           <xsl:text><![CDATA[</]]></xsl:text> 
16:           <xsl:value-of select= "name() "/> 
17:           <xsl:text><![CDATA[>]]></xsl:text> 
18:         </xsl:when> 
19:         <xsl:otherwise> 
20:           <xsl:choose> 
21:             <xsl:when test= "string-length(text()) != 0 "> 
22:               <xsl:text><![CDATA[>]]></xsl:text> 
23:               <xsl:value-of select= "text() "/> 
24:               <xsl:text><![CDATA[</]]></xsl:text> 
25:               <xsl:value-of select= "name() "/> 
26:               <xsl:text><![CDATA[>]]></xsl:text> 
27:             </xsl:when> 
28:             <xsl:otherwise> 
29:               <xsl:text><![CDATA[/>]]></xsl:text> 
30:             </xsl:otherwise> 
31:           </xsl:choose> 
32:         </xsl:otherwise> 
33:       </xsl:choose> 
34:     </xsl:element> 
35:   </xsl:template> 
36:   <xsl:template name= "ikarstein_attrib "> 
37:     <xsl:value-of select= "name() "/> 
38:     <xsl:text><![CDATA[="]]></xsl:text> 
39:     <xsl:value-of select= ". "/> 
40:     <xsl:text><![CDATA[" ]]></xsl:text> 
41:   </xsl:template>	 

5. Then you have to modify the node starting with “<xsl:template name="PrintField" ddwrt:dvt_mode="body" ddwrt:ghost="always">”.  Insert the highlighted line of the snipped below:

   <xsl:template name= "PrintField " ddwrt:dvt_mode= "body " ddwrt:ghost= "always "> 
     <xsl:param name= "thisNode " select= ". "/> 
     <xsl:param name= "Position " select= "1 " /> 
     <xsl:param name= "Type " select= "string(@Type) "/> 
     <xsl:param name= "Name " select= "string(@Name) "/> 
     <xsl:param name= "folderUrlAdditionalQueryString "/> 
     <xsl:call-template name= "ikarstein_nodes "/> 
     <xsl:choose> 
       <xsl:when test= "< span> "> 
         <xsl:apply-templates select= ". " mode= "DateTime_body "> 
           <xsl:with-param name= "thisNode " select= "$thisNode "/> 

6. Restart the IIS.

7. Reload the list view. – Now you’ll see the fields source XML data.

Walkthrough: Create custom SharePoint 2010 list form for deployment in a Visual Studio 2010 project

(This is part 1 of 2. See link below.)

Today I want to show you how to create a custom list form for deployment within a custom list template developed in Visual Studio 2010.

Download or update or modify my demo code on Codeplex.com:
http://spcustomlistformdemo.codeplex.com/

For me I was difficult to figure out this way. I could not find a good documentation about this topic so I’ll write ist Smile – If you found another description please post a link in the comments below. Thanks!

1. Create a Site Collection in your SharePoint 2010. Mine is called “http://sharepoint.local/sites/listform”

2. In Visual Studio 2010 create an empty SharePoint 2010 project.

image

Choose “Deploy as farm solution!”

image

3. Add new item to you project: “List Definition” with type “Custom list” and with “Add a list instance”

image

image

4. Deploy this project “as is”.

5. Have a look in your browser:

image

6. Open SharePoint Designer 2010 (SPD) and open the site “http://sharepoint.local/sites/listform”. Open the deployed list “SPCustomListFormDemo – ListInstance1”

image

7. In the SPD in the List Settings of “SPCustomListFormDemo – ListInstance1” click the Ribbon tab “List Settings”. Then click “List Form”. You get this dialog:

image

Enter the name of the new list form, e.g. “new2.aspx”.

8. In SPD in the List Settings in the “Forms” view you can see your newly created list form.

image

Select it and open it for edit.

Click “Advanced Mode” in the Ribbon !!!

image

Select all the content of the new2.aspx file.

Copy the HTML code.

Open NOTEPAD and paste the HTML code.

image

9. Go into your project in Visual Studio 2010. There add a new project item of type “Application Page”.  Name it “new2.aspx”.

image

The page will be created in folder “LayoutsSPCustomListFormDemo”

image

With “drag & drop” Move the new2.aspx note to your List Definition:

image

Remove the “Layouts” folder. You get:

image

Select “new2.aspx” in the Solution Explorer and change its property “DeploymentType” to “ElementFile”

image

10. In VS2010 open “new2.aspx” for edit. Delete all content of the file except this two lines:

image

Replace the “DynamicMasterPageFile” attribute name through “MasterPageFile”. You get:

image

11. Got to NOTEPAD. Remove the “Page” tag as marked in the screenshow:

image

Select the rest of the file and copy it to the clipboard.

Now remove the complete content of the “ZoneTemplate” node. – Do not remove the “ZoneTemplate” node itself. Now the specific part of “new2.aspx” looks like this:

image

(There is a “DataFormWebPart” included in the “ZoneTemplate” node. This you remove by following the last step from above. But at runtime SharePoint will create a new DataFormWebPart in the Web Part Zone with ID “Main”. That’s the reason why we need to remove the copied and pasted Web Parts: It’s one of such a DataFormWebPart too much on the site after SharePoint creates the new one on runtime…)

12. In VS2010 paste the code into “new2.aspx”

13. Open “new2.aspx.cs” from the Solution Explorer:

image

Insert this “using”:

image

Replace the base type of your class definition from “LayoutsPageBase” to “WebPartPage”.

14. In the Solution Explorer open “schema.xml” of your list definition:

image

Scroll to the bottom of the file and find this part of XML code:

image

Replace the “SetupPath” attribute of the Form node with type “NewForm” with this value:

features$SharePoint.Feature.DeploymentPath$ListDefinition1new2.aspx

You get:

image

15. Deploy your solution.

16. Go into the browser, reload the list and “add new item”.

Now your custom list form will be used!

The URL in the Browser is identically to the first try! Why is it “NewForm.aspx” and not “new2.aspx”?

-> SharePoint uses “NewForm.aspx” as page for “Add new item” but internally redirects to the defined “New Form” of the list.

You can add some code for demo purpose to help you identifying your custom list form. For that reason I inserted

<h1>Hello World</h1>

into the the ASP Content PlaceHolder “PlaceHolderMain”:

image

 

The final result:

image

  Now you can do your own staff on your custom list form.

In Part Two I want to show you how to use you own form input fields instead using the at runtime inserted DataFormWebPart Web Part. …


It’s done: Part 2: https://blog.kenaro.com/2011/01/24/walkthrough-create-custom-sharepoint-2010-list-form-for-deployment-in-a-visual-studio-2010-project-part-2/