Sunday, September 21, 2014

Reflection: A PDF document must be opened with PdfDocumentOpenMode.Import to import pages from it.

The solution for the problem is very obvious as outlined below, so this is a reflection on developer behavior and API friendliness.

This is not a logical bug: a lot of times programmers are not faced with algorithmic challenges. In the code snippet below, there is nothing much to this for loop that add pages from a PdfDocument to another using PDFSharp.

foreach(var reportStream in reportStreams)
    var pdfDoc = PdfReader.Open(reportStream);
    foreach (PdfPage page in pdfDoc.Pages)

Developers do not scratch their heads to write that piece of code, but sometimes the simplest things take time and effort because developers do not understand how APIs work. We live in a software development world that is filled with APIs whether on the web or local and for most using APIs is a natural part of their jobs which is good until the benefits of using the API e.g. avoid reinventing the wheel and making use of others who studied the object of the API more in depth, are outweighed by the disadvantages: API learning curve as APIs involve learning concepts of the API and a sophisticated object structure, going around things that are not implemented by the API, and so on.

In this particular case, the API that I was using, the PDFSharp library, threw an exception that told exactly what was expected. This is an example of excellent API communication. It told me that I have opened a PDF Document in a mode that did not allow me to import PDFs.

So simply adding PdfDocumentOpenMode.Import solves the issue:

foreach(var reportStream in reportStreams)
    var pdfDoc = PdfReader.Open(reportStream, PdfDocumentOpenMode.Import);
    foreach (PdfPage page in pdfDoc.Pages)

I've had experience with other API that throws the most obscure exceptions even at locations where it is hard to trace where your erroneous API usage originated. Or doesn't even through exceptions but does not do what is required, e.g. doesn't add pages to the main doc so it leaves it up to you to guess what went wrong: the loop was not entered for some reason, reportStreams is empty, the page elements are null, etc?

I can hardly consider fixing such an issue as a programming challenge because APIs are designed by humans, or even if they are "engineered" by humans, there are a lot of things that are just arbitrary regarding how APIs are built. Of course there are choices that makes sense more than others such as naming an API method as GetPurchaseOrders(DateTime, DateTime) rather than GetSome(DateTime, DateTime). The choices increase exponentially from here (Parameter numbers and types, overloads, type structure, complexity, error messages, returning null on failure, empty objects, etc...).

I wonder about the ways to actually "engineer" or systematize the process of "designing" an API? 

Wednesday, September 17, 2014

SharePoint CustomAction Features can be used for 3 things

Well I have a very short post because I want to note this simple fact in SharePoint customization.

Custom Action features (CustomAction XML element) is used with for both ribbon actions, site settings page section and I think list item context menus. The naming matches directly for ribbon buttons and context menus but not as much for site settings section.

And all you need to do is set the attribute Location="Microsoft.SharePoint.SiteSettings" in the CustomAction element, to have it as a site settings action. To create an item for the ribbon set Location="CommandUI.Ribbon"

Example Elements.xml of a feature:

     Title="Configuration Section Title"
     Description="blah blah"

    Title="SharePoint custom configuration page (application page)"

Thursday, August 7, 2014

Developer doing administration because of SharePoint

Even if you are on the code side of things, i.e. a programmer, you are exposed to consider a lot of things that usually belong to the administration and the infrastructure domains because a lot of what you need to use as a develop in SharePoint, relies on things that are configured by administrators.

One first initial example is that SharePoint must run within a domain, this means that you will need to create a server with Active Directory Domain Services, called ADDS. This server is called the domain controller.

Virtually everything else relies on administration related work. If you want to configure search, you will need the administrator to create a domain account for the search service. In my company developers do not have administration rights, so they must ask the administration team's help. If they are busy or not even convinced that you should do what you want to do (even on a test server), then you're out of luck. I wonder where is my negotiation skills?! Anyways, that was so annoying for me that I decided to create my own environment on my machine. Luckily I had 16GB of physical ram and an SSD. Not bad and could be used for testing purposes.

Windows Server VM, SQL Server, Domain Controller with a static IP, internet connection? Etc..

As someone whose administration skills are "me can creates adhoc network" this opens up a whole new world for me. I am learning a lot of curious things.

Wednesday, August 6, 2014

Restoring deleted Site Collections in SharePoint 2013

Useful MSDN resource:

I just learned what's the identity of a site. At least according to what Restore-SPDeletedSite knows.

This PowerShell SharePoint command is the only way to restore a deleted site collection. In SharePoint 2013 there is no UI in central administration, or even SharePoint designer as far as I have searched that allows you to do this.

To get the list of Site Collections that were deleted and are restorable, use the Get-SPDeletedSite command that will return SPDeletedSite objects.

For example (on a test server, hence http not https) gets you the following information:

WebApplicationId   : 9fa68842-c64d-493b-8102-15d4929d2fb6
DatabaseId         : dcacbbf9-719b-41b7-b7f9-526bce8100ff
SiteSubscriptionId : 00000000-0000-0000-0000-000000000000
SiteId             : b1110b1f-822b-4d70-aace-09dcba30aeca
Path               : /sites/test3
Scheme             : Http
Url                : http://msesrv30/sites/test3
DeletionTime       : 8/6/2014 8:05:41 AM

But which one of these is the site's identity? Sometimes, or a lot of times depending on how new your are to SharePoint, the terminology that is used is confusing. Anyways after a few tries someone realized that they can use the site Path as the identity while invoking the Restore-SPDeletedSite PowerShell command.

Don't forget the preceding forward-slash (/). Using sites/test3 will not work in this example.

Restore-SPDeletedSite -Identity /sites/test3

Wednesday, July 30, 2014

Complexity Management and Software Development

The details are endless, and are of the lowest business value and complete irrelevance.

One of the primary functions in the business layer of a software system uses a generated control structure. Who cares?

All those helper methods, the similarities in the code, the necessity to handle all the errors, all the different data types, the different sources of information, the conversions between the various representations, etc.

Software Development teaches developers to management complexity which is what business management is all about.

From the code's perspective, we don't care if this object denoting a person is a chief operator or a junior operator. It's just a person whose id must be entered in this field and associated with another object that is in turn associated with an period of time.

From the business perspective, we don't care if this is an object or a magic potion. I don't care that the method that processes a chief operator is exactly the same as that of a junior operator. All I care about is that I can choose both and that the system marks them as unavailable for more work, until they finish.

This is what I love about my current job. I must care for both the business perspective and the lowest levels of code details.

Wednesday, July 9, 2014

Exception from HRESULT: 0x80131904 Caused by missing LookupID="True"

I was running the following query when I unexpectedly got this cryptic error: Exception from HRESULT: 0x80131904.


PersonFieldName person/group field cannot be compared directly to the integer value 11. This somehow caused the error message which certainly does not indicate anything related to the actual mistake that I have made. One must indicate that we want to compare the Id of PersonFieldName in the FieldRef element, to the integer value in the Value element. We do that simply by adding the attribute LookupId and set its value to "TRUE" as follows:

Why didn't someone just throw new InvalidOperationException("Cannot compare field of type Person/Group to integer value.");

What's more interesting is that this very same error message seems to appear when other kinds of problems occur. Looks like some part of SharePoint's code is missing proper exception handling. See this blog post about receiving the same error message for memory capacity problems!

Saturday, June 28, 2014

IE Compatibility view to add complications to web design

This is interesting and shocking at the same time. Why would IE 9 for one user display your site incorrectly while for another displays correctly?

Compatibility View. This "Feature" let's your modern browser behave like a really old one, this is useful depending on what mental illness you have.

Anyways, psychological problems aside, it is not just that your IE 8, 9, 10 or 11 might suddenly behave like the IE 7 that you no longer support, and as thus have users who enable the view acceidentally have bad user experience with your site, it is not even as simple as that.

When I discovered that my design was not working for some users because of compatibility view, I started to investiage and found out the following MSDN article:

The article mentioned that:
In Windows Internet Explorer 9 and earlier versions, quirks mode restricted the webpage to the features supported by Microsoft Internet Explorer 5.5.

So we also have Quirks Mode, which occurs when you omit the HTML page's DOCTYPE, to add complexity to your web design life (ON IE!). Unfortunately a significant percentage of my audience uses IE 9 for my current project.

This is why I had to use x-ua-compatible and set the supported IE browsers like so:

This means, I support Edge (shouldn't I?!), if Edge is not available, then I support IE 10, if that's not available then IE 9 and so on... This will disallow the user to incorrectly turn on "In"compatibility view. And this will ease testing as you can rest assured that what you see on your modern browser is that same as what your beloved client will see.