tag:blogger.com,1999:blog-88884501656422317452024-03-13T19:35:07.356+00:00Howard's SharePoint FarmA SharePoint blog - hopefully you can find some helpful info here.Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.comBlogger44125tag:blogger.com,1999:blog-8888450165642231745.post-59355381101857624342014-06-20T16:28:00.001+01:002014-06-27T17:07:40.993+01:00SharePoint Web Part "No item exists at" I've just started using SharePoint Online (part of Office 365).<br />
<br />
<br />
I'm creating an Intranet using Publishing Pages. Most of the pages are using the Welcome Links page layout.
On some of the pages, I wanted to add a List View Web Part (supplied with SharePoint).
I could add these to the page. However, when I selected "Edit Web Part" I saw the following SharePoint error:<br />
<br />
<br />
<strong>No item exists at https://sitename/OpsManagement/Pages/default.aspx?Filter=1&FilterOnly=1&List={7B611D12-3559-4F60-9B6B-265CA420177B}. It may have been deleted or renamed by another user.</strong><br />
<br />
<br />
After some trial-and-error, I noticed that this issue does not occur if the page is using the Blank Web Part page layout. Note that this page layout does not render the Publishing Image field.<br />
<br />
<br />
My conclusion is that the issue is caused by a conflict between the Publishing Image field (rendered by the Welcome Links layout) and the List View Web Part.<br />
<br />
<br />
(Maybe this is due to the new image rendition functionality?)<br />
<br />
<br />
I've raised a ticket with Microsoft support and will report back any findings.
<br />
<br />
<span style="background-color: yellow;">Update 26/06/2014</span>
<br />
Microsoft accepts that this is a bug and is working on a fix. No indication of when this will be resolved. I'll provide another update when it is.
<br />
<br />
<span style="background-color: yellow;">Update 27/06/2014</span>
<br />
Just finished a call with Microsoft. It would appear the problem has now been fixed as part of a different ticket.
Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com5tag:blogger.com,1999:blog-8888450165642231745.post-79461523315562130352013-02-27T12:03:00.001+00:002013-02-27T12:03:44.987+00:00SharePoint "Managed Navigation" visitors<p>Is your Managed Navigation not showing / hidden? If so read on...</p>
<p>SharePoint 2013 includes Managed Navigation. I used this to setup some basic navigation
but found that, when logged-in as a visitor, the navigation disappears.</p>
<p>I came across this page - "<a href="http://social.msdn.microsoft.com/Forums/en-US/sharepointcustomization/thread/1ef8f793-0af2-4064-9b08-d690d97e1256/">Managed navigation not visible to Readers</a>" - which said "navigation nodes which do not have a page will not be shown to Readers".</p>
<p>To implement this fix, for each term (in your Managed Navigation Term set) you can :</p>
<ol>
<li>On the "NAVIGATION" tab, change the "Navigation Node Type" to "Simple Link" and specify a page url, or</li>
<li>On the same tab, change the "Navigation Node Type" to "Term-Driven Page with Friendy URL" and then, on the "TERM-DRIVEN PAGES" tab, change the target page for the term to a page url.</li>
</ol>
Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com1tag:blogger.com,1999:blog-8888450165642231745.post-56767300178337010702012-07-03T08:50:00.001+01:002012-07-03T08:50:31.897+01:00SharePoint ItemAdded OpenBinary Zero<p>I created an ItemAdded event receiver for a document library. This sets metadata values for an uploaded file. Everything worked well for documents added using SharePoint's single, or multiple file upload forms.</p>
<p>However, when using Windows Explorer to upload a file to the library, I found that a call to the OpenBinary method for the file returned a zero length byte array.</p>
<p>In fact the wider issue was that the length of the file object was zero. Here's some skeleton code:</p>
<p>
<code style="font-size:8pt">
public override void ItemAdded(SPItemEventProperties properties)<br/>
{<br/>
long length = properties.ListItem.File.Length; // zero<br/>
}<br/>
</code>
</p>
<p>Other people that have found the same issue suggest using Thread.Sleep() in the event receiver to add an artifical delay.</p>
<p>However, I chose to work around this issue another way:</p>
<ol>
<li>In the ItemAdded receiver, do a check for a zero length file. Don't do any processing if it is zero. Obviously this won't work for a file uploaded using Windows Explorer. So I also needed to...</li>
<li>Add an ItemUpdated event receiver (which just so happens to called when a user uploads a file using Windows Explorer.</li>
<li>Both receivers call some shared code which updates the file's metadata. However, to avoid this being done multiple times, the shared code runs a check to verify that the metadata is blank before it is set.</li>
</ol>
</p>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-23209085417626442972012-06-27T09:01:00.000+01:002012-06-27T09:01:07.105+01:00SharePoint Index Music<p>I'm storing music tracks in a SharePoint Foundation 2010 library. I want users to be able to search for tracks using music file metadata e.g. Track Name. Artist, Album, Lyrics, etc.</p>
<p>This metadata is stored within popular music file types (e.g. mp3, wma, ogg, etc); though the format of the metadata varies. So how can SharePoint index these files and extract the metadata? You have a number of options:</p>
<ol>
<li>Install FAST Search Server 2010 and the "Advanced Filter Pack", which can index <strong>certain</strong> music file types.</li>
<li>Install a 3rd party IFilter, which knows how to index your music files. You'll probably need one IFilter for each specific media file type.</li>
<li>Develop your own music file IFilter. This should be written in C++ and it's not an easy exercise - believe me; I've tried.</li>
<li>Expose the music file metadata through the standard SharePoint user interface.</li>
</ol>
<p>I went for option (4), but it does require some development knowledge, and the use of a 3rd party .Net library called "taglib-sharp". In essence you create a SharePoint Event Receiver that fires whenever a music file is added to a library. The Receiver then uses "taglib-sharp" to extract metadata from the file and copy it to custom SharePoint metadata.</p>
<p>The picture below shows the custom SharePoint metadata, extracted from an .mp3 file:</p>
<a href="http://2.bp.blogspot.com/-R3pNGPIJxWc/T-q9Xhq_LaI/AAAAAAAAARo/QOc1Vwm4iYU/s1600/SharePoint%2Bmusic%2Bfile.bmp" imageanchor="1" style=""><img border="0" height="215" width="320" src="http://2.bp.blogspot.com/-R3pNGPIJxWc/T-q9Xhq_LaI/AAAAAAAAARo/QOc1Vwm4iYU/s320/SharePoint%2Bmusic%2Bfile.bmp" /></a>
<p>The SharePoint indexer can now index the custom metadata, which you can then use in custom searches.</p>
<p>Two great things about taglib-sharp:</p>
<ol>
<li>It can be called from .Net and is easy to use - you just point it directly at a file in the SharePoint library.</li>
<li>It supports the following music file formats: wma, aiff, asf, mp3, m4a, mpeg, ogg, riff, aac, ape, flac, Musepack and WavPack.</li>
</ol>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-39565750845407647052012-06-21T11:39:00.000+01:002012-06-21T11:42:58.765+01:00TagLib Stream Buffer<p>Do you want to load TagLib mp3 properties from a buffer or stream?</p>
<p>As I write this, the latest version in the TagLib Master branch on <a href="https://github.com/taglib/taglib">GitHub </a>supports this.</p>
<p>Here's some C++ code that I've hacked together to do it - thanks to Lukáš Lalinský for his help.</p>
<p>Note that I'm not a C++ Developer ;)</p>
<p>I need to use C++ in this instance as I'm working on a project that cannot use the .Net framework - more in a later post.</p>
<br />
<code style="font-size:9pt">
// Load a sample track into a stream.
std::ifstream is("Track1.mp3");<br />
<br />
if (!is.bad())<br />
{<br />
// Calculate the size of the stream.<br />
long l = is.tellg();<br />
is.seekg (0, ios::end);<br />
long m = is.tellg();<br />
is.seekg (0, ios::beg);<br /><br />
long diff = (m - l);<br /><br />
// Save the stream to a buffer.<br />
char* buffer = new char[diff];<br />
is.read(buffer, diff);<br /><br />
ByteVector v(buffer, diff);<br />
TagLib::IOStream* stream = new TagLib::ByteVectorStream(v);<br /><br />
TagLib::ID3v2::FrameFactory *frameFactory = TagLib::ID3v2::FrameFactory::instance();<br />
TagLib::MPEG::File* mpegFile =new TagLib::MPEG::File (stream,frameFactory,true,TagLib::AudioProperties::Accurate);<br /><br />
TagLib::FileRef* f = new TagLib::FileRef(mpegFile);<br /><br />
cout << f->tag()->title() << endl;<br />
cout << mpegFile->ID3v1Tag()->artist() << endl;<br /><br />
is.close();<br />
}
</code>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-90427321097509027332012-06-18T16:19:00.001+01:002012-06-18T16:19:19.474+01:00SharePoint check user in group<p>I created some code to check if the current user belonged to a specific SharePoint group, similar to this:</p>
<code>
SPUser user = SPContext.Current.Web.CurrentUser;<br/><br/>
foreach (SPGroup group in user.Groups)<br/>
{<br/>
if (group.Name == [INSERT YOUR GROUP NAME HERE)<br/>
{<br/>
}<br/>
}<br/>
</code>
<p>This worked when users were directly added to the SharePoint group. However, it did not work if they were part of an AD group, which was then added to the SharePoint group.</p>
<p>To fix the issue, I used code similar to this:</p>
<code>
SPGroupCollection groups = SPContext.Current.Site.RootWeb.Groups;<br/>
bool inGroup = groups[INSERT YOUR GROUP NAME HERE].ContainsCurrentUser;<br/>
</code>
<p></p>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-47062952565218894812012-06-14T09:08:00.000+01:002012-06-14T09:08:45.612+01:00SharePoint "Crawled Properties" FilenameI have a document library that contains audio files (mp3, wma, etc). When I search the site, the results contain links to the library's DispForm.aspx. This is expected as I haven't installed an iFilter for the audio file types.
However, I wanted to be able to get at the Name property (highlighted in the image below), which is the filename of the media file:
<br/><br/>
<a href="http://4.bp.blogspot.com/-1Q1s-5PoPJU/T9mXlHZ4MNI/AAAAAAAAARI/r6G-PRr3UJo/s1600/DispForm.png" imageanchor="1" style=""><img border="0" height="191" width="320" src="http://4.bp.blogspot.com/-1Q1s-5PoPJU/T9mXlHZ4MNI/AAAAAAAAARI/r6G-PRr3UJo/s320/DispForm.png" /></a>
<br/><br/>
To do this, I had to:
<ol>
<li>Include values from the crawled property "ows_FileLeafRef" in the index.</li>
<li>Create a mapping to a managed property</li>
</ol>
These are shown below:
<br/><br/>
<a href="http://3.bp.blogspot.com/-P8M3_D259X8/T9mZB_6g7qI/AAAAAAAAARU/96YNDZ44EAg/s1600/Properties.png" imageanchor="1" style=""><img border="0" height="246" width="320" src="http://3.bp.blogspot.com/-P8M3_D259X8/T9mZB_6g7qI/AAAAAAAAARU/96YNDZ44EAg/s320/Properties.png" /></a>
<br/><br/>
The platform was a single-server farm, using SharePoint Foundation 2010 and Search Server Express 2010.Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-49121036654910042122012-06-08T08:23:00.002+01:002012-06-08T08:27:44.399+01:00WMPLib Artist Blank<p>I'm using SharePoint to host music tracks, which I play with Windows Media Player (WMP).</p>
<p>The player is controlled via WMPLib - Microsoft's WMP API.</p>
<p>I found that I can add SharePoint music files to a WMP playlist via the API, and that the tracks are played. However, when I wanted to display information about the current track (track name, artist, duration, etc), I found that the artist property was empty.</p>
<p>I discovered the fix for this was to URL encode the URL of the track (as it exists in SharePoint) before adding it to the playlist. This was because the track URLs contained spaces (and potentially other odd characters).<p>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-10604244033684400612012-06-06T09:08:00.000+01:002012-06-08T08:40:13.332+01:00SharePoint mp3 Headers<p>Music tracks include header information such as artist, album, duration, etc</p>
<p>In SharePoint Foundation 2010, I wanted to extract this header data and use it to populate library metadata.</p>
<p>To do this, I first downloaded <a href="http://www.novell.com/products/linuxpackages/opensuse11.1/taglib-sharp.html">TagLib</a>.</p>
<p>The clever bit about TagLib is that you can create your own SharePoint-specific implementation of the TagLib.File.IFileAbstraction interface. I then used this in a SharePoint event receiver to extract the header data when a user uploads a music file.</p>
<p>Note that this works for other types of music tracks, not just mp3.</p>
<p>The following code shows the code I created for a class that implements IFileAbstraction:</p>
<br />
<code style="font-size:8pt">
using System;<br />
using System.Collections.Generic;<br />
using System.Linq;<br />
using System.Text;<br />
using System.IO;<br />
using Microsoft.SharePoint;<br /><br />
namespace Redweb.Redio.Audio<br />
{<br />
public class SharePointMediaFile : TagLib.File.IFileAbstraction<br />
{<br />
private string _fileUrl = String.Empty;<br /><br />
public string FileUrl<br />
{<br />
get<br />
{<br />
return _fileUrl;<br />
}<br />
set<br />
{<br />
_fileUrl = value;<br />
}<br />
}<br /><br />
void TagLib.File.IFileAbstraction.CloseStream(System.IO.Stream stream)<br />
{<br />
if (stream == null)<br />
throw new ArgumentNullException("stream");<br />
stream.Close();<br />
}<br /><br />
string TagLib.File.IFileAbstraction.Name<br />
{<br />
get { return _fileUrl; }<br />
}<br /><br />
System.IO.Stream TagLib.File.IFileAbstraction.ReadStream<br />
{<br />
get<br />
{<br />
MemoryStream outputSteam = null;<br />
using (SPSite site = new SPSite(_fileUrl))<br />
{<br />
using (SPWeb web = site.OpenWeb())<br />
{<br />
if ((web == null) || (web.Exists == false))<br />
{<br />
throw new Exception("No web exists.");<br />
}<br />
SPFile file = web.GetFile(_fileUrl);<br />
if ((file == null) || (file.Exists == false))<br />
{<br />
throw new Exception("No file exists.");<br />
}<br />
byte[] bytes = file.OpenBinary();<br />
outputSteam = new MemoryStream(bytes);<br />
}<br />
}<br /><br />
return outputSteam;<br />
}<br />
}<br /><br />
System.IO.Stream TagLib.File.IFileAbstraction.WriteStream<br />
{<br />
get { throw new NotImplementedException(); }<br />
}<br />
}<br />
}<br />
</code>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-67439854261041669592012-01-05T09:45:00.005+00:002012-06-08T08:24:20.575+01:00SharePoint StackoverflowI've recently started to answer SharePoint questions on Stackoverflow / Stackexchange . Hopefully I'll be able to help out some people.<br /><br />Here are my blog posts related to <a href="http://spfarm.blogspot.com/search/label/Development">SharePoint development</a>. I also design and build SharePoint server farms. You can find my configuration posts <a href="http://spfarm.blogspot.com/search/label/Installation">here</a>.<br /><br />Cheers<br />HowardHowardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-58638814027914959082011-12-05T09:39:00.025+00:002011-12-06T08:07:13.104+00:00SharePoint Radio StationWe turned SharePoint 2010 into a "Radio Station". Dan Haywood (Microsoft) writes: "<em><strong>This is probably one of the most impressive solutions I have ever seen built on SharePoint 2010</strong></em>"...<br /><br />My company, <a href="http://www.redweb.com">Redweb</a>, gives each team the opportunity to work on a Hack Project. We have 33 hours to conceive, build and present an innovative piece of work.<br /><br />My team choose to create "Redio", a coroporate radio station that allows companies to play and stream live music across the Enterprise. In a nutshell, the solution included:<br /><br />* Playlist creation - a user can select tracks from Spotify<br />* Scheduling of Playlists<br />* Ability to add adverts and "sweepers"<br />* Streaming of Spotify tracks from a central server to satellite PCs<br />* Streaming directly to client machines<br /><br />The project was challenging enough; but we also needed to present to Microsoft. We did this via Lync and anyone from the Microsoft network could see what we did.<br /><br />Full review by Dan Haywood: <a href="http://www.danhaywoodblog.com/2011/12/redweb-hack-day-produces-sharepoint-fis.html">http://www.danhaywoodblog.com/2011/12/redweb-hack-day-produces-sharepoint-fis.html</a><br /><br />Video of presentation: <a href="https://skydrive.live.com/redir.aspx?cid=9b7d796bd3e9e65c&resid=9B7D796BD3E9E65C!1228&parid=9B7D796BD3E9E65C!305&authkey=!AGjG73d414ceqm0">https://skydrive.live.com/redir.aspx?cid=9b7d796bd3e9e65c&resid=9B7D796BD3E9E65C!1228&parid=9B7D796BD3E9E65C!305&authkey=!AGjG73d414ceqm0</a><br /><br /><br />Here's just a couple of examples of the work we did...<br /><br />* Our Senior Designer Luke produced an outstanding design for a SharePoint custom field.<br /><br />With this field, end users can select tracks from Spotify using drag-and-drop. The meter allows users to add up to 30 minutes of music to a Playlist. After the Playlist has been created, it can be scheduled to play at a certain time.<br /><br /><a href="http://3.bp.blogspot.com/-NIZLnXoBrEM/TtyXD6SpetI/AAAAAAAAAQw/SV4ftgjV9c4/s1600/CustomField.png"><img style="cursor:pointer; cursor:hand;width: 320px; height: 251px;" src="http://3.bp.blogspot.com/-NIZLnXoBrEM/TtyXD6SpetI/AAAAAAAAAQw/SV4ftgjV9c4/s320/CustomField.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5682582923277597394" /></a><br /><br />* I created a Visual Web Part that shows the track currently playing. This uses the Bing API to dynamically download Album Art for the track.<br /><br /><a href="http://2.bp.blogspot.com/-xGA1S7PCZ0U/TtyYuyb4ytI/AAAAAAAAAQ8/jc7eXgfr_FU/s1600/NowPlaying.png"><img style="cursor:pointer; cursor:hand;width: 320px; height: 168px;" src="http://2.bp.blogspot.com/-xGA1S7PCZ0U/TtyYuyb4ytI/AAAAAAAAAQ8/jc7eXgfr_FU/s320/NowPlaying.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5682584759414868690" /></a>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-80671296353562151532011-11-09T08:42:00.010+00:002011-11-09T17:16:01.228+00:00Remove query string from urlI needed to delete the querystring value from a Url. The code I used to do this is right at the end of this post.<br /><br />First though, here's the reason I needed to do it.<br /><br />I found that if you call the SPWeb.GetFile method, with a Url that contains a query string, the value of Item for the returned SPFile will be null. Here's an example:<br /><br /><code style="FONT-SIZE: 10pt; FONT-WEIGHT: bold"><br />string url = "http://red-hb:8080/TestSite/Pages/Tamar.aspx?x=y";<br /><br />using (SPSite site = new SPSite(url))<br />{<br />using (SPWeb web = site.OpenWeb())<br />{<br />SPFile file = web.GetFile(url);<br />Console.Write(file.Item["Title"]); // Item will be null.<br />}<br />}<br /></code><br /><br />OK, here's how I removed the query string:<br /><br /><code style="FONT-SIZE: 10pt; FONT-WEIGHT: bold"><br />string url = "http://red-hb:8080/TestSite/Pages/Tamar.aspx?x=y";<br /><br />Uri uri = new Uri(url);<br /><br />string queryString = uri.Query;<br /><br />if (String.IsNullOrEmpty(queryString) == false)<br />{<br />url = url.Replace(uri.Query, String.Empty);<br />}<br /><br /></code>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-73595295474100230672011-11-03T09:37:00.018+00:002011-11-08T08:04:25.558+00:00"This solution contains no resources scoped for a Web application"I created a SharePoint Solution that contained a single Feature. The Feature had a Receiver which is used to make web.config modifications.<br /><br />I wanted to target these modifications at specific SharePoint web applications. However, when I ran the following PowerShell command, I got the message: "<strong>This solution contains no resources scoped for a Web application</strong>". <br /><br /><strong>Install-SPSolution –Identity <WSP NAME>.wsp –WebApplication http://<TARGET APP URL> -GACDeployment -Force</strong><br /><br />Other people suggest not including the target web application url. I don't want to do this as it will affect all web applications, not just our own.<br /><br />The workaround I used was to include the Solution assembly within its own package, and mark it as a "SafeControl".<br /><br />I realise that this not ideal. Do you have a better solution?<br /><br />The steps I followed were:<br /><br />1) Open the Project Properties for the Solution, and set "Include Assembly in Package" to "False".<br /><br /><a href="http://1.bp.blogspot.com/-C7ojUjTiGQQ/TrJoQa0L8sI/AAAAAAAAAQM/g8RL9Nw9NsE/s1600/Include%2Bin%2Bpackage.png" border="1px"><img style="cursor:pointer; cursor:hand;width: 320px; height: 251px;border: 1px solid" src="http://1.bp.blogspot.com/-C7ojUjTiGQQ/TrJoQa0L8sI/AAAAAAAAAQM/g8RL9Nw9NsE/s320/Include%2Bin%2Bpackage.png" border="1px" alt="Include Assembly in Package" id="BLOGGER_PHOTO_ID_5670709512098280130" /></a><br /><br />2) Edit the Package manifest and include the assembly from the project's own output. Add the assembly / namespace as a SafeControl.<br /><br /><a href="http://1.bp.blogspot.com/-etCng0KBaXk/TrJqdSVThOI/AAAAAAAAAQY/PJ3oXP7sCwE/s1600/SafeControls.png"><img style="cursor:pointer; cursor:hand;width: 320px; height: 225px;border: 1px solid" src="http://1.bp.blogspot.com/-etCng0KBaXk/TrJqdSVThOI/AAAAAAAAAQY/PJ3oXP7sCwE/s320/SafeControls.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5670711932182824162" /></a>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com1tag:blogger.com,1999:blog-8888450165642231745.post-86812413759596078232011-10-28T10:00:00.011+01:002011-10-28T16:08:10.852+01:00SharePoint Anonymous Access<p>I was trying to change the Anonymous Access settings for a list, as per this screen:</p><br /><a href="http://2.bp.blogspot.com/-J0U_6a6ZmAQ/TqpyOi6H7eI/AAAAAAAAAP0/46Xt4cZNEUk/s1600/Anonymous%2BAccess.png"><img style="cursor:pointer; cursor:hand;width: 320px; height: 277px;" src="http://2.bp.blogspot.com/-J0U_6a6ZmAQ/TqpyOi6H7eI/AAAAAAAAAP0/46Xt4cZNEUk/s320/Anonymous%2BAccess.png" border="0" alt="SharePoint Anonymous Access checkboxes" id="BLOGGER_PHOTO_ID_5668468675213520354" /></a><br /><p>However, when I checked the "Add Items" box and clicked OK, it did not save the changes. Everytime I repeated this and went back to the screen, the "Add Items" box was not checked.</p><br /><p>The cause of the problem was that the Anonymous Policy for the SharePoint Application (that hosted the site) had been changed. By default this is set to "None". However, it had been set to "Deny Write".</p><br /><a href="http://4.bp.blogspot.com/-skVePSVxIz0/TqpzrJov8SI/AAAAAAAAAQA/_2TUTnICBD4/s1600/Anonymous%2BPolicy.png"><img style="cursor:pointer; cursor:hand;width: 320px; height: 242px;" src="http://4.bp.blogspot.com/-skVePSVxIz0/TqpzrJov8SI/AAAAAAAAAQA/_2TUTnICBD4/s320/Anonymous%2BPolicy.png" border="0" alt="SharePoint Anonymous Policy" id="BLOGGER_PHOTO_ID_5668470266157592866" /></a><br /><p>There wasn't a good reason for this and switching it back to "None" fixed the problem.</p>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-25830213315294833062011-10-27T14:32:00.018+01:002011-10-28T10:03:16.044+01:00DataFormWebPart maximum field lengthsI used a DataFormWebPart to generate a custom edit form. Our client wanted to limit the maximum length of various fields on this form, but didn't want these to be applied site-wide.<br /><br />The built-in SharePoint fields (FormField, TextField, NoteField, etc) don't have a "maxlength" property. <br /><br />The solution was to modify the template for the various fields within the DataFormWebPart XSLT, to include RegularExpressionValidators.<br /><br />Credit to Bart McDonough for this. His <a href="http://doseofdotnet.wordpress.com/2011/01/16/max-length-of-a-multi-line-text-note-field-on-sharepoint-publishing-page/">blog post</a> relates to creating a new field type, but I tried it within the DataFormWebPart and it worked.<br /><br />The nice thing about this is that the validation will take place on both the client and the server<br /><br />Here is a sample from my DataFormWebPart XSLT file. This sets the maximum length of a text field to 80 characters.<br /><br />Note that the curly braces in the regular expression have to be escaped. If you don't do this, the XSLT will break.<br /><br /><p style="font-size:10pt;font-weight:bold"><br /><code><br /><strong><SharePoint:TextField runat="server" id="ff1{$Pos}" ControlMode="Edit" FieldName="Title" __designer:bind="{ddwrt:DataBind('u',concat('ff1',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@Title')}"> <br /> <br /><Template> <br /> <br /><asp:TextBox id="TextField" runat="server"/><br /> <asp:RegularExpressionValidator <br /> ControlToValidate="TextField" <br /> ValidationExpression=".{{0,80}}"<br /> Text="Value cannot exceed 80 characters." <br /> runat="server" /> <br /> <br /></Template> <br /> <br /></SharePoint:TextField></strong></code><br /></p>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-23529898158696671822011-10-26T14:29:00.012+01:002011-10-26T14:37:58.561+01:00SharePoint Check "page layout"In code, I had a reference to an SPFile object and I wanted to check if the SPFile was a page layout file.<br /><br />I used code (similar to the sample below) to do this. It checks to see if the file's parent list is the master page / page layout library.<br /><br />Maybe you know a better way?<br /><br /><P style="font-size:10pt"><br />string url = " -- ABSOLUTE PATH TO YOUR FILE -- ";<br /><br />using (SPSite site = new SPSite(url))<br />{ <br /> using (SPWeb web = site.OpenWeb())<br /> {<br /> SPList masterPagelist = site.GetCatalog(SPListTemplateType.MasterPageCatalog);<br /> SPFile file = web.GetFile(url);<br /> <br /> if (file.Item.ParentList.ID == masterPagelist.ID)<br /> {<br /> // The file is in the master page library.<br /> } <br /> }<br />} <br /></P>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-56633196708352996422011-10-24T11:03:00.025+01:002011-10-28T13:50:35.936+01:00SharePoint SummaryLinks "Edit Properties"While logged-in as a user with Contributor permissions, I noticed that the toolbar for a Summary Links field was not visible on the Edit Form of a publishing page. <br /><br />This is is shown in the picture below:<br /><br /><a href="http://2.bp.blogspot.com/-AY7sGHIoF1Y/TqU4nPpGG1I/AAAAAAAAAPo/t0atYUC_mBI/s1600/NoToolbar.png"><img style="cursor:pointer; cursor:hand;width: 320px; height: 82px;" src="http://2.bp.blogspot.com/-AY7sGHIoF1Y/TqU4nPpGG1I/AAAAAAAAAPo/t0atYUC_mBI/s320/NoToolbar.png" border="0" alt="SummaryLinks has no" id="BLOGGER_PHOTO_ID_5666997952980589394" /></a><br /><br />I suspect this is a SharePoint bug as the toolbar <strong>was </strong>visible when the page was in WYSIWYG edit mode.<br /><br />Also, the issue did not occur when logged-in as a Site Collection administrator.<br /><br />A work-around to this issue is to give the user the <em>Manage Lists</em> permission. However, this is really not something you should consider lightly as it gives editors an awful lot of power.<br /><br />I'm going to speak to Microsoft to see what they say about it and then I'll post an update....<br /><br /><p style="background-color:yellow"><U>UPDATE</U><p><br /><p>Microsoft has acknowledged that this is an "Offbug" (as they call it). In other words, it's a bug in their code.</p><br /><p>This will be fixed in a future hotfix or service pack. However, they will not / cannot give a date for the fix.</p>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-72720953266046339932011-09-13T08:13:00.011+01:002011-09-13T09:17:51.445+01:00SharePoint Inline HTML EditorOne of our clients had very specific requirements for the way in which their editors manage the main body content of a page. Here is some background:<br /><br />With the previous version of SharePoint (MOSS 2007), page editors could edit page content using a Rich Text editor that sat above the content field. This is shown below:<br /><br /><a href="http://1.bp.blogspot.com/-WJwzjWeEg2c/Tm8EWG3jF5I/AAAAAAAAAPY/vKStNbqFSTY/s1600/MOSSRichTextEditor.png"><img style="cursor:pointer; cursor:hand;width: 320px; height: 124px;" src="http://1.bp.blogspot.com/-WJwzjWeEg2c/Tm8EWG3jF5I/AAAAAAAAAPY/vKStNbqFSTY/s320/MOSSRichTextEditor.png" border="0" alt="MOSS RichText Editor" id="BLOGGER_PHOTO_ID_5651740835220494226" /></a><br /><br />With SharePoint 2010, the Ribbon provides the editing functionality, as shown below:<br /><br /><a href="http://3.bp.blogspot.com/-fDkmCIS3xTs/Tm8KQ-2uBdI/AAAAAAAAAPg/tHjdaqZ4Dhw/s1600/RibbonEditor.png"><img style="cursor:pointer; cursor:hand;width: 320px; height: 78px;" src="http://3.bp.blogspot.com/-fDkmCIS3xTs/Tm8KQ-2uBdI/AAAAAAAAAPg/tHjdaqZ4Dhw/s320/RibbonEditor.png" border="0" alt="Ribbon Editor"id="BLOGGER_PHOTO_ID_5651747344239953362" /></a><br /><br />Even though our client is using SharePoint 2010, they wanted to use the MOSS-style page editor, rather than the Ribbon. This was for a subset of editors, on one specific site.<br /><br />One way to solve this is to switch the User Interface (UI) version of the site from "4", to "3" e.g. switch from the SharePoint 2010 UI to the MOSS UI. This is done via the SPWeb.UIVersion property.<br /><br />We didn't want to change the UI version so in the end, the solution was to:<br /><br />1) Create a custom edit form.<br />2) Change the control used to edit the page content from SharePoint:FormField to SharePoint:InputFormTextBox <br /><br />The InputFormTextBox has some properties that allow Rich Text, which are shown below:<br /><br /><SharePoint:InputFormTextBox TextMode="MultiLine" Rows="6" RichText="true" RichTextMode="Compatible" runat="server" />Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-91232062119401297142011-09-09T09:47:00.006+01:002011-09-09T10:15:39.302+01:00SharePoint 0x810200c6 List Validation FailedWe use custom code to create a new Publishing Page:<br /><br />SPWeb currentWeb = SPContext.Current.Web;<br /> <br />PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(currentWeb);<br /><br />PublishingPage page = publishingWeb.GetPublishingPages().Add(newPageName, newPageLayout);<br /><br />This was failing with the error:<br /><br /><nativehr>0x810200c6</nativehr><nativestack></nativestack>List data validation failed.<br /><br />The error was caused because the Pages library had validation applied to it, which validated two date fields. The formula for the validation was:<br /><br />=[Start Date and Time]<[End Date and Time]<br /><br />When the page was created in code, the validation was fired, which failed because the two date fields are initially empty. <br /><br />The solution to the problem was to change the validation formula to handle the initial values e.g.<br /><br />=[Start Date and Time]<<strong>=</strong>[End Date and Time]Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-71321455562771284402011-09-06T12:13:00.008+01:002011-09-13T09:16:35.903+01:00SharePoint The document contains invalid utf-8 encoded charactersWe used SharePoint to index a website and got the message "The document contains invalid utf-8 encoded characters". <br /><br />To fix this, modify the target site and replace special characters with their encoded equivalent. For example, replace any £ characters with &pound;. The same is true for ©, which should be replaced with &copy, etc.<br /><br />Use the <a href="http://validator.w3.org/">W3C validator</a> to identify encoding issues.Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-51842034318011530602011-07-05T13:48:00.012+01:002011-09-13T09:16:35.903+01:00"Activate Features" "The object has been updated by another user since it was last fetched"I created a Feature Receiver to assign an Event Receiver to various content types. This was working fine. However, after a small update to the code, the package would no longer deploy and failed with the following message:<br /><br /><i>Error occurred in deployment step 'Activate Features': The object has been updated by another user since it was last fetched.</i><br /><br />I discovered the problem was caused because I:<br /><br /><br /><ol><br /><li>Assigned the Event Receiver to a base content type (CT 1).</li><br /><br /><li>Immediately after attempted to add the Event Receiver to a content type (CT 2) derived from the base content type (CT 1)</li></ol><br /><p>To solve the issue, I did not do step (1) above and just did step (2).<br /></p>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-10639859907897083652011-06-29T14:14:00.006+01:002011-06-29T14:27:54.274+01:00SharePoint Public WebsitesThis is how you can find a list of public web sites built using SharePoint...<br /><br />To do this, I used Google to search for the phrase "Turn on more accessible mode". This phrase is rendered by most SharePoint pages yet is specific enough to restrict the number of non-SharePoint sites returned.<br /><br />Try it for yourself: <a href="http://www.google.co.uk/search?q=%22Turn+on+more+accessible+mode%22">http://www.google.co.uk/search?q=%22Turn+on+more+accessible+mode%22</a><br /><br />I'm aware of the list on <a href="http://www.wssdemo.com/Pages/websites.aspx">WssDemo.com</a>. However, I wanted to use Google to generate a dynamic list.Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-26910122120390787632011-06-27T12:23:00.004+01:002011-06-27T12:29:24.478+01:00SharePoint "Corrupted Control Template"I began seeing the error message "Corrupted Control Template" when I switched a Publishing Page into Edit Mode.<br /><br />Eventually I tracked-down the issue....<br /><br />1) Another developer had created a number of custom fields.<br />2) They had created a file called "fldtypes_custom.xml" (which is required to register the custom field types).<br />3) I renamed this file to something more specific.<br /><br />To fix the issue I had to....<br /><br />1) Delete the Web Application (including the associated Content Database)<br />2) Rename the file back to what it was before I changed it<br />3) Re-deploy the solution.Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-54726686059427303232011-05-27T15:39:00.010+01:002011-06-13T09:30:35.836+01:00SharePoint PublishingPageImage srcFor an article page, SharePoint stores the value of the Publishing Image field in a particular format. Here is an example:<br /><br /><img alt="" src="/SiteCollectionImages/home.jpg" style="BORDER: 1px solid; "><br /><br />I wanted to extract the value of the "src" attribute. Here is the code I used:<br /><br />string fullValue = String.Format("{0}", file.Item[FieldNames.PUBLISHING_PAGE_IMAGE]);<br /><br/><br />string src = String.Empty;<br /><br />if (String.IsNullOrEmpty(fullValue) == false)<br />{<br />string xml= String.Format("{0}</img>", fullValue);<br />string src = XElement.Parse(xml).Attribute("src").Value;<br />}Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com0tag:blogger.com,1999:blog-8888450165642231745.post-42616370874382086632011-05-25T10:31:00.014+01:002011-09-13T09:24:52.929+01:00SharePoint "Object reference not set to an instance of an object" Page SaveI'd created a custom page layout, applied it to a page and then tried to edit the page. Everything was fine until I clicked on one of the save options for the page. At this point the site blew-up with the following stack trace:<br /><br />NullReferenceException: Object reference not set to an instance of an object.]<br />Microsoft.SharePoint.WebPartPages.WikiPageWebPartSaver.SaveWebPartsInRichText(SPWebPartManager wpmgr) +230<br /><br />It took a bit of work but I tracked-down the cause. Essentially the Designer had given me some HTML mark-up which I'd pasted into the page layout. This mark-up contained an additional "form" element. When this was removed, the page-save worked correctly.<br /><br /><span style="background-color:yellow">UPDATE</span><br /><br />I don't remember the exact code, but it was something like the code below. The first form element is generated by SharePoint. The second form element was pasted-in by mistake.<br /><br /><form id="aspnetForm" method="post" name="aspnetForm" action="default.aspx"><br /><br />...<br /><br /><span style="background-color:yellow"><form action="destination_url" method="get"><br /></form></span><br /><br />...<br /><br /></form>Howardhttp://www.blogger.com/profile/02983575248612564761noreply@blogger.com2