tag:blogger.com,1999:blog-82940239851089274482024-02-20T23:06:28.406+01:00SharePoint - Deeper than out of the boxPractical experience for SharePoint-DevelopingRicky Mattischeckhttp://www.blogger.com/profile/17257590197323377139noreply@blogger.comBlogger104125tag:blogger.com,1999:blog-8294023985108927448.post-27820260668067432072020-07-08T13:59:00.000+02:002020-07-08T14:00:49.082+02:00WARNING: Unable to resolve package source 'https://www.powershellgallery.com/api/v2/'.Hi everybody,<br /><br />recently I tried to download PowerShell modules inside my development-image in VirtualBox by using the save-module-cmdlet which leads to this errormessage:<br /><br /><code><br />PS C:\Windows\system32&gt; save-module microsoftteams -path c:\temp<br />WARNING: Unable to resolve package source 'https://www.powershellgallery.com/api/v2/'.<br />PackageManagement\Save-Package : No match was found for the specified search criteria and module name<br />'microsoftteams'. Try Get-PSRepository to see all available registered module repositories.<br />At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:1561 char:21<br />+ $null = PackageManagement\Save-Package @PSBoundParameters<br />+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br /> + CategoryInfo : ObjectNotFound: (Microsoft.Power...ets.SavePackage:SavePackage) [Save-Package], Exceptio<br /> n<br /> + FullyQualifiedErrorId : NoMatchFoundForCriteria,Microsoft.PowerShell.PackageManagement.Cmdlets.SavePackage<br /></code><br /><br />Trying to connect to the displayed https-url also failed while opening it in browser succeded:<br /><br /><code><br />PS C:\Windows\system32> invoke-webrequest https://www.powershellgallery.com/api/v2/<br />invoke-webrequest : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS<br />secure channel.<br /></code><br /><br />So after hours of checking all possible proxy/certificate/ssl-settings, I found the solution in powershell itself:<br /><br />Because of reasons I had added the SharePoint-Powershell SnapIn to c:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1 which afterwards broke something so that all connections to https broke. <br /><br />After commenting out the <code>Add-PSSnapin "Microsoft.SharePoint.PowerShell"</code> everything works like a charm.<br /><br />If you encounter something similar, try this. And if you try to save changes to profile.ps1 ensure that you opened the file in your editor as administrator. You can test the successful save by adding a write-host-output to the screen. Finally don't forget to close the current and reopen a new PowerShell.<br />Ricky Mattischeckhttp://www.blogger.com/profile/17257590197323377139noreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-3776960534241177442017-07-04T15:50:00.000+02:002017-07-04T15:56:26.153+02:00Restore deleted Form-WebParts (NewForm.aspx, EditForm.aspx, DispForm.aspx)If a clever user hits on the idea to delete the form webpart from NewForm.aspx, EditForm.aspx or DispForm.aspx, this can be restored easily with PowerShell. No need to open SharePoint Designer.<br />
<br />
Basically a new ListFormWebPart-object must be instanciated, connected with the list and added to the webpartzone of the page. That's it.<br />
<br />
Have a look at the following code:<br />
<br />
<code>
$site = New-Object Microsoft.SharePoint.SPSite -ArgumentList http://sitecollection/sites/site1 <br />
$web = $site.OpenWeb() <br />
<br />
$list = $web.Lists["My Library"] #title of the regarding list <br />
<br />
$webpart = new-object Microsoft.SharePoint.WebPartPages.ListFormWebPart <br />
<br />
# assign list to webpart <br />
$webpart.ListId = $list.ID <br />
<br />
# possible pagetypes are PAGE_DISPLAYFORM, PAGE_EDITFORM, or PAGE_NEWFORM <br />
# see: https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webpartpages.listformwebpart.pagetype.aspx <br />
$webpart.PageType = "PAGE_EDITFORM" <br />
<br />
# use the absolute link to the form-aspx <br />
$wpm = $web.GetLimitedWebPartManager("http://sitecollection/sites/site1/myLibrary/Forms/EditForm.aspx", [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared) <br />
<br />
$wpm.AddWebPart($webpart, "Main", 1) <br />
<br />
# dispose spweb-object in webpartmanager to avoid memory leaks <br />
$wpm.Web.Dispose() <br />
<br />
$web.Dispose() <br />
$site.Dispose() <br />
</code>Ricky Mattischeckhttp://www.blogger.com/profile/17257590197323377139noreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-7576745497481641392014-09-10T10:38:00.001+02:002014-09-10T10:47:45.341+02:00Adding ECB directly to document librariesRecently I used to look for a possibility to change the SharePoint 2013 ECB (Edit Control Block) from CallOut-Popup back to direct call as known from SharePoint 2010.<br />
<br />
I found this way as a quick work around:<br />
<a href="http://www.learningsharepoint.com/2013/05/18/hide-callouts-in-a-sharepoint-2013-task-list/">http://www.learningsharepoint.com/2013/05/18/hide-callouts-in-a-sharepoint-2013-task-list/</a><br />
<br />
But by this solution, the drag-and-drop area is not rendered anymore and the old-fashioned "Add new item"-link below the list returns.<br />
<br />
So I spent a little more time with googeling and found this page which adds an additional icon to click which displays the ECB directly:<br />
<br />
<a href="http://www.booden.net/DirectAccessToEcb.aspx">http://www.booden.net/DirectAccessToEcb.aspx</a><br />
<br />
The site describes the How-To and provides a sandboxed-solution for directly adding to the solutions-gallery of the SiteCollection. After activating everything to do is finished. <br />
<br />
As you can see, the standard behaviour is not touched but extended by a new functionality:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgukmeLmCIh-WQ54t91T8RqfB51V54JDlJXc4cYwwEQXUI8oprVd7s9_sAE0UqlPe8s0kvxHZu2GWZpZMgWg-ZKgoq2ihY5nV2LDO4iYw7oY3RabT8ZvMpoUzkY1AhTXIjW0WpmLYI4axU/s1600/2014-09-10_103408.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgukmeLmCIh-WQ54t91T8RqfB51V54JDlJXc4cYwwEQXUI8oprVd7s9_sAE0UqlPe8s0kvxHZu2GWZpZMgWg-ZKgoq2ihY5nV2LDO4iYw7oY3RabT8ZvMpoUzkY1AhTXIjW0WpmLYI4axU/s1600/2014-09-10_103408.png" height="176" width="320" /></a></div>
<br />
<br />
It depends to the customer's wish if the three-dots-button now should be hidden (needs some additional work) or both buttons should remain.<br />
<br />
<br />Ricky Mattischeckhttp://www.blogger.com/profile/17257590197323377139noreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-60490402957620921562014-07-08T15:01:00.001+02:002014-07-08T15:10:36.985+02:00SPFile.Publish() writes 'System Account' to 'ModifiedBy'-column instead of current userI had the following scenario:<br />
<br />
Documents that are dragged&dropped in a documentlibrary should be enriched with additional metadata and after that they should be published.<br />
The document library has versions enabled with minor versions.<br />
<br />
All action takes place in a SPItemEventReceiver, the details for that I'll omit for now.<br />
<br />
Now when it came to do spFile.Publish(), after that the "ModifiedBy"-Column has 'System Account' instead of the current user and there seemed no way to set it manually. Neither the Publish-Method had a parameter to set the current user, nor SPListItem.SystemUpdate or SPListItem.UpdateOverwriteVersion worked:<br />
<br />
- SystemUpdate won't save changes to CreatedBy/Created or ModifiedBy/Modified-fields.<br />
- UpdateOverwriteVersion would work but creates a minor version (1.1 in my case)<br />
<br />
But then I found a solution <a href="http://social.msdn.microsoft.com/Forums/en-US/63c52338-ffcf-42f6-8d13-df8ce27c51ae/updating-modified-by-and-modified-in-list-where-versioning-is-enabled?forum=sharepointdevelopmentlegacy">here</a>.<br />
<br />
I couldn't believe that and tried it out and it really worked! The post said, the SPSite-Object should be opened by adding the SPUserToken to the constructor and then SPFile.Publish() will save the user as last modifier. To show a concrete minimal example:<br />
<br />
<code>
using (SPSite spSite = new SPSite(properties.SiteId, properties.OriginatingUserToken))
{</code><br />
<code> using (SPWeb spWeb = spSite.OpenWeb(serverRelativeWebUrl))
{ </code><br />
<code> SPListItem spListItem = spWeb.GetListItem(properties.Web.ServerRelativeUrl); // make sure, the file is checked in before or try to acces or you get a file-not-found-error here </code><br />
<code> SPFile spFile = spListItem.File; </code><br />
<code> ... add more data to spListItem... </code><br />
<code> spListItem.SystemUpdate(false); </code><br />
<code> ... check for enabled versions, etc... </code><br />
<code> spFile.Publish(); // writes the SPUser related to the SPUserToken from properties.OriginatingUserToken to 'ModifiedBy'-column, if SPSite is instantiated with new SPSite(properties.SiteId) only, 'System Account' is used</code><br />
<code> }</code><br />
<code>}</code><br />
<br />
<code>properties</code> is the default SPItemEventProperties-object from the SPItemEventReceiver.<br />
<br />
Pay attention, the "Modified"-Column (DateTime) changes to DateTime.Now. But this was not in the focus of my requirement.<br />
<br />
I always thought, using new SPSite(Guid) would open the SPSite in current user's context but that's not true as a closer look by using Reflector shows. Have a look at two of the default constructors from SPSite-class:<br />
<br />
public SPSite(System.Guid id) : this(id, SPFarm.Local, SPUrlZone.Default, <span style="background-color: yellow;">SPSecurity.GetDefaultUserToken()</span>)<br />
<br />
<br />
public SPSite(System.Guid id, SPUserToken userToken) : this(id, SPUrlZone.Default, <span style="background-color: yellow;">userToken</span>)<br />
<br />
Do you note the difference? :-) Ricky Mattischeckhttp://www.blogger.com/profile/17257590197323377139noreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-22404081273603190412014-06-30T13:26:00.001+02:002014-06-30T13:26:12.149+02:00Avoiding conflicts if Custom_AddDocLibMenuItems-function is implemented multipleToday I found a really helpful tip how to add custom items to the SharePoint Edit Control Block (ECB) without getting in conflict with other used Custom_AddDocLibMenuItems-function-calls (for e.g. from another deployed wsp-solution or script added in a Content Editor WebPart (in SharePoint 2010) or ScriptEditor-WebPart (in SharePoint 2013).<br />
You can find it here in Stuart Roberts' blog: <a href="http://www.stuartroberts.net/index.php/2014/01/21/quick-tip-19">http://www.stuartroberts.net/index.php/2014/01/21/quick-tip-19</a>Ricky Mattischeckhttp://www.blogger.com/profile/17257590197323377139noreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-31021779063815864342013-11-25T10:12:00.000+01:002014-09-10T14:42:20.700+02:00A potentially dangerous Request.Form value was detected from the client (ctl00$PlaceHolderMain$...Recently I got the following errormessage in SharePoint 2013 after trying to save an edited publishing page. Also it was not possible to add any webpart.<br />
Some googling resultet in different web.config-modifications, some said to set requestValidationMode="4.0" to requestValidationMode="2.0" in <system.web>-node, others recommended to set validateRequest="false"in <pages>-node. In fact for it only worked after I did both changes. So search for <br />
<br />
<code>
<system.web><br /> <httpRuntime <b>requestValidationMode="4.0"</b> /><br /></system.web><br />
</code>
<br />
and set <b>requestValidationMode</b> to "2.0" and search for<br />
<br />
<code>
<pages enableSessionState="false" enableViewState="true" enableViewStateMac="true" <b>validateRequest="true"</b> clientIDMode="AutoID" pageParserFilterType="Microsoft.SharePoint.ApplicationRuntime.SPPageParserFilter, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" asyncTimeout="7"><br /> <namespaces><br /> <remove namespace="System.Web.UI.WebControls.WebParts" /><br /> </namespaces><br /> <tagMapping><br /> <add tagType="System.Web.UI.WebControls.SqlDataSource, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mappedTagType="Microsoft.SharePoint.WebControls.SPSqlDataSource, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" /><br /> </tagMapping><br /> <controls><br /> <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /><br /> <add tagPrefix="spsswc" namespace="Microsoft.Office.Server.Search.WebControls" assembly="Microsoft.Office.Server.Search, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" /><br /> </controls><br /> </pages><br />
</code>
<br />
and set <b>validateRequest </b>to "false".
Ricky Mattischeckhttp://www.blogger.com/profile/17257590197323377139noreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-67640144052359248522013-05-02T13:16:00.000+02:002013-05-02T13:16:15.745+02:00Get current versions for activated features (not feature definitions) in a web or site collectionRecently I wrote a PowerShell-Script which writes the current version-numbers of web-features specified by a name-filter into a file. These versions are not from the feature-definition but from the feature activated in a web.<br />
<br />
An example for this could be the following:<br />
On a SharePoint-server a feature named <b>custom_feature_1</b> was installed which has a version of 3.0.0.0 because it's been updated a few times during the lifecycle of the appication.<br />
Because the rootweb was created first, the feature's version is 1.0.0.0 there. A newer subweb below has been created after the feature was updated and there the feature's version is 2.0.0.0. Now, after the third update, another web will be created where the feature now has a version of 3.0.0.0.<br />
<br />
So how can you easily get the version of the feature activated in one of these webs?<br />
<br />
You can use this PowerShell-script to get all information about your features:<br />
<code><br />
get-spweb <b>http://customsitecollection/customweb</b> |% {$_.Features} | where-object {$_.Definition -ne $null} | where-object {$_.Definition.DisplayName.StartsWith("<b>custom</b>")} |% {new-object psobject -Property @{Id = $_.DefinitionId; Version = $_.Version; DisplayName = ($_ | select -ExpandProperty Definition).DisplayName; Scope = ($_ | select -ExpandProperty Definition).Scope; }} | format-table -Property * -Autosize | Out-String -Width 120 | out-file <b>custom_web_features.txt</b><br />
</code><br />
<br />
Just copy these lines and replace the bold-marked parts by your own needs:<br />
<b>http://customsite/customweb</b> - The full path to the web you want the feature-versions from<br />
<b>custom</b> - The name that the features starts with in SharePoint-Root features-folder<br />
<b>custom_web_features.txt</b> - The name of the file that's created with information<br />
<br />
The content of the file should look like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHrjPLjTm8O4SLiU-ftvX3P5p759r8XS22EEbCNtvwiLAXoZaCZVXJSIZGETQqkaOAhMs2iCNaDDrXFtxntXr29PeGO2x2D5-FtNATs4vm0jjO4wOnVKJviZxvmerMtbN3ySSW6g6L3gQ/s1600/result_ps_current_feature_versions_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHrjPLjTm8O4SLiU-ftvX3P5p759r8XS22EEbCNtvwiLAXoZaCZVXJSIZGETQqkaOAhMs2iCNaDDrXFtxntXr29PeGO2x2D5-FtNATs4vm0jjO4wOnVKJviZxvmerMtbN3ySSW6g6L3gQ/s640/result_ps_current_feature_versions_1.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
You can reuse the script for site-scoped features too. Just replace <b>get-spweb</b> by <b>get-spsite</b> and a valid URL to a sitecollection.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-44485919234107570312013-04-23T12:58:00.001+02:002013-04-23T13:16:56.987+02:00"Active Deployment Configuration"-setting in Visual Studio 2012 is always "Default"There is a bug in current Visual Studio 2012 which always sets the "Active Deployment Configuration" to "Default" after re-opening the program/solution.<br />
If you set "No Activation", this is correctly stored in the .csproj-file but VS ignores this and preselectes "Default" on opening:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPLAivImU_0WjU4p-SKsaBkD37BLx9ka3-ghlA32mVAZb3kO6GEP5mf7DQOjT8QBzJUorCtbrTmuxbfaARNSnyn77AVg-TMv-Hu8AATbS0FDKTmzVp-Q2FtAuyizTG1gVOTe30SfZW0SA/s1600/active_deployment_configuration_default.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPLAivImU_0WjU4p-SKsaBkD37BLx9ka3-ghlA32mVAZb3kO6GEP5mf7DQOjT8QBzJUorCtbrTmuxbfaARNSnyn77AVg-TMv-Hu8AATbS0FDKTmzVp-Q2FtAuyizTG1gVOTe30SfZW0SA/s1600/active_deployment_configuration_default.png" /> </a><br />
I reported this to <a href="https://connect.microsoft.com/VisualStudio/feedback/details/781650/vs-2012-sharepoint-solution-properties-active-deployment-configuration-is-not-saved#tabs" target="_blank">Microsoft </a>and finally got an answer that said I should install the Microsoft Office Developer Tools which were released in March 2013 (can be found <a href="http://aka.ms/OfficeDevToolsForVS2012" target="_blank">here</a>). After installing, the bug indeed was fixed and now the configuration is loaded correctly:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0wL2zB8UYe3iy3fOpc-_EN5EDfB5qDFk0ef4WdvD08C1MvJbphTFdCR7AVHHxlV0CHmJp1H9HcCFOmWqY46XoBBES8hbWEBD_ZFn7qvYR0c4Ejt8aww3Jkj7VHvYD3KIyUJWz2tj-nOE/s1600/active_deployment_configuration_no_activation.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0wL2zB8UYe3iy3fOpc-_EN5EDfB5qDFk0ef4WdvD08C1MvJbphTFdCR7AVHHxlV0CHmJp1H9HcCFOmWqY46XoBBES8hbWEBD_ZFn7qvYR0c4Ejt8aww3Jkj7VHvYD3KIyUJWz2tj-nOE/s1600/active_deployment_configuration_no_activation.png" /></a><br />
Personally I think, Microsoft should fix this bug in a Visual Studio update but not in an separate downloadable add-on because it's a bug by Visual Studio itself.<br />
<br />
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-4953135875418681132012-11-23T14:55:00.000+01:002013-04-23T13:18:11.884+02:00Issues with Lookup-Fields with each more than 20 itemsIf you have multiple lookup-fields in your form which reference to more than 20 items (hardcoded limit in the LookupField-Control!), you may notice to the display and behaviour of your control:<br />
<br />
- The rendering of the field switches from select-tag to an input-tag and an img-tag. A click on the image shows a layer with the selectfield.<br />
- This only occures to Internet Explorer, not to Firefox.<br />
<br />
The naughty thing on this is the issue, that the selectfield-layer appears below the first-clicked lookup-field, no matter, which lookupfield you click afterwards. <br />
<br />
Click on the first lookup:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBlu-54fQiYZ0r6Xea-AjbT4fLUdt9dPAs90VyGWlLapafhVOjJltSTNT7PyTHI3KM9WwJj9LrvDb2jqnvRl-ly2qVgoGQDUrgGzj3l6FopYWn69FI2ranuqHDZt30ITbMtWAYW-Mtb5s/s1600/lookup1.png" imageanchor="1" style=""><img border="0" height="150" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBlu-54fQiYZ0r6Xea-AjbT4fLUdt9dPAs90VyGWlLapafhVOjJltSTNT7PyTHI3KM9WwJj9LrvDb2jqnvRl-ly2qVgoGQDUrgGzj3l6FopYWn69FI2ranuqHDZt30ITbMtWAYW-Mtb5s/s400/lookup1.png" /></a><br />
<br />
Click on the second lookup:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSVmdVBQm05xeAbclR7MTvvg4Fg95C3oO_kRsd9y4HbDh8UEaiqLyJdICMRXiHAPTjlyWTeZVVms9WOLzLJG47kV-x91GnQjM7hV_bCKKHafdy_kSsB59Ktbjp51XdygaPtwUz3oXXfS4/s1600/lookup2.png" imageanchor="1" style=""><img border="0" height="137" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSVmdVBQm05xeAbclR7MTvvg4Fg95C3oO_kRsd9y4HbDh8UEaiqLyJdICMRXiHAPTjlyWTeZVVms9WOLzLJG47kV-x91GnQjM7hV_bCKKHafdy_kSsB59Ktbjp51XdygaPtwUz3oXXfS4/s400/lookup2.png" /></a><br />
<br />
This bug can be fixed by override a function in the core.js that must be loaded immediatly in the masterpage. A good piece of working code I found here today: <a href="http://dipaktele.blogspot.de/2012/07/two-lookup-field-with-more-than-20.html">http://dipaktele.blogspot.de/2012/07/two-lookup-field-with-more-than-20.html</a><br />
<br />
I copied the code found on this page and added it here:<br />
<br />
<code><br />
function FilterChoice(opt, ctrl, strVal, filterVal) {<br />
if (typeof (opt) != "undefined") {<br />
var i,<br />
cOpt = 0,<br />
bSelected = false,<br />
strHtml = "",<br />
strId = opt.id,<br />
strName = opt.name,<br />
strMatch = "",<br />
strMatchVal = "",<br />
strOpts = ctrl.choices,<br />
rgopt = strOpts.split("|"),<br />
offSet = $(ctrl).position(),<br />
x = offSet.left,<br />
y = offSet.top 15, <br />
strHidden = ctrl.optHid,<br />
iMac = rgopt.length - 1,<br />
iMatch = -1,<br />
unlimitedLength = false,<br />
strSelectedLower = "";<br />
if (opt != null && opt.selectedIndex >= 0) {<br />
bSelected = true;<br />
strSelectedLower = opt.options[opt.selectedIndex].innerText;<br />
}<br />
for (i = 0; i < rgopt.length; i = i 2) {<br />
var strOpt = rgopt[i];<br />
while (i < iMac - 1 && rgopt[i 1].length == 0) {<br />
strOpt = strOpt "|";<br />
i ;<br />
if (i < iMac - 1) {<br />
strOpt = strOpt rgopt[i 1];<br />
}<br />
i ;<br />
}<br />
var strValue = rgopt[i 1];<br />
var strLowerOpt = strOpt.toLocaleLowerCase();<br />
var strLowerVal = strVal.toLocaleLowerCase();<br />
if (filterVal.length != 0)<br />
bSelected = true;<br />
if (strLowerOpt.indexOf(strLowerVal) == 0) {<br />
var strLowerFilterVal = filterVal.toLocaleLowerCase();<br />
if ((strLowerFilterVal.length != 0) && (strLowerOpt.indexOf(strLowerFilterVal) == 0) && (strMatch.length == 0))<br />
bSelected = false;<br />
if (strLowerOpt.length > 20) {<br />
unlimitedLength = true;<br />
}<br />
if (!bSelected || strLowerOpt == strSelectedLower) {<br />
strHtml = "<option selected value=\"" strValue "\">" STSHtmlEncode(strOpt) "</option>";<br />
bSelected = true;<br />
strMatch = strOpt;<br />
strMatchVal = strValue;<br />
iMatch = i;<br />
}<br />
else {<br />
strHtml = "<option value=\"" strValue "\">" STSHtmlEncode(strOpt) "</option>";<br />
}<br />
cOpt ;<br />
}<br />
}<br />
var strHandler = " onclick=\"HandleOptDblClick()\" onkeydown=\"HandleOptKeyDown()\""; <br />
var strOptHtml = "";<br />
if (unlimitedLength) {<br />
strOptHtml = "<select tabIndex=\"-1\" ctrl=\"" ctrl.id "\" name=\"" strName "\" id=\"" strId "\"" strHandler;<br />
}<br />
else {<br />
strOptHtml = "<select class=\"ms-lookuptypeindropdown\" tabIndex=\"-1\" ctrl=\"" ctrl.id "\" name=\"" strName "\" id=\"" strId "\"" strHandler;<br />
}<br />
if (cOpt == 0) {<br />
strOptHtml = " style=\"display:none;position:absolute;z-index:2;left:" x "px;top:" y "px\" onfocusout=\"OptLoseFocus(this)\"></select>";<br />
}<br />
else {<br />
strOptHtml = " style=\"position:absolute;z-index:2;left:" x "px;top:" y "px\"" " size=\"" (cOpt <= 8 ? cOpt : 8) "\"" (cOpt == 1 ? "multiple=\"true\"" : "") " onfocusout=\"OptLoseFocus(this)\">" strHtml "</select>";<br />
}<br />
opt.outerHTML = strOptHtml;<br />
var hid = document.getElementById(strHidden);<br />
if (iMatch != 0 || rgopt[1] != "0")<br />
hid.value = strMatchVal;<br />
else<br />
hid.value = "0";<br />
if (iMatch != 0 || rgopt[1] != "0")<br />
return strMatch;<br />
else return "";<br />
}<br />
}<br />
<br />
_spBodyOnLoadFunctionNames.push("FilterChoice"); <br />
function EnsureSelectElement(ctrl, strId) {<br />
$("#" strId).remove();<br />
var select = document.getElementById(strId);<br />
if (select == null) {<br />
select = document.createElement("SELECT");<br />
ctrl.parentNode.appendChild(select);<br />
select.outerHTML = "<select id=\"" strId "\" ctrl=\"" ctrl.id "\" class=\"ms-lookuptypeindropdown\" name=\"" strId "\" style=\"display:none\" onfocusout=\"OptLoseFocus(this)\"></select>";<br />
FilterChoice(select, ctrl, ctrl.value, "");<br />
}<br />
return document.getElementById(strId); ;<br />
}<br />
</code><br />
<br />
After that, the select is displayed correctly:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqqn5J7sG3EJnN3PfSlC3Z9ayo5yc5HwiI2D-VFTjoA-32gdQYf9LGS9IL4b3AEHCmc6rfkj4IZpLQhpEwAHNEgyob5F__XkQrqhvL23t3w5QcQlW2TTf_s4Q9w3ByEUuEGdlIt-uKXFw/s1600/lookup_afterchange.png" imageanchor="1" style=""><img border="0" height="149" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqqn5J7sG3EJnN3PfSlC3Z9ayo5yc5HwiI2D-VFTjoA-32gdQYf9LGS9IL4b3AEHCmc6rfkj4IZpLQhpEwAHNEgyob5F__XkQrqhvL23t3w5QcQlW2TTf_s4Q9w3ByEUuEGdlIt-uKXFw/s400/lookup_afterchange.png" /></a><br />
<br />
Please be sure to include there functions in your own js-file that's loaded after the core.js and avoid modifying the original core.js.<br />
<br />
<br />
<br />
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-3247386934002170952012-11-15T15:21:00.005+01:002014-09-10T14:42:51.138+02:00New SharePoint 2013 / 15 cmdlets for Powershell you shouldn't use...I just browse the web for new things that come with SharePoint 2013 / 15. Now I'm landed on the technet-page for all new Powershell-Cmdlets: <br />
<br />
<a href="http://technet.microsoft.com/library/ff678226%28office.15%29.aspx">http://technet.microsoft.com/library/ff678226%28office.15%29.aspx</a><br />
<br />
A funny thing are a few new cmdlets you explicitely should avoid to use but the funniest imo are Add-SPSocialAppPermissions and Remove-SPSocialAppPermissions.<br />
<br />
So if you belong to the 1% of people with a completely working user profile synchronization service without any issues and you are bored of all the perfectly working sharepoint environment, you should definitively run this cmdlet, because "The use of the Add-SPSocialAppPermissions cmdlet can result in profile synchronization connections that are unusable and non-editable". <br />
<br />
More cmdlets you called upon not to use are:<br />
<br />
- New-SPBECWebServiceApplicationProxy<br />
- Remove-SPSocialAppPermissions<br />
- New-SPBECWebServiceApplicationProxy<br />
<br />
If you have any idea, why Microsoft creates such cmdlets not intended to use by people, please leave a comment :-D Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-85731723483033933192012-04-04T10:04:00.000+02:002012-04-04T10:06:06.719+02:00ArgumentException when setting SPUser to a UserField in SPListItemA little hint for everyone that ever got an argument exception if he tried to set a SPUser-object to an userfield in a list item:<br />
<code><br />
SPListItem listItem = list.Items.Add(listRootFolder.ServerRelativeUrl, SPFileSystemObjectType.File, null); <br />
listItem["Owner"] = spUser; <-- if you step through the code while debugging, an argument exception may occur here <br />
listItem["Url"] = url; <br />
listItem["Title"] = title; <br />
listItem.Update(); </code><br />
<br />
In case of an argument exception, you have to check if the assigned spUser-object has been opened from the same parent web as the list.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-84928535091503071842012-02-17T11:30:00.001+01:002013-04-23T13:23:04.107+02:00Bugfix for 'Walkthrough: Replacing a Button on the Server Ribbon'There is an example how to replace a button on the server ribbon <a href="http://msdn.microsoft.com/en-us/library/ff407619.aspx" target="_blank">available in the MSDN</a> with one issue: it doesn't work ... ;-)<br />
<br />
But I found the error and commented it below in the Community Content-section. For completeness I'll post it in my blog again:<br />
<br />
There exists no button with the ID 'Ribbon.Library.Actions.ConnectToClient.ReplacementButton' so a javascript-error is thrown in the browser. The part of the xml must changed to this line and then it works:<br />
<br />
<code><CommandUIDefinition Location="Ribbon.Library.Actions.ConnectToClient"><br />
<Button Id="Ribbon.Library.Actions.ConnectToClient" Command="ReplacementButtonCommand" ...></code><br />
<br />
Just remove the string '.ReplacementButton' in the Id of the Button from the example and it works.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-22683043991514422812011-10-04T15:35:00.001+02:002013-04-23T13:23:13.181+02:00Error occurs while trying to upgrade installed features of an upgraded solutionIt’s way back since my last post, but at last I found something very useful to post.<br />
<br />
During the process of developing on a SharePoint 2010 solution, to have clean presuppositions for testing and avoid phantom mistakes I very often create new site collections and delete them afterwards. A part of this process is also removing and adding newer versions of the solutions to the solution-store. So from time to time I was confronted with strange error messages when I tried to upgrade features to new versions.<br />
<br />
I concretely tried to do it the Microsoft recommended way and used a modified version of the program, you can find here: <a href="http://msdn.microsoft.com/en-us/library/ff798298.aspx">http://msdn.microsoft.com/en-us/library/ff798298.aspx</a><br />
<br />
The program that iterates over the SPWebApplication to find upgradable features sometimes fails with an error message that says that it can’t find a special SiteCollection: The site with the id <code>D0D529C1-DC06-4DB0-A8A3-81466E1E75DB</code> could not be found.<br />
This is true because it has been previously deleted by me and is no longer available in Central Administration or anywhere else. It seems, there are still some SiteCollection-related artifacts in the content database stored that prevent a clean upgrading of the new versioned features. <br />
<br />
Have a look at the Default TimerJobs, the promisingly entry “Gradual Site Delete”, we perhaps can use to solve this issue with tools out of the box. By default it’s executed daily but we can change the cycle to earlier executions or even start it manually. <br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRnl6RRMYfV2meJO-a5_K8bRWBLCpCKniDob0UYZjtNYYugT10DQjcdHH4RDKoWH63io1SIL78cc9fvAJTmYcMhpdL9_o_Tc39o6Y1K0PQvHi2NAbToXsMs9RF2GoFyhvwhyOBp6MUqw8/s1600/gradual_site_deletion_detailview.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRnl6RRMYfV2meJO-a5_K8bRWBLCpCKniDob0UYZjtNYYugT10DQjcdHH4RDKoWH63io1SIL78cc9fvAJTmYcMhpdL9_o_Tc39o6Y1K0PQvHi2NAbToXsMs9RF2GoFyhvwhyOBp6MUqw8/s1600/gradual_site_deletion_detailview.png" /></a></div><a href="http://bastiaanjacobs.nl/2010/10/14/sharepoint-2010-timer-jobs-their-functions-overview/">This blog</a> described its functionality as “Deletes all the data from the host content database for all deleted site collections”. What a pitty, in my case, it doesn’t. The error remains.<br />
<br />
Now it’s time to have a look at the content database. The name of this table looks encouraging: dbo.SiteDeletion<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2cLcP6G8ZIeQBOpxU3wbVGpLyznRIGUYfe9v2f5TXhherw_SdXQ3zk20R48JhlJ7P3CawnS7y-mxDX1AG8LfF4UweWOTscQp63geuUcUwSLdbDjp9be5hVJWUVHPK9RiuF2v8p4ftUFA/s1600/dbo.siteDeletion.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2cLcP6G8ZIeQBOpxU3wbVGpLyznRIGUYfe9v2f5TXhherw_SdXQ3zk20R48JhlJ7P3CawnS7y-mxDX1AG8LfF4UweWOTscQp63geuUcUwSLdbDjp9be5hVJWUVHPK9RiuF2v8p4ftUFA/s1600/dbo.siteDeletion.png" /></a></div>After opening the table, an entry appears that includes the evil SiteId, which seems to be the crux of the matter:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiXVJ-Pdq-6-kVC75e3EY7_ByhgqscQ3iofhADt83VmNRdCeMWYsbvUQ0UC0Xiw1ANqexWaR_6QnPWn6PEefr0jSxyamPUAphyu0qOtgkBbIn2492vnmqk1FVhbGea65ZZevgn99hJ3sM/s1600/dbo.siteDeletion_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiXVJ-Pdq-6-kVC75e3EY7_ByhgqscQ3iofhADt83VmNRdCeMWYsbvUQ0UC0Xiw1ANqexWaR_6QnPWn6PEefr0jSxyamPUAphyu0qOtgkBbIn2492vnmqk1FVhbGea65ZZevgn99hJ3sM/s1600/dbo.siteDeletion_2.png" /></a></div><br />
Luckily Microsoft gave us the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spcontentdatabase.forcedeletesite.aspx">method ForceDeleteSite on the SPContentDatabase-class</a>.<br />
<br />
If you write a really short program, for e.g. a console application that takes the Uri to get the SPWebApplication-object and the Guid of the corrupted SiteCollection, you can create a new entry to the database-table with a datetime of 1900-01-01. <br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkmhoJdGs5D4r6qHuJSRTTxLbUJtFi9E9Nsd-PUswf1uSGLMBNi-qVs0E8Jb4HhCIJ1WFvm0FjThILXIPjZJUUTqNLdaJ2GmMLuhKbeoN-_m08az520TcXfIKxGIt-7FOoJKfdWvD1DBA/s1600/dbo.siteDeletion_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkmhoJdGs5D4r6qHuJSRTTxLbUJtFi9E9Nsd-PUswf1uSGLMBNi-qVs0E8Jb4HhCIJ1WFvm0FjThILXIPjZJUUTqNLdaJ2GmMLuhKbeoN-_m08az520TcXfIKxGIt-7FOoJKfdWvD1DBA/s1600/dbo.siteDeletion_3.png" /></a></div><br />
Simply, there are only those two lines needed:<br />
<code><br />
SPWebApplication spWebApplication = SPWebApplication.Lookup(new Uri("http://mywebapplication")); // insert the webapplication<br />
<br />
spWebApplication.ContentDatabases[0].ForceDeleteSite(new Guid("D0D529C1-DC06-4DB0-A8A3-81466E1E75DB"), true, false); // insert the ID from the errormessage<br />
</code><br />
<br />
After that, retry running the “Gradual Site Delete”-timerjob and – surprise – both entries are deleted.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjg5_9D8FVlGppchUGMv6FmoMtAl4afVziublfBTGnfSnRahimMB4RsUCkOVMieOsqk2Tu0m3XDG3gop7HdGRnQXbUqqFoJupfQZeWHiVquuS8M400vpskU3SsAzDZvs4kPBk6dk-hZwnI/s1600/dbo.siteDeletion_4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjg5_9D8FVlGppchUGMv6FmoMtAl4afVziublfBTGnfSnRahimMB4RsUCkOVMieOsqk2Tu0m3XDG3gop7HdGRnQXbUqqFoJupfQZeWHiVquuS8M400vpskU3SsAzDZvs4kPBk6dk-hZwnI/s1600/dbo.siteDeletion_4.png" /></a></div><br />
If you retry upgrading your feature, no more annoying error message occurs.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-77027582206211037602011-07-12T15:12:00.002+02:002013-04-23T13:23:23.060+02:00Anonymous access prompted for login after click in web part area on publishing portalCurrently I'm experimenting with publishing portal and the ability to use it for publicfacing internet sites where anonymous access is allowed. In the site permissions I gave the anonymous users access to the entire website.<br />
Afterwards I created a custom list named 'Test' and entered three simple items with just the title-field filled.<br />
<br />
On the default.aspx of the publishing portal I added a ListVievWebPart to the 'Test'-list and published it.<br />
<br />
Now if the anonymous user loggs in, he sees the default publishing page with that LVWP and three items in it.But if he clicked on an item, the login-popup appeared. Also if I tried to break the list-permission-inheritance from the web, the list items would open but the first click in the webpart resulted in that nasty login-popup.<br />
<br />
So what to do? A lot of pages, blogs and forums on the internet suggest to deactivate a hidden feature called '<b>ViewFormPagesLockDown</b>' to allow anonymous users to have access to list-items.<br />
Another approach I found on several pages was to remove the coupling to the code-behind in the file wpribbon.aspx on the _layouts-folder directly to workaround the other problem.<br />
<br />
I didn't like neither the first nor the second way. The one kills the security concept, the other transgesses the rules of Microsoft by changing files directly on the server.<br />
<br />
So I grabbed good old SharePoint Manager 2010 and examined the 'Test'-List where I detected the <b>AnonymousPermMask64</b>-Attribute that had this string set by default: ViewListItems, ViewVersions, Open, ViewPages, UseClientIntegration.<br />
<br />
This had to be the key to solve the problem... I went to the MSDN-Article describing all SPBasePermissions-enum-values and found... <b>ViewFormPages</b> (<span class="selflink"></span>View forms, views, and application pages, and enumerate lists).<br />
<br />
Okay, rest was easy... If there is a feature activated on publishing-portal called ViewFormPagesLockDown that prevents the anonymous user from entering formpages, then the basepermission ViewFormPages perhaps grants access for the element.<br />
<br />
So I programmatically broke the inheritance of the list-permissions and reset the spbasepermissions to the AnonymousPermMask64-Attribute as you can see in the following code-segment and everything worked as I imagined:<br />
<br />
<code></code><br />
<br />
SPList spList = spWeb.GetList("/Lists/Test");<br />
<br />
spList.BreakRoleInheritance(false);<br />
spList.AnonymousPermMask64 =<br />
SPBasePermissions.ViewListItems | <br />
SPBasePermissions.ViewVersions | <br />
SPBasePermissions.Open | <br />
SPBasePermissions.ViewPages |<br />
SPBasePermissions.UseClientIntegration |<br />
SPBasePermissions.ViewFormPages;<br />
<br />
spList.Update(); <br />
<br />
<br />
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-36235108641367130352011-07-07T10:31:00.013+02:002013-04-23T13:23:30.860+02:00Add customaction to ribbonbar in sharepoint 2010 wiki pageJust a simple copy & paste of a custom action that adds a button to the ribbonbar in a publishingpage in the pageslist of a wiki-site:<br />
<br />
<code> <CustomAction Id="WikiDocumentExportCustomizationPageView" Rights="Contribute" Location="CommandUI.Ribbon" Sequence="30" Title="Wiki-Document-Export"> </code><br />
<code> <CommandUIExtension> </code><br />
<code> <CommandUIDefinitions> </code><br />
<code> <CommandUIDefinition Location="Ribbon.WikiPageTab.Share.Controls._children"> </code><br />
<code> <Button Id="WikiDocumentExportCustomizationPageView.Button" Command="ExportCurrentWikiDocumentFile2" CommandType="General" Description="Export Wiki-Document" TemplateAlias="o1" Sequence="30" Image32by32="/_layouts/images/wiki/pdf_export.png" LabelText="Export Wiki-Document"/> </code><br />
<code> </CommandUIDefinition> </code><br />
<code> </CommandUIDefinitions> </code><br />
<code> <CommandUIHandlers> </code><br />
<code> <CommandUIHandler Command="ExportCurrentWikiDocumentFile2" CommandAction="javascript:ExportCurrentWikiDocumentFile('{SiteUrl}');"/></code><br />
<code> </CommandUIHandlers> </code><br />
<code> </CommandUIExtension> </code><br />
<code></CustomAction> </code><br />
<br />
Pay attention that this button is only visible to users with contribute-rights on the list.<br />
<i>ExportCurrentWikiDocumentFile </i>is a custom external javascript-function that implements the code behind the button. You must define your own function here...Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-69986306799472761092011-06-24T15:56:00.002+02:002011-06-24T15:58:27.257+02:00Good example for a custom service applicationCheck out chapter 9 of the book <a href="http://www.amazon.de/exec/obidos/asin/0071744568/wwwtotal"> Microsoft SharePoint 2010 Web Applications: The Complete Reference</a>, there is a really good example how to create a custom service application. The described scenario creates a translation service and a webpart that's using it.<br />
<br />
But be aware of a little error on page 199, change this line<br />
<br />
<code>
public string AlternativeLanguage { get; set; }<br />
</code>
<br />
to <br />
<code>[Persisted] private string _alternativeLanguage;<br /><br />public string AlternativeLanguage<br />{<br /> get { return _alternativeLanguage; }<br /> set { _alternativeLanguage = value; }<br />}</code>
<br />
or otherwise no change of the Alternative Language would be stored.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-44198252992301569202011-06-17T15:52:00.001+02:002011-06-17T15:52:46.778+02:00Free alternative for .net Reflector: ILSpyBecause of the fact that the most valueable tool in the SharePoint-World beside SharePoint Manager (I mean our beloved .net Reflector) is no longer free and becomes unsusable after a few weeks until it looks for updates, some resourceful developers started writing an open source equivalent, which can be found at:<br />
<br />
<a href="http://wiki.sharpdevelop.net/ILSpy.ashx">http://wiki.sharpdevelop.net/ILSpy.ashx</a><br />
<br />
I downloaded and tested it already and I think, it's really advanced for the short time elapsed since its development started in february 2011. The look and feel is very similar to .net Reflector and you definitely should give it a try.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-1338945344524496722011-05-02T14:03:00.001+02:002013-04-23T13:28:05.229+02:00CustomAction in ribbonbar doesn't appear for contenttypeRecently I wanted to add a contenttype-specific custom action to the ribbonbar of a document-library. But the button didn't appear. After a short time of verifying and comparing IDs with SharePoint manager, I found the issue: <br />
<br />
GuidGen in Visual Studio created me this GUID: 717EE0C46890438e8E245E7D4B4B7438 which I used for the sitecontenttype inheriting from document (0x010100). Then the list instance creates a listcontenttype from this and appends its own GUID. But the ID from the listcontenttype is 0x010100717EE0C46890438E8E245E7D4B4B743800E57C8E7D4D7D024C9A357907E925F14B.<br />
<br />
So what's the difference between the root? Its the lower case character 'e'. It seems as if SharePoint would have a problem with case-sensitivity. Since I changed the lower 'e' to an upper 'E' in my sitecontenttype and customaction, the button is visible now.<br />
<br />
So please pay attention for lower case characters and replace them when generating Guids with VisualStudio GuidGen.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-73973123487898063012011-03-28T08:27:00.000+02:002013-04-23T13:23:39.670+02:00MCPD: SharePoint Developer 2010 receivedFinally Microsoft sent me a congratulation-mail that says, I'm now MCPD: SharePoint Developer 2010 certified. Cool.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-77653541537335753002011-03-22T08:45:00.001+01:002011-03-22T08:46:31.444+01:00Exam 070-573 passed!I successfully finished this exam yesterday and may entitle myself<a href="http://www.microsoft.com/learning/en/us/exam.aspx?ID=70-573"> TS: Microsoft SharePoint 2010, Application Development</a>. Hooray!<br />
<br />
Although it's commonly said, 070-576 is the more complex exam, I personally felt the TS-exam the harder one.<br />
<br />
<span id="labelCreditCertification"><span class="DetailPagesContentText">Now I'm awaiting for the MCPD: SharePoint Developer 2010 status set by Microsoft...</span></span>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-34006339722282962722011-03-16T16:34:00.000+01:002011-03-16T16:34:44.647+01:00No two choices should have the same IDIn any case avoid create different fields with the same Guid OR - and this is important - the same internal name.<br />
<br />
This is never checked by the solution packaging mechanism or while adding or installing the solution to the solution store. The errormessage "<b>No two choices should have the same ID</b>" occurs, if you for e.g. try to add an existing field to a sharepoint list. <br />
<br />
Be sure to check this from time to time during development-process and before setup your solution to the production server. If the system is up and running, it's very difficult to do changes here...<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8294023985108927448.post-1978399377609676742011-01-14T13:27:00.001+01:002011-01-14T15:52:29.238+01:00Just passed Exam 070-576Yeeehaa, I just passed <a href="http://www.microsoft.com/learning/en/us/exam.aspx?ID=70-576">Microsoft's Exam 070-576</a> (PRO: Designing and Developing Microsoft SharePoint 2010 Applications). <br />
<br />Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-8294023985108927448.post-28642319585125013912010-11-14T16:35:00.008+01:002013-04-23T13:28:20.835+02:00How to use custom form templates in NewForm.aspx/EditForm.aspx<br />
<div class="MsoNormal"><span lang="EN-US">A main criterion that distinguishes websites between good and bad usability is the way, how users can enter data to forms. </span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><span lang="EN-US">Imagine a list with around 15 or more fields. Now a user creates an initial item for that he only enters a few metadata to the item like title, description and a date. After that, another user modifies that item and adds some other field-values. And at last but not least, a third user completes the form by entering all missing values. So you want to show specific fields related to users or roles. Wrap that by a workflow with email-notifications if you want but that’s not the topic of my post. </span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><span lang="EN-US">By default, you have a newform.aspx/editform.aspx that displays all those 15 fields which is not quite necessary for the first user. The second user should not see those metadata-fields the first user entered during initial creation and the last user fills the last values.</span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><span lang="EN-US">Finally you really want to impress your customer so the fields in the form are grouped by context in a multi-columned table and have some stylish images around.</span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><span lang="EN-US">So how would you do that without creating your own applicationpage with onClick-eventhandling on the submit-button and managing saving all the field-values to the item by your own?</span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><span lang="EN-US">“Use custom form templates!” is the answer.</span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><span lang="EN-US">So how do we do that?</span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><span lang="EN-US">At first, it’s important to know that the default-template that’s displayed if you enter the NewForm.aspx or the EditForm.aspx is called <b>ListForm</b> and can be found in 14-Hive\TEMPLATE\CONTROLTEMPLATES\DefaultTemplates.ascx.</span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><span lang="EN-US">In that RenderingTemplate the typical design you know from the xxxForm.aspx is rendered here. Pay attention to the WebControl <b><sharepoint:listfielditerator runat="server"></sharepoint:listfielditerator></b> which renders all visible fields from the list by iterating them. MSDN says you can inherit from the ListFieldIterator and create your own FieldIterator-Class. We don’t want that. We write our own RenderingTemplate.</span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><span lang="EN-US">For this experiment, I created a new Blank Site Collection with english language where I set my upcoming project to. Create a new <b>Empty SharePoint Project</b> in your Visual Studio 2010 and set its destionation Site Url to the just created Site Collection. Now add an item <b>Content Type</b> to your project and set <b>Item</b> as base content type. Now add an item Empty Element named “fields” to that content type.</span></div><br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_ZDJEuA47ktqR76BzWJLhKjlOW3TzWfdjAaqJf8T48o-45KuhfvbjtKEbDJBCWEfiUaJm3muJxdnLE4FVcuKJYtmz4YUAcwrzFwU4mjqdE2KnSlc-CH6GvHaYWKQZlBDENH0BOCXCKH0/s1600/screenshot_custom_forms_contenttype.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_ZDJEuA47ktqR76BzWJLhKjlOW3TzWfdjAaqJf8T48o-45KuhfvbjtKEbDJBCWEfiUaJm3muJxdnLE4FVcuKJYtmz4YUAcwrzFwU4mjqdE2KnSlc-CH6GvHaYWKQZlBDENH0BOCXCKH0/s1600/screenshot_custom_forms_contenttype.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><div class="MsoNormal"><span lang="EN-US">This is our project structure so far</span></div></td></tr>
</tbody></table><div class="MsoNormal"><span lang="EN-US">In its Elements.xml we add some fields that we want to use in our list later:</span></div><div class="MsoNormal"><span lang="EN-US"> <code> </code></span></div><span style="color: blue;"><Elements xmlns="http://schemas.microsoft.com/sharepoint/"></span><br />
<span style="color: blue;"> <Field ID="{42DEFD29-4A11-4fd7-958A-137049381E53}"</span><br />
<span style="color: blue;"> Name="TestTextfeld"</span><br />
<span style="color: blue;"> StaticName="TestTextfeld"</span><br />
<span style="color: blue;"> DisplayName="TestTextfeld"</span><br />
<span style="color: blue;"> Type="Text"/></span><br />
<span style="color: blue;"> <Field ID="{3B6982AF-7B93-4b3c-95BB-3D90E03E30EC}"</span><br />
<span style="color: blue;"> Name="TestDatetime"</span><br />
<span style="color: blue;"> StaticName="TestDatetime"</span><br />
<span style="color: blue;"> DisplayName="TestDatetime"</span><br />
<span style="color: blue;"> Format="DateOnly"</span><br />
<span style="color: blue;"> Type="MyDateTimeField"/></span><br />
<span style="color: blue;"> <Field ID="{B3C1A58F-9583-410d-BA4B-5545E37565F1}"</span><br />
<span style="color: blue;"> Name="TestBoolean"</span><br />
<span style="color: blue;"> StaticName="TestBoolean"</span><br />
<span style="color: blue;"> DisplayName="TestBoolean" </span><br />
<span style="color: blue;"> Type="Boolean"/></span><br />
<span style="color: blue;"> <Field ID="{273D7F41-BB9D-4537-AF66-477A0FA09CC9}"</span><br />
<span style="color: blue;"> Name="TestChoice"</span><br />
<span style="color: blue;"> StaticName="TestChoice"</span><br />
<span style="color: blue;"> DisplayName="TestChoice"</span><br />
<span style="color: blue;"> Type="Choice"></span><br />
<span style="color: blue;"> <CHOICES></span><br />
<span style="color: blue;"> <CHOICE>1</CHOICE></span><br />
<span style="color: blue;"> <CHOICE>2</CHOICE></span><br />
<span style="color: blue;"> <CHOICE>3</CHOICE></span><br />
<span style="color: blue;"> </CHOICES></span><br />
<span style="color: blue;"> </Field></span><br />
<span style="color: blue;"> <Field ID="{EB57DC41-A510-442a-83DE-09D01462914E}"</span><br />
<span style="color: blue;"> Name="TestUserField"</span><br />
<span style="color: blue;"> StaticName="TestUserField"</span><br />
<span style="color: blue;"> DisplayName="TestUserField"</span><br />
<span style="color: blue;"> Type="User"/></span><br />
<span style="color: blue;"></Elements></span><br />
<span lang="EN-US">After that, reference those fields in your ContentType. Your Elements.xml now should look like this:</span><br />
<code></code><br />
<span style="color: blue;"><Elements xmlns="http://schemas.microsoft.com/sharepoint/"></span><br />
<span style="color: blue;"> <!-- Parent ContentType: Item (0x01) --></span><br />
<span style="color: blue;"> <ContentType ID="0x01000db7705609a14adeacf933a7ce690bb8"</span><br />
<span style="color: blue;"> Name="SharePointProject1 - ContentType1"</span><br />
<span style="color: blue;"> Group="Custom Content Types"</span><br />
<span style="color: blue;"> Description="My Content Type"</span><br />
<span style="color: blue;"> Inherits="FALSE"</span><br />
<span style="color: blue;"> Version="0"></span><br />
<span style="color: blue;"> <FieldRefs></span><br />
<span style="color: blue;"> <FieldRef ID="{42DEFD29-4A11-4fd7-958A-137049381E53}" Name="TestTextfeld"/></span><br />
<span style="color: blue;"> <FieldRef ID="{3B6982AF-7B93-4b3c-95BB-3D90E03E30EC}" Name="TestDatetime"/></span><br />
<span style="color: blue;"> <FieldRef ID="{B3C1A58F-9583-410d-BA4B-5545E37565F1}" Name="TestBoolean"/></span><br />
<span style="color: blue;"> <FieldRef ID="{273D7F41-BB9D-4537-AF66-477A0FA09CC9}" Name="TestChoice"/></span><br />
<span style="color: blue;"> <FieldRef ID="{EB57DC41-A510-442a-83DE-09D01462914E}" Name="TestUserField"/></span><br />
<span style="color: blue;"> </FieldRefs> </span><br />
<span style="color: blue;"> </ContentType></span><br />
<span style="color: blue;"></Elements> </span><br />
<br />
<span lang="EN-US">Now comes the cool part: after the closing </FieldRef>-Tag add this xml-snippet:</span><br />
<code></code><br />
<span style="color: blue;"><XmlDocuments></span><br />
<span style="color: blue;"> <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms"></span><br />
<span style="color: blue;"> <FormTemplates xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms"></span><br />
<span style="color: blue;"> <Display>ListForm</Display></span><br />
<span style="color: blue;"> <Edit>CType1CustomForm</Edit></span><br />
<span style="color: blue;"> <New>CType1CustomForm</New></span><br />
<span style="color: blue;"> </FormTemplates></span><br />
<span style="color: blue;"> </XmlDocument></span><br />
<span style="color: blue;"> </XmlDocuments> </span><br />
<div class="MsoNormal"><br />
</div><div class="MsoNormal"><span lang="EN-US">CType1CustomForm is the new RenderingTemplate we want to use for edit and new. Display we do ignore for the moment; show the item in the default way by <b>ListForm</b>. It’s important to set the <b>Inherits</b>-Attribute to FALSE or the custom form templates are ignored, no matter, what you enter here. If you need to inherit from another content type, you also can set the formTemplates by code, for e.g. in a Feature Receiver:</span></div><div class="MsoNormal"><span lang="EN-US"><code></code></span></div><div class="MsoNormal" style="color: blue;"><span lang="EN-US">SPContentType ctype = spWeb.ContentTypes[new SPContentTypeId("0x01000db7705609a14adeacf933a7ce690bb8")];<br />
<br />
ctype.NewFormTemplateName = "CType1CustomForm";<br />
ctype.EditFormTemplateName = "CType1CustomForm";<br />
<br />
ctype.Update(true);</span></div><div class="MsoNormal"><span lang="EN-US"></span></div><div class="MsoNormal"><br />
<span lang="EN-US">Pay attention that the approach of setting custom templates to each content types makes it possible to individualize the form for every content type in your list. No more inappropriate fields. :-)</span><br />
<br />
<span lang="EN-US">So now it’s time to create the Template. Add a new <b>SharePoint Mapped Folder</b> and set it to {SharePointRoot}\TEMPLATE\CONTROLTEMPLATES. </span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">Add a new User Control to this folder and remove its .cs-Files. In my example, I named it CType1CustomForm.ascx. From the SharePoint DefaultTemplate.ascx (found in </span><span lang="EN-US">14-Hive\TEMPLATE\CONTROLTEMPLATES</span><span lang="EN-US">) I copied that Part beginning with <b><SharePoint:RenderingTemplate id="ListForm" runat="server"></b> and ending with <b></SharePoint:RenderingTemplate></b> <sharepoint:renderingtemplate id="”ListForm”"> into the new user control. </sharepoint:renderingtemplate></span><br />
<br />
<span lang="EN-US"><sharepoint:renderingtemplate id="”ListForm”">To proof, that now this Template is used by our content type, I </sharepoint:renderingtemplate></span><span lang="EN-US">added the Term “<b>CType1CustomForm</b>” after the <span id='part1'>-<span id="’part1’">Tag which is displayed first in the dialog’s contentarea.</span></span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><span lang="EN-US">Add a list definition of type custom with list instance to your VS2010 project. Add a contenttype-reference and copy the field-elements to the schema.xml. If you want, you can add some demo-data to the data-section of the listinstance like this:</span><br />
<span lang="EN-US"></span><code></code><br />
<span lang="EN-US" style="color: blue; font-family: Consolas; font-size: 9.5pt;"> <ListInstance Title="SharePointProject1 - ListInstance1"<br />
OnQuickLaunch="TRUE"<br />
TemplateType="10000"<br />
Url="Lists/SharePointProject1-ListInstance1" <br />
Description="My List Instance"><br />
<Data><br />
<Rows><br />
<Row><br />
<Field Name="TestTextfeld">Text im Textfeld</Field><br />
<Field Name="TestDatetime">2010-10-28T11:00:00Z</Field><br />
</Row><br />
</Rows><br />
</Data><br />
</ListInstance></span><span lang="EN-US" style="font-family: Consolas; font-size: 9.5pt;"></span> <br />
<div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">If you want, you can test the progress so far by pressing F5 and click “Add new item” in the list. You should see something like this:</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
<span lang="EN-US"></span></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0cJfIOEMKHWpK4HL90xIbHxZbQvILgNKtyrqg62Utv7Nuw95uwiCBiUWYzpQru0YR6FHIanr2yxtldJNOs0QhJ_YY1uQXP64SjQkKiHBVGeQKs6M8AfHlYBqjqZYXK3Y_GKF-b1VODIA/s1600/screenshot_custom_forms_template_part_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0cJfIOEMKHWpK4HL90xIbHxZbQvILgNKtyrqg62Utv7Nuw95uwiCBiUWYzpQru0YR6FHIanr2yxtldJNOs0QhJ_YY1uQXP64SjQkKiHBVGeQKs6M8AfHlYBqjqZYXK3Y_GKF-b1VODIA/s1600/screenshot_custom_forms_template_part_1.png" /></a></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
<span lang="EN-US"></span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">Okay, the half of the job is done. Now we want to rearrange the lame display of the fields.</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">For that purpose, add another User Control to the mapped CONTROLTEMPLATES-folder but this time leave all the automatically created Code-Behind-Files. In my case, I named it MyCustomForm.ascx.</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><span lang="EN-US">By default the <sharepoint:listfielditerator> displays all contenttype-fields, that may be displayed in this form and that are not yet added to the form. So we include our own User Control right before the <sharepoint:listfielditerator><SharePoint:ListFieldIterator> -Tag in the CType1CustomForm.ascx:</sharepoint:listfielditerator></span><br />
<span lang="EN-US"></span><code></code><br />
<div style="color: blue;"><SharePoint:FolderFormFields ID="FolderFormFields1" runat="server"/><br />
<br />
<!-- myCustomForm --><br />
<myCustomForm:AddForm runat="server" /><br />
<!-- myCustomForm --><br />
<br />
<SharePoint:ListFieldIterator ID="ListFieldIterator1" runat="server"/></div><br />
<div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">Don’t forget to register the tag in the directives-area:</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US"><code></code></span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US"><span style="color: blue;"><%@ Register TagPrefix="myCustomForm" TagName="AddForm" src="~/_controltemplates/MyCustomForm.ascx" %></span> </span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US"> </span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">All the fields, which are added in MyCustomForm.ascx will not be rendered by the ListFieldIterator again. But if your customer adds new fields to the list after you installed the solution, those new fields are rendered fine like the default-forms below your customizations.</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">Now let’s come to the MyCustomForm.ascx. </span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">In this User template, I created a HTML-Table where I placed all the SharePoint-WebControls to render the fields, for e.g:</span></div><br />
<code></code><br />
<span style="color: blue;"><table width="700px"> </span><br />
<span style="color: blue;"> <tr></span><br />
<span style="color: blue;"> <td></span><br />
<span style="color: blue;"> <asp:Label ID="Label5" runat="server" Text="Title" /></span><br />
<span style="color: blue;"> </td></span><br />
<span style="color: blue;"> <td></span><br />
<span style="color: blue;"> <SharePoint:TextField ID="Title" runat="server" FieldName="Title" /></span><br />
<span style="color: blue;"> </td></span><br />
<span style="color: blue;"> <td> </span><br />
<span style="color: blue;"> </td></span><br />
<span style="color: blue;"> <td></span><br />
<span style="color: blue;"> <asp:Panel ID="bild" runat="server"></asp:Panel></span><br />
<span style="color: blue;"> </td></span><br />
<span style="color: blue;"> </tr></span><br />
<span style="color: blue;"> <tr> </span><br />
<span style="color: blue;"> <td></span><br />
<span style="color: blue;"> <asp:Label ID="Label1" runat="server" Text="Textfeld" /></span><br />
<span style="color: blue;"> </td></span><br />
<span style="color: blue;"> <td></span><br />
<span style="color: blue;"> <SharePoint:TextField ID="TextField1" runat="server" FieldName="TestTextfeld" /></span><br />
<span style="color: blue;"> </td> </span><br />
<span style="color: blue;"> <td></span><br />
<span style="color: blue;"> <asp:Label ID="Label2" runat="server" Text="Datetime" /></span><br />
<span style="color: blue;"> </td></span><br />
<span style="color: blue;"> <td> </span><br />
<span style="color: blue;"> <SharePoint:DateTimeField ID="DateTimeField1" runat="server" FieldName="TestDatetime" /> </span><br />
<span style="color: blue;"> </td></span><br />
<span style="color: blue;"> </tr> </span><br />
<span style="color: blue;"> <tr> </span><br />
<span style="color: blue;"> <td></span><br />
<span style="color: blue;"> <asp:Label ID="Label6" runat="server" Text="Userfeld" /></span><br />
<span style="color: blue;"> </td></span><br />
<span style="color: blue;"> <td></span><br />
<span style="color: blue;"> <SharePoint:UserField ID="UserField" runat="server" FieldName="TestUserField" /></span><br />
<span style="color: blue;"> </td> </span><br />
<span style="color: blue;"> <td></td> </span><br />
<span style="color: blue;"> <td></td></span><br />
<span style="color: blue;"> </tr> </span><br />
<span style="color: blue;"> <tr></span><br />
<span style="color: blue;"> <td></span><br />
<span style="color: blue;"> <asp:Label ID="Label3" runat="server" Text="Boolean"/></span><br />
<span style="color: blue;"> </td></span><br />
<span style="color: blue;"> <td></span><br />
<span style="color: blue;"> <SharePoint:BooleanField runat="server" FieldName="TestBoolean" ID="booleanField" /> (Check this box to see more settings)</span><br />
<span style="color: blue;"> </td></span><br />
<span style="color: blue;"> <asp:TableCell ID="choiceLabel" runat="server"></span><br />
<span style="color: blue;"> <asp:Label ID="Label4" runat="server" Text="Choice"/></span><br />
<span style="color: blue;"> </asp:TableCell></span><br />
<span style="color: blue;"> <asp:TableCell ID="choiceField" runat="server"></span><br />
<span style="color: blue;"> <SharePoint:RadioButtonChoiceField ID="RadioButtonChoiceField1" runat="server" FieldName="TestChoice" /></span><br />
<span style="color: blue;"> </asp:TableCell></span><br />
<span style="color: blue;"> </tr> </span><br />
<span style="color: blue;"></table></span> <br />
<br />
<div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">As you can see, it’s quite simple to add the field controls. It’s important, to set the correct FieldName. If the FieldName-Values doesn’t match the internal fieldnames, SharePoint can’t map them and displays the control by the ListFieldIterator instead of your code.</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">You can also use your own custom fields here. To demonstrate, I created a new custom field by inheriting from the default DateTime-field to show the user an error-message, if the entered date is lower than the current date. Because my custom field inherits from SPFieldDateTime, I can display it by using </span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US"><code></code></span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US"></span><span lang="EN-US" style="color: blue; font-family: Consolas; font-size: 9.5pt;"><SharePoint:DateTimeField ID="DateTimeField1" runat="server" FieldName="TestDatetime" /></span><span lang="EN-US" style="font-family: Consolas; font-size: 9.5pt;"></span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US" style="font-family: Consolas; font-size: 9.5pt;"><span style="color: blue;"></span></span><span lang="EN-US"> </span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">In the wired CodeBehind I added some functionality to toggle the visibility of the radiobuttons-field depending on the checkbox-state. Don’t be worried, to provide you a sum of all the written above, I attach the sourcecode for download below.</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">Following a picture of the final result:</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN6Dw8j1_l6sgP6bVXGC2qMd-lbVmR_bs6QfcbbCpdUp1t2NOMdHD90UNTZhDOYizD6hrpfbnogC3sOfyQ8u_mIBPXMuj9brg-bOkgopF43PAUfrErifpkbQtTYVKydx6dv6HanJl7IwY/s1600/screenshot_custom_forms_result.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="321" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN6Dw8j1_l6sgP6bVXGC2qMd-lbVmR_bs6QfcbbCpdUp1t2NOMdHD90UNTZhDOYizD6hrpfbnogC3sOfyQ8u_mIBPXMuj9brg-bOkgopF43PAUfrErifpkbQtTYVKydx6dv6HanJl7IwY/s640/screenshot_custom_forms_result.png" width="640" /></a></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US"></span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">As you can see, the content of the NewForm/EditForm is completely different from the default-style. As I described earlier, the ListFieldIterator adds new not referenced fields below until you update the user control:</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBHmutvI4mCaz1e9M5ugf-rR1OqDm_s2i48J0VObRwIoarhF2ulCayVYeevNr5gGpgR1RB6Y-GnlVugg-QfPe9hI4k659aQirD4HbyeFkE9sxf_iki7vnI-Nj1NFT8QQ-5rYnXFP-Py0I/s1600/screenshot_custom_forms_result_new_field.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBHmutvI4mCaz1e9M5ugf-rR1OqDm_s2i48J0VObRwIoarhF2ulCayVYeevNr5gGpgR1RB6Y-GnlVugg-QfPe9hI4k659aQirD4HbyeFkE9sxf_iki7vnI-Nj1NFT8QQ-5rYnXFP-Py0I/s1600/screenshot_custom_forms_result_new_field.png" /></a></div><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFPKqFs19q0_vymOz9q-IJzf9VJO4E_zfYdGsP5wEU6lYNicykhs-OB-sQRAYqJ8RGfCjOr_YSZX3J_vJqoyrloP5aQ2lHqiJv9eq5W7_3A22bDw7mbFpl8ZyxOcEsVrtI2g1c-CbeTb0/s1600/screenshot_custom_forms_result_new_field.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US"></span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">Hint: If you get an exception during F5-debugging when you entered an invalid date, like you can see on the following screen, just ignore it by hitting the run-button. It seems like this way (throwing an exception on field-validation) is the Microsoft-preferred way to handle invalid field-values:</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLXB9Rlcc-R75o_xDQjJtjQNajcGhMOwkgp9W4qrvgZdXU436RoQ36zKBfcpAByCKOENxa_hAfvY7_zn1kqjiAjBSIF35MoqerxB5Vaqhr4z5ja4ABmg3I3yorA6M8abSU7nxCIBtyhQg/s1600/screenshot_custom_forms_exception_during_debugging.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLXB9Rlcc-R75o_xDQjJtjQNajcGhMOwkgp9W4qrvgZdXU436RoQ36zKBfcpAByCKOENxa_hAfvY7_zn1kqjiAjBSIF35MoqerxB5Vaqhr4z5ja4ABmg3I3yorA6M8abSU7nxCIBtyhQg/s1600/screenshot_custom_forms_exception_during_debugging.png" /></a></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">The exception-message is the red-displayed error-message below the validated field.</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">The complete Visual Studio-Project can be downloaded from codeplex (my first codeplex-project, yehaa!): <a href="http://customformtemplates.codeplex.com/">http://customformtemplates.codeplex.com </a></span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">I hope, you’ll find this design-possibility as much as useful and exciting as I did when I discovered it.</span></div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><br />
</div><div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"><span lang="EN-US">Happy coding!</span></div>Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-8294023985108927448.post-2627256759302074782010-11-11T16:22:00.000+01:002013-04-23T13:24:02.633+02:00ExcelServices "You do not have permissions to open this file."Today I spent hours to solve a problem most annoying. I walked through Microsoft's tutorial you can find <a href="http://msdn.microsoft.com/en-us/library/ms519100.aspx">here</a> how to use SharePoint 2010 Excel Services to open an Excelsheet uploaded to a SharePoint-Library.<br />
<br />
I implemented the not really complex example with the result... that nothing worked like expected. Always when the debugger was in the line of <i>sessionId = es.OpenWorkbook(...)</i>, I've got an exception with the nothing-telling message "You do not have permissions to open this file.".<br />
<br />
So I searched for solutions and hints at Google but all those tips there (change Excel Service Application-Settings, modify Trusted Locations, etc.) didn't work.<br />
<br />
At last I tried something, I had in mind all the time but somehow it was too obvious that it wouldn't be the solution for my problem. And ha! As I tried anyway just for fun, it suddenly <b>worked</b>.<br />
All I did, was to change the <b>Location Type</b> for my library in which the excel was uploaded to "HTTP". All the time before it didn't worked, this setting for here was "Microsoft SharePoint Foundation".<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbxJy1acq1jHJOPhyphenhyphenarKhj_tqTuOY9AFGf4vFcK_uVmhKhLhZjSCBU0QLHsi5EOJuATTkm-T2lq-_E9JI0l6fdcW2oPjA8W9LWzrctXh9_hbx3J7YFkLH5HiESVTUr4GtBIt1rVpsGPQY/s1600/screenshot_trusted_locations_excel_service.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbxJy1acq1jHJOPhyphenhyphenarKhj_tqTuOY9AFGf4vFcK_uVmhKhLhZjSCBU0QLHsi5EOJuATTkm-T2lq-_E9JI0l6fdcW2oPjA8W9LWzrctXh9_hbx3J7YFkLH5HiESVTUr4GtBIt1rVpsGPQY/s1600/screenshot_trusted_locations_excel_service.png" /></a></div><br />
Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-8294023985108927448.post-32317659298882669002010-11-09T10:51:00.002+01:002012-11-15T15:24:11.555+01:00Dilbert @ SharePointSimply great! <br />
<br />
<div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0NqlPg0lx4OAAE9v8MLsMO87mKKn-g5mueMLezzDDLyUF95H3zsumY1q8Cen8TeVPqRkzAqu_A3zIjz35CGKQYbkIk3oirMZUG_P8PqWUYLbGiGrTPCxTYB5Q6Dp9bi8Av7kvaR9-JA0/s1600/dilbert@sharepoint.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0NqlPg0lx4OAAE9v8MLsMO87mKKn-g5mueMLezzDDLyUF95H3zsumY1q8Cen8TeVPqRkzAqu_A3zIjz35CGKQYbkIk3oirMZUG_P8PqWUYLbGiGrTPCxTYB5Q6Dp9bi8Av7kvaR9-JA0/s1600/dilbert@sharepoint.png" /></a></div><br />
Found at <a href="http://sptechblog.wordpress.com/">http://sptechblog.wordpress.com/</a>Unknownnoreply@blogger.com0