Archive for the ‘SP2013 Development’ Category

As SharePoint Developers, we are often challenged with requests to sort list item data seemingly arbitrarily. In these cases, none of the field data can be used to sort ascending or descending and get the results we are seeking. Often, we end up creating a Number column and setting a value so we can sort on that value. The trouble here is that you must manually update all of the other items. This can be painful if you’re trying to move an item with Order = 50 to Order = 1: You must change the Order value on 49 other items!

Links Lists have a handy link in the Items menu labelled “Change Item Order.” The page this link takes you to allows you to change the order of items in the Links List just like you would change the order of fields in a list view. SharePoint then stores the numerical sort order in a hidden field on the list which the Links Lists view uses with an orderBy.

So, excellent, there is something out of box to do what we want to do. Hooray! Now, how do we make use of it? Turns out, if you add a column to your custom list that is identical to the hidden column used in the Links List, you can take advantage of the “Change Item Order” page for your custom list! Here’s how I did it:

Using SharePoint REST API, I discovered the SchemaXml property for the hidden Order field in the Links List is:

<Field ID=\"{ca4addac-796f-4b23-b093-d2a3f65c0774}\" ColName=\"tp_ItemOrder\" RowOrdinal=\"0\" Name=\"Order\" DisplayName=\"Order\" Type=\"Number\" Hidden=\"TRUE\" SourceID=\"http://schemas.microsoft.com/sharepoint/v3\" StaticName=\"Order\" FromBaseType=\"TRUE\" />

I then simply generated a POST using the REST API once again to create a field on my custom list using the SchemaXml above. You can, of course, use whatever app you wish to do the POST. My favorite is Postman. Here’s how I setup the request to send:

  1. POST to [your site URL]/_api/web/lists/getbytitle(‘[title of your custom list]‘)/fields/createfieldasxml
  2. Headers:
    1. Accept: application/json
    2. Content-Type: application/json
    3. X-RequestDigest: [a current request digest]
  3. Body:
        "parameters": {
           "__metadata": {
              "type": "SP.XmlSchemaFieldCreationInformation"
           "SchemaXml": "&lt;Field ID=\"{ca4addac-796f-4b23-b093-d2a3f65c0774}\" ColName=\"tp_ItemOrder\" RowOrdinal=\"0\" Name=\"Order\" DisplayName=\"Order\" Type=\"Number\" Hidden=\"TRUE\" SourceID=\"http://schemas.microsoft.com/sharepoint/v3\" StaticName=\"Order\" FromBaseType=\"TRUE\" /&gt;"

This adds a hidden Order field to your custom list. The only thing left to do is access the “Change Item Order” page for your list and start setting item order. Here’s the URL:

[your site URL]/_layouts/15/Reorder.aspx?List=[your list GUID]

If you want to get the ordering data for your client-side app, here’s an important tip: The SharePoint REST API does not return the Order field when you simply execute a call to _api/web/Lists…/items. If you add Order to a $select option—like _api/web/Lists…/items?$select=Order—the item ordering set by the “Change Item Order” page will be returned.

Happy ordering! Let me know below if you find any issues doing this.

Update/Note, 11/7/2017: The “Change Item Order” page only supports up to 100 items at a time. It pages items in groups of 100. Thus, it gets a little tricky to move an item around when you’re dealing with hundreds of items or more.


Read Full Post »

I’ve been working on Apps quite a lot this month and learning all sorts of things like: the difference between Office 365 D (Dedicated) and Office 365 MT (Multi-Tenant); how to setup Access Control Service (ACS); and when to use F5 in Visual Studio and when to package and deploy. It’s been a roller coaster of confusion and trial-and-error as I’ve attempted to wade through all of the How-To’s created over the last couple of years and merge them with all of the changes made available to the products during that same period. This week has brought a lot more clarity and understanding; in short, I think I’m finally starting to grasp the hang of it.

At the end of the day yesterday, I ran into an interesting phenomenon I thought would be worth sharing. Several of the documents I’ve read regarding app event receivers have said they are not supported from an on-premise install of SharePoint (see Where can I use app event receivers? in the MSDN App event receivers FAQ). Thus, online being my “only” option, I was banging my head trying to get event receivers to work in SharePoint Online for a provider-hosted app. No matter what I tried, my attached W3SVC wouldn’t stop on the breakpoint for the IRemoteEventService's ProcessEvent.

Having lost nearly all hope, I shelved my efforts and moved on to something else in the project. Upon installing the app to my on-premise SharePoint server, Visual Studio surprisingly hit my breakpoint in IRemoteEventService's ProcessEvent! Whoa! What’s going on here?

Well, it turns out that my host web (the IIS site hosting the service being called by the event) is on a Dev server. Naturally, it isn’t available publicly. As such, when SharePoint Online went to call the service, it couldn’t establish a connection. Of course, our on-premise SharePoint can connect to the Dev server because they’re on the same side of the firewall. So, what about all the documentation implying this can’t be done? Well, most of the documentation out there doesn’t consider that you can now run ACS from an on-premise server (many were written before ACS was a known option for on-premise).

Notice how the MSDN article doesn’t say it’s not possible; it only indicates that it’s not supported. I suppose such configuration as I have is just too new to support as of the last update of that article (December 31, 2014)–that more testing is needed. I for one am glad app event receivers for provider-hosted apps work when you have an accessible host web and other configurations (like ACS), either way!

Let me know if you encounter any issues using app event receivers with provider-hosted apps in an on-prem SharePoint app web and/or host web.

Read Full Post »

I’ve been struggling for the past week to get some custom Access Denied, Signout, and Login pages implemented in our environment. There is a lot of agreement that Get-SPCustomLayoutsPage, Set-SPCustomLayoutsPage, and Microsoft.SharePoint.Administration.SPWebApplication.UpdateMappedPage() were great additions to SharePoint 2010, but there’s been quite the struggle getting these to work in SharePoint 2013.

The first question to ask is: Are you running the April 2013 CU or later? This is critical! There was a bug in earlier versions of SharePoint which made it so you could set a custom layouts page, but it wouldn’t use it. Be patient after you upgrade your farm, it took several days before ours finally started behaving itself after the CU (go ask the Computer Gods if you want to know why–I just thanked them when it finally worked.)

The next question to ask is: What UI is your site using? Is it using the 2010 UI or the 2013 UI? In many cases, you have upgraded your farm to SP2013, but haven’t upgraded your sites, yet.

As it turns out, the question about the UI is quite important. If your site is using the 2013 UI, you’re fine: By default Get-SPCustomLayoutsPage, Set-SPCustomLayoutsPage, and SPWebApplication.UpdateMappedPage(...) work with a CompatibilityLevel = 15. That’s right, CompatibilityLevel! There is an undocumented parameter on these cmdlets and method (presumably added with the April 2014 CU). If your site is using the 2010 UI, you’ll need to specify a CompatibilityLevel = 14 when using these cmdlets or method. Just be sure to give the correct path for the correct hive/UI: The path must start with “/_layouts/15/” for the 2013 UI (CompatibilityLevel = 15, or omitted), and must start with “/_layouts/” for the 2010 UI (CompatibilityLevel = 14).

Just be sure you deploy your custom pages to both hives. For me, I had packaged the custom pages in a farm solution. Just needed to deploy the pages to both hives by specifying CompatibilityLevel = All when executing Install-SPSolution. (Unfortunately, there’s no way to do this from the deployment in CA.)

Of course, this means you are able to have different pages for each of the mapped pages for each of the hives. Want one Access Denied page for the 2010 UI and a different one for the 2013 UI? No problem!

Read Full Post »

My thanks to Peter Holpar for his blog post on “How to Override the Default Item Save Event Using Custom Fields.” Gave me the information I needed to create a handy custom field.

During our testing, though, we found that save errors were not being handled correctly. For example, when the “Allow duplicate values” was set to “No” and you tried to set a duplicate value in the field, you got a very ugly error page. So, I went back to Peter’s blog: No solution. I searched all over: no solution. So, back to Peter’s blog. There was one little tidbit that turned into the key to solving the problem and getting SharePoint to properly handle the SPDuplicateValuesFoundException. Peter mentioned an alternative to using SPContext.Current.ListItem.Update() was to use SaveButton.SaveItem(). Close, very close! The parameterless method is actually not available to our custom field, but SaveButton.SaveItem(SPItemContext, bool, string) is. Calling this method instead of the update method took care of the problem. Now, when someone tries to enter a duplicate value in our custom field, we get the nice, red message “This value already exists in the list.”

Now a happy Monday morning!

Read Full Post »

Radu Tut did a wonderful blog about how to get Search Analytics Reports programmatically in SharePoint 2013. I am quite grateful for his guidance and it’s undoubtedly the most referenced article on the topic (even being referenced in Microsoft blogs and other documentation).

I followed Radu’s guidance and have successfully retrieved usage data from my site collections in 2013, but I’ve discovered a few things I’ve not seen anyone talking about:

  1. It is important to note that the DateTime value you use should be UTC. If not, you will, at some time during the day–depending on your offset–get a “Specified argument was out of the range of valid values” error when trying to get the furthest back data (example: -14 days for Day) if you use Local time. Internally, SharePoint uses DateTime.UtcNow.Date (see reflection of Microsoft.Office.Server.Search.Analytics.AnalyticsItemData in the Microsoft.Office.Server.Search.Applications.dll).
  2. To my surprise, I was able to retrieve usage data from a 2010 site collection in SP2013! Apparently, SharePoint is tracking and compiling this data, but the 2010 UI has no way to interface with the data. Thus, if you need usage data for a 2010 UI site collection in SharePoint 2013, turn to your Devs or PowerShell-savvy Admins: If your site is being crawled, the 2013 usage data you seek is in there!
  3. The time period for SP2013 to compile usage data is fairly lengthy (at least 15 minutes in my tiny dev farm). If you attempt to retrieve the data while SharePoint is compiling it, you’ll get back a big fat ‘0’. For expected results, make sure you’re not retrieving the data while SharePoint is compiling it. 🙂 I believe this compilation is done by a timer job once a day at midnight, by default (I was up pretty late working on my project when I discovered this behavior).

Happy reporting!

Read Full Post »

Another day, another discovery on my quest to migrate our farm from SharePoint 2010 to SharePoint 2013. I started noticing image quality problems with the user thumbnail images in my upgraded farm: The small and large thumbnail images were looking very blurry. This was particularly evident when I viewed my My Site Host’s People page (MyPeople.aspx). The photo of myself on the left side was fairly blurry, but the small photos of the people I am following were nearly indistinguishable. Okay, what’s going on here?

Well, it turns out that Microsoft has changed the default thumbnail sizes for User Profile photos in SharePoint 2013. Here’s a comparison of the maximum dimensions (pixels) as given in Microsoft.Office.Server.UserProfiles.UserProfilePhotos:

Max pixels
Thumbnail SP2010 SP2013
Large 144 300
Medium 96 72
Small 32 48

As you can see, the dimensions for the large and small images have increased but has decreased for the medium image.

The new dimensions for the medium and small images isn’t much of a problem thanks to the handy dandy PowerShell cmdlet Update-SPProfilePhotoStore (read more at TechNet). The detailed description given in the TechNet reference still refers to 2007, but what this cmdlet does still apply to upgrades from 2010. By executing Update-SPProfilePhotoStore -MySiteHostCollection http://sppaule/my my thumbnail images were regenerated to match the default sizes desired by the system.

There’s still one gliche: SharePoint’s thumbnail image creation routine (found in Microsoft.Office.Server.UserProfiles.UserProfilePhotos) won’t enlarge images. (I’ve got a background in design and photography and can say with assurity that this is a good thing!) This means the large thumbnails stay at a maximum 144 pixels. Since they are displayed at 200 pixels, the image is thus enlarged by the browser by 38% causing bluriness. Unfortunately, unless you have a repository of higher resolution images of your users, you’re stuck.

This is where I think the new Image Renditions can come in quite handy. For more information about Image Renditions, I highly recommend MVP Waldek Mastykarz’s wonderful post “Image Renditions in SharePoint 2013.” If the User Profile Photos were to use Image Renditions, your originally uploaded file could be stored for use whenever the preset thumbnail sizes were inadequate. This would allow for a regeneration of the large thumbnail image should it’s default size increase again in the future. Not only that, but uploading a file could conceivably trigger a scaling-and-cropping UI similar to that used by Image Renditions (hopefully a little simpler) wherein the user uploading the photo could scale and crop the original photo right in the browser!

For SP2010, I gave our HR department a webpart which did allow them to scale and crop the original right in the browser (using Jcrop) and stored the original photo in another photo library. Now I’m just kicking myself for not storing the cropping information as properties/fields along with the original photo. Had I done so, I’d be able to programmatically regenerate the large thumbnail images at the new SharePoint 2013 largeThumbnailSize of 300 pixels and perhaps even implement something using Image Renditions. (Fortunately, my webpart actually saves the cropped image at full resolution. So, I only need to rescale the images programmatically in order to generate new large thumbnails for SharePoint 2013. Phew!)

One final note: Update-SPProfilePhotoStore has one other side benefit for which I’d like to give my gratitude to the Microsoft team who put it together! In our migration to SharePoint 2013, we are changing our web application’s default zone to a different domain name and moving the My Site Host under this web application (lots of work and not particularly recommended to have the My Site Host under the same web application, but it’s going to save our users–and thus me–a lot of headache). Thus, when the User Profile Service was upgraded from SharePoint 2010 to SharePoint 2013, all of the user’s profile photos were still pointing to the old domain name. Fortunately, the old farm was still running and accessible under the old domain name. Having not migrated the My Sites Host content (I wanted to start clean with a 2013 My Sites Host), I didn’t have the user photos in the new SP2013 farm. I ended up writing a console application which would copy the user photos I needed from the old farm to the new farm (hence my last post). Turns out, that wasn’t necessary. To my surprise–and the credit of the Microsoft team–Update-SPProfilePhotoStore retrieved the photo from the old farm using the URLs in the new farm’s user profiles, resized them (except for the large thumbnail as spoken of above), stored the sizes (144, 72, and 48) in the new farm, and updated the URL in the user profile to point to the new 2013 My Sites Host > User Photos > Profile Photos. SLICK!

So, despite the shift in default image sizes for User Photo thumbnails, there is a convenient way to update your thumbnails. If Microsoft were to integrate Image Renditions with the User Photos, the whole process will become much more robust for all SharePoint consumers. I’m crossing my fingers!


Read Full Post »

Older Posts »