SharePoint with Attitude…

    Karla Ponce's Blog

    That’s the error that users were experiencing with an InfoPath form in production. The error started to appear with no apparent reason. The form had been working for months, no changes had been applied to it and it didn’t have any custom code. It was a “simple” form with controls and rules to manage the business logic.

    Doing some research I found that SP1 and Cumulative Updates were installed on the SharePoint server; also I found some blogs talking about a bug with SP1/CU and Form Services (Giles blog, Joel’s blog)

    Scenario:

    • SharePoint 2010 SP1 and June Cumulative Updates for Office Server installed on the Server.
    • InfoPath 2010 Form deployed to SharePoint 2010 Form Services.
    • No custom code
    • Form contains attachment controls and Person/Group picker controls (among others)



    Behavior:

    • When attaching a file to the form (using the InfoPath attachment control), a post back occurs and the following error is thrown:



    Description of error:

    • June CU introduces a new event for InfoPath forms: OnLoad(), this event causes a Postback to the server and if the form has a PeoplePicker or an Attatchments control, then it will throw a security exception. What needs to happen is to have a security validation both on initial page load as well as Post Back; currently the Form page does not implement a security validation control needed in the postback.



    Solution:

    As of September 9th 2011, Microsoft has not released any fix to this bug, and the response from the Microsoft support team is that they’re not planning to release a fix anytime soon. The possible workarounds to solve this issue are:

    1. Disable Security Validation. The Web Page Security Validation feature helps enhance security by imposing a time limit on Web pages when a user submits information to the server. When a user tries to submit information to the server after the validation time-out expires, the user receives an error message. This option is not recommended for security reasons; most of the SharePoint functionality uses Security Validation, and disable it can cause unexpected behaviors.
    2. Add a security control to the page. As explained above, a security validation has to happen after the postback; to accomplish this we need to update the server page: FormServer.aspx to include the code for the security validation control.

    Since Microsoft doesn’t have any solution to this problem yet, we got their approval to implement solution #2:

    • Go to the layouts folder under the 14 hive
    • Before making any change, do a backup of the page FormServer.aspx
    • Open the FormServer.aspx page and location the body tag with the Id PageBody:  <body runat=”server” id=”PageBody”>
    • Right after this line, insert the following line of code:

    <SharePoint:FormDigest runat=”server”/>

    • Save file and close

    That fixes the issue and now the form is working as expected.

    To be able to view the actual error messages in SharePoint the following settings have to be changed in the web application web.config file:

    • Set custom error to Off
    • Set compilation debug to True
    • Set CallStack to True

    The web.config file is located under the web application folder in drive:\inetpub\wwwroot\wss\VirtualDirectories.

    That worked fine for SharePoint 2007, however for SharePoint 2010, there is one additional configuration file that has to be modified:

    • The web.config file located in drive:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS
    • On this file, the customErrors section  has to be set to Off.

    The following error message is returned by Infopath when publishing a form to SharePoint 2010:

    The problem occurs because the site does not have a root site collection. This problem also occurs when you try to publish the InfoPath form to a site collection other than the root site collection.

    “This problem occurs because InfoPath makes a call to determine the version of SharePoint Server that is being run by the server. This call is performed as part of the publishing process, and the call is made to the root site collection. When no root site collection exists, the call cannot to determine the version of SharePoint Server that is being run by the server. Therefore, the publishing process fails.”

    To resolve this problem, create a root site collection for the SharePoint 2010 site.

    This post goes to a friend that needed to host a webpart in a page located in the _layouts folder.

    Application pages are generic pages that will not be customized, will be deployed only once per web server and will be used across multiple site collections (these pages reside in the layouts server folder).  Therefore if you need to create an application page, you either write inline code (only allowed in application pages, not in site pages) or write a code behind class. I really haven’t found a good requirement that justifies the need of a webpart inside an application page.

    Why would you need a webpart inside an application page? to me, if you need a webpart, then you’re looking for a site page, not an application page, anyways if somebody knows a good requirement for this please let me know.

    Back to the point, eventhough it is told that webparts cannot be added to application pages and that the only way to add the webpart is in the form of a web control; the truth is that you actually CAN add webparts to application pages, however you won’t be able to customize them using the browser and they can’t be inside a WebPartZone.

    If you’re adding a webpartzone with a webpart to your application page you’ll get an error “Unknown server tag WebPartZone”.

    Web parts inside an application page are called “static web parts”, and behave like normal controls; and web parts inside a webpartZone in site pages are called “Dynamic web parts” and can be added and dropped at runtime (Thanks to Serge Luca for these concepts).

    To add the web part just add it directly in MarkUp by registering the tag:

    <%@ Register TagPrefix="ABC" Namespace="Namespace" Assembly="Assembly" %>
    

    and directly adding the web part,

    <ABC:ClassName ID="ControlID" FrameType="None" runat="server" __WebPartId="YouWebPartGUID" WebPart="true" />

    As an example the next is an application page that contains a Content Editor Web Part:

    And this is how the page looks:

    hey Chris! I’m still waiting for the good business requirement of this! :)

    Never thought it would take me about an hour to delete a Record library…

    I was trying to delete a Record library and the delete option is not part of the library site settings as with any other type of library or list.

    This is the first time I work with Record libraries so I found it interesting. I tried using SharePoint Designer and got the error “List cannot be deleted”.  I was an administrator and the library had some documents so I thought maybe I had to delete first all documents and then try to delete it.

    When trying to delete documents from the library and I kept getting this error: “The item cannot be deleted, moved, or renamed because it is either on hold or is a record which blocks deletion”

    Turns out that when you create a Record library, by default it declares all items in the Library as records (which makes sense because it is a Record library right?), and a record cannot be deleted. So if you are planning to delete records from a Record library it is better to go to “Record declaration settings” (under the library site settings) and uncheck the “Automatically declare items as records when they are added to this list”.

    If you however didn’t do this and want to delete an existing document record, go to “Record declaration settings” (under the library site settings), uncheck the “Automatically declare items as records when they are added to this list”, and check the “Always allow the manual declaration of records”.

    By doing this you are now able to undeclared a record as a record, and then be able to delete it.

    To undeclared a record:

    Under the record context menu, select “Compliance Details”

    You will see the status of the record, whether if it is on hold or not and wheter if it is a record or not. To be able to delete remove all any holds and “Undeclare record”.

    Close the window and now try to delete the document; it will be deleted :)

    Great! So the library is now empty and I still can’t delete it :S

    Well, the job “Hold Processing and Reporting” takes care of scanning libraries to find records and to know what libraries what records or not. So we have to run this job for SharePoint to know that the library doesn’t have any records.

    After running the job I go to the Library settings and the delete option is there!!! Finally!!!

    With the arrival of the Managed Metadata Service in SharePoint 2010 we know how useful and powerful this concept is to centrally define and manage terms that will be used as attributes for items in
    SharePoint.

    Using the Term Store in central Admin to create terms is very easy and straight forward. Creating Managed Metadata coulmns using the UI and adding items that use these columns is also a very easy.
    However when it comes to managing the Managed metadata service from the client side, what are out options?

    Unfortunately the SharePoint client object model does not support working with MMS taxonomy, fortunately SharePoint provides a web service to wotk with managed metadata: TaxonomyClientService.
    The TaxonomyClientService  provides the following methods:

      – AddTerms
      - GetChildTermsInTerm
      - GetChildTermsInTermSet
      - GetKeywordTermsByGuids
      - GetTermSets
      - GetTermsByLabel
    As you can see it does not provide a way to update or delete existing Terms.

    Creating Terms with the Client Object Model

    To add one or more terms to the term store we have to use the TaxonomyClientService.AddTerms() method,  this methos takes the following parameters:

    [WebMethodAttribute]
    public string AddTerms( Guid sharedServiceId, Guid termSetId, int lcid, string newTerms )

    • SharedServiceId. TermStore Id of TermSet to add Term in. Type: Guid
    • termSetId. Id of the TermSet that will contain the new term. Type: Guid
    • lid. The language that the label will be added in. Type: Int
    • newTerms. The XML of the new terms to be added. Type: String

    The XML for the newTerms parameter has to be in the following format:

    <newterms>
    <NewTerm label=\”TermValue1\” clientId=\”34\” parentTermid=\”8195c6aa-ce94-4588-9725-33cf96e82bcc\”></NewTerm>
    <NewTerm label=\”TermValue2\” clientId=\”34\” parentTermid=\”8195c6aa-ce94-4588-9725-33cf96e82bcc\”></NewTerm>
    </newterms>

    Using the Method:

    The method returns the GUID (in a string form) of the newly added Term.

    Get Terms with the Client Object Model

    To get a collection of all terms from the a TermSet we can use the TaxonomyClientService.GetTermSets() method, it takes the following parameters:

    [WebMethodAttribute]
    public string GetTermSets(string sharedServiceIds, string termSetIds, int lcid, string clientTimeStamps, string clientVersions, out string serverTermSetTimeStampXml)

    • sharedServiceIds. The ID of the Term Store. Type: String
    • termSetIds. The ID of the Term set to get the terms from. Type: String
    • lcid. LCID of language that labels will be returned in. Type: Int
    • clientTimeStamps. Collection of TimeStamps which are the last edit time of TermSets stored on the client. Type: String
    • clientVersions. Collection of versions of the server that each TermSet was downloaded from (always 1 unless the client doesn’t have the TermSet, then it is 0). Type: String
    • serverTermSetTimeStampXml. Returns the collection of TimeStamps of the last edit time of each TermSet. Type: String

    Using the method:

    The output is in the form:

    The definition of this XML is: (thanks to Solid Quality)

    Container: Container for all TermStores retrieved
    TermStore: Term store retrieved by ID
    TS: Term set retrieved by ID
    a9: TermSet ID
    a11: TermSet description
    a16: Submision Policy –> true = Open, false =Closed
    a12: TermSet name
    a68: TermSet contact email
    T: Term
    a9: Term ID
    LS: Label Set. Set of synonyms for Term
    TL: Label Term
    a32: Label name
    DS: Set of descriptions
    TD: Term description
    a11: Description text
    TMS: More information about Term Set
    TM:
    a24: TermSet Id
    a12: TermSet name
    a69: True of false. This term has children terms?. If true then appear a69 attribute, else don’t appear it.
    a25: Parent Term ID

    You can parse this html to get the term data that you’re looking for; for example if you’re looking for the term GUID:

    And that’s how we work with the Taxonomy MMS remotely, not as easy as using central admin but at least we have an option for working remotely.

    Cheers
    K

    SharePoint 2010 Certification Path

    If you’ve worked with the data form web part (or as some people call it: the data view web part, lol), you’ve probably noticed that if you enable “Sorting and Filtering on column headers” in the data view properties, it doesn’t actually behave as expected: Yes, it enables sorting and filtering in your columns, but if your columns are of a numeric type, then the sorting doesn’t actually work, it sorts all columns as if they were of a string type.

    Let’s take for example the ID field of a list items, the ID is an integer field. Now let’s create a DVWP to display the items from a list, including the ID, and then enable sorting. Now let’s sort the ID column and we notice that it is sorted in a wrong way, it is sorted as a string and not as a number.

    Well, this is a “bug” in the DVWP, by default it will always sort all columns as strings, if you want to fix this you have to do some extra work in the DVWP code. So this is what happens:
    First let’s remember how sorting works in XSLT: to sort we have to use the element. This element has the property “data-type”, this property specifies if the output should be sorted as text or as a number. As an example if we want to sort the ID field as a number we have to write this xslt code:

    Now, let’s go back to the DVWP sorting. When you enable sorting, the DVWP adds to the page some xslt code, including the following xsl parameter: text

    If you look at your xslt parameters you will see it in there, this parameter will be used as the data-type property for the element. We can see that the default value is text, so it doesn’t matter what type of field you sort, it will always be sorted as a string.
    This parameter is used Inside the “dvt_1.body” template :

    The way to solve this issue is to add a condition inside the template and verify which field is being sorted and depending on the field you specify “text” or “number” to the data-type property. This way your “dvt_1.body” template should look like this:

    Now the ID is sorted as a number:

    K

    Basically this error refers to a permissions issue in the SharePoint server files (12 or 14 hive). Read your SharePoint logs and you’ll see some “Access Denied” entries like this one:

    The server extensions were unable to access the file “schema.xml”. Please check the file permissions.

    To fix this error, go to the SharePoint files (C:\Program Files\Common Files\Microsoft Shared\web server extensions\(12/14)), right click on the “Features” folder and in the advance properties from the security tab check the “Allow inheritable permissions…”. This will give all subfolders the appropiate permissions.

    Phil Wicklund has a detailed description about this error.

    K

    I’m working on a Silverlight application that makes calls to WCF services to work with data, and today I ran into this error:

    System.ServiceModel.CommunicationException: An error occurred while trying to make a request to URI ‘http://SharePointDev:4444/_wcf/WCF_Services.svc’.
    This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services.
    You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent.
    This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute.
    Please see the inner exception for more details.
    —> System.Security.SecurityException —> System.Security.SecurityException: Security error.

    I remembered I had this issue some time ago and nonetheless I didn’t remember what the problem was or what the solution was, even thought the error is self explanatory…
    So after wasting time researching I found on the internet the solution, so this time I’m writing about it for my records. Dang! I’m a 25 year old with a memory of a 60 year old (with all the respect for the 60 year old people out there :-) …) hehe, I don’t like to waste time on these little errors, specially when I’m as busy as today.

    Anyway, the solution is the “clientaccesspolicy.xml” file. The error has to do with the cross-domain policy. We have to explicitly grant cross domain access to Silverlight (even if you are working with local apps), and the way to do it is by adding the “clientaccesspolicy.xml” file to the root level of the WCF service.

    Since my WCF is hosted in SharePoint and it is using a virtual path, Silverlight was looking for the file at the root level and not at the virtual path level, so you also have to take this in consideration. This is the blog that helped me with this issue for a better reference

    K