How it works: Site categories form for site collection creation

This post is part of the Site directory troubleshooting series, you can access the other posts here.

So the focus is on the rendering and submit action of this form on the /_layouts/csignup.aspx page or /admin/createsite.aspx.

sitedir6

The major difference in the form rendering is the fact that the master site directory form is prepared to have the site directory even in another other SharePoint farm therefore local object model calls cannot be used to verify the web, list, view existence. Web service calls are used with the identity of the application pool account. In case of the /admin/createsite.aspx by default it will be the system account. On the  /_layouts/csignup.aspx page it will be the configured application pool identity. Single machine installs having network service as the default application pool account might run into permissions problems accessing master site directory on another farm due to machine accounts being used for the web service calls.

However you cannot set remote farm to be the default master site directory in central administration. You can enter a remote farm absolute url and click ok and receive no errors, but this won’t be persisted and next time you open the setting it will be unchanged. This is a side effect how SharePoint stored master site directory in the PortalService. The site id and web id stored instead of the url, and the siteid and webid looked up from the url in the local farm therefore saving a remote farm url cannot succeed. On the other hand the form rendering is fully capable of handling remote farm urls if the remote master site directory url is passed  as query string parameter.

This is the pre-requisite check process for the form rendering:

  1. Get the absolute path of the site directory subsite to be used
    1. Check if there is a query string parameter called sitedirectory passed in containing the url encoded absolute url of the site directory subweb in a site collection.
    2. If this is not specified in the query string or it is empty then SharePoint checks the PortalService instance for master site directory location data. This is stored in the configuration database.
    3. Then the site and subweb is opened using the ids retrieved in the local farm (no webservices are used here).  File not found exception is handled silently and empty string is returned for site directory url. If the site collection and web could be opened successfully, the subweb’s Url is returned. The current website’s Zone is used to retrieve this url so if you’re accessing the site collection creation page with a url from etc the Intranet zone, then the site directory url will be created using the Intranet zone as well, if there is no public url for that zone in AAM settings of the webapp of the master site directory than the default zone url will be returned.
  2. If the returned url is not null the form is displayed.
  3. SharePoint checks if the enforcement was turned on from the query string or the PortalService property and displays the checkbox accordingly.
  4. Same action to retrieve the entry requirements to decide if the user needs to specify value to all controls,only one or none.
  5. SharePoint uses $master_site_directory_url$/_vti_bin/lists.asmx using the application pool’s identity (not the logged on user’s id) to get the lists in the web. Iterates through the result and uses the title of the first list which has the site directory template type (300)
  6. Next step is to fetch the language of the subweb using the /_vti_bin/webs.asmx. Using the web’s language id SharePoint looks up the localized capture view name from a resource file. The view is called “Site Creation Categories” in English, for other languages you can check \12\resources\spscore.*.resx , it’s resource label is called SitesList_CaptureViewName_Text.
  7. If the list title or the capture title is empty, the controls won’t be added to the form.
  8. Otherwise SharePoint calls /_vti_bin/views.asmx webservice to get the view collection for the returned list title. Iterates through the result (if result is null, no control rendering) and locates the view GUID using the capture view’s title gathered in step 6.
  9. Then /_vti_bin/views.asmx webservice  is called again using the capture view GUID to get the view itself and its fields in a single call.
  10. Finally the /_vti_bin/lists.asmx webservice  is called to fetch the Sites list and its fields using the list title gathered  in step 5.
  11. Then SharePoint iterates through the fields of the capture view and looks up the same field in the list fields and renders the control for the corresponding field type:
    1. For Choice column it will be a DropDownList with the choices of the field.
    2. For MultiChoice it will be a checkbox list with the choices of the field.
    3. For Lookup field it will be a DropDownList with the values of the lookup list items. Here the /_vti_bin/lists.asmx webservice is called with the GetListItem operation to fetch the lookup list items.
    4. For Boolean field it will be a checkbox.
    5. For all other types it will be a simple textbox.
  12. If there is any problem encountered during the form field rendering depending on the error type the following line is logged into ULS if the Site Directory trace level is Medium or above:
    "CreateSiteCollectionPanel1: A SOAPServer exception occured in Site Categories panel. Setting CreateSiteCollectionPanel1 to not render. Exception: "
    "CreateSiteCollectionPanel1: An XML exception occured in Site Categories panel. Setting CreateSiteCollectionPanel1 to not render. Exception: "
    "CreateSiteCollectionPanel1: An exception occured in Site Categories panel. Setting CreateSiteCollectionPanel1 to not render. Exception: "

Note: there is a typo in the ULS log entry itself, I pasted as you will see it in the log.

On submit event depending on the entry requirements server side validation runs to check all field values or to ensure that at least one is filled out. Before the save operation all control rendering happens in the same sequence from step 5 to create the update XML with the correct field names and values which will be used in the /_vti_bin/lists.asmx webservice  in the UpdateListItems operation (again the application pool’s identity is used as in all site directory initiated webservice calls).

If there is a problem during the update XML creation , save operation can fail with "Update xml is unexpectedly empty.  No update performed." if the Site Directory category trace level is at least on Unexpected or above.

When the new list item is added in the site directory list in the site directory subweb using the webservice te following is logged in ULS if the Site Directory category trace level is at least on Medium or above (the placeholder between $ signs will be populated with real values) :

“Adding site directory item with title of "$new site collection’s title$" completed”

If there is an error during save the following line is logged into ULS if the Site Directory trace level is High or above
"CreateSiteCollectionPanel1: An exception occured in OnFormSave(). Exception: "

Note: there is a typo in the ULS log entry itself, I pasted as you will see it in the log.

Troubleshooting

If the form is not displayed on the site collection creation page 

  • First of all enable the Site Directory ULS category with Verbose trace level. You can find the cause of your form display issue with the ULS log entries. The CreateSiteCollectionPanel1 will log error messages if any of the web service calls fail.
  • Verify the full url in the sitedirectory  query string parameter if there is any in the browser’s address bar, try to remove the sitedirectory= section with the url value and try again to see if the local master site directory web can be determined automatically.
  • Verify Site directory settings in central administration website under Operations / Master Site directory settings. Enter the absolute url of the site directory subsite in the farm. The settings page does not give an error if the entered url was not created with the Site directory template so you have to open it again to verify if the path is not empty. If it is empty than the subweb you entered is not a valid site directory subsite.
  • You have to ensure that the web’s application pool identity has rights on the master site directory website. You can test it easily by logging on with that user to the SharePoint frontend and open the master site url in IE and try to add a new list entry to the Sites list.
  • You have to ensure that it is possible to access the absolute url of the master site directory from the server itself. This can be tricky since the public url can be returned of an AAM zone if the  site collection page was opened using a non-default internal url. So you have to guarantee that the server itself can resolve and connect to each public url of your web application which holds the master site directory.
    • If the public url is different from the servername, you can run into the LoopbackCheck security limitation, which will result authentication error – the server will not send any credentials to itself for unknown url. Solution: https://support.microsoft.com/kb/971382
      I suggest using the BackConnectionHostNames key if you have small number of public urls.
  • If you use external master site directory, you have to ensure that the server can resolve that url and the application pool identity of the site where you opened the create site collection page has rights on it.
  • Because by default Sharepoint uses automatic proxy server detection, you might run into proxy authentication errors or webservice call failures due to proxy usage for the local server.
    In the web.config file you can find the defaultProxy tag which controls this behavior.
    <system.net>
        <defaultProxy>
          <proxy autoDetect="true" />
        </defaultProxy>
      </system.net>
    You can turn proxy auto-detection off for the affected website to bypass default proxy usage. This will not affect the crawler’s proxy setting although it can cause problems for webparts accessing the internet (like RSS webpart).
  • Check the existence of the Sites list and the Capture.aspx view in it (“Site Creation Categories” in English, for other languages you can check \12\resources\spscore.*.resx , it’s resource label is called SitesList_CaptureViewName_Text). A view with this localized name must exists otherwise the form rendering will fail. You have to check furthermore if this view has any columns selected, since those columns will be rendered in the form.

Form submit fails and site collection is not added to the list.

  • Check ULS for the exception during list item addition.
  • Try to open the site directory list and add an item manually using the app pool identity user to verify if you receive an error. Try to resolve the error received.

Form submit succeeds and site collection is not added to the list.

  • Application pool identity has only read access to the Sites list in the master site directory and list addition webservice call fails with the following message in ULS with Medium or above trace level for Site Directory category you can spot the error:

    Adding site directory item with title of "team1" completed: <Results xmlns="https://schemas.microsoft.com/sharepoint/soap/"><Result ID="1,New"><ErrorCode>0x80070005</ErrorCode><ErrorText>The operation failed because an unexpected error occurred. (Result Code: 0x80070005)</ErrorText></Result></Results>

    0x80070005 is access denied. You might have other error code listed. Try to open the site directory list and add an item manually using the app pool identity user to verify if you receive an error as well. Try to resolve the error received.

  • Another similar error can happen when custom columns used in the Sites list were created by a feature and that feature is removed or gets corrupted on a frontend machine. The error returned in ULS looks like this with clear steps to follow:

    Adding site directory item with title of "test2" completed: <Results xmlns="https://schemas.microsoft.com/sharepoint/soap/"><Result ID="1,New"><ErrorCode>0x81020014</ErrorCode><ErrorText>One or more field types are not installed properly. Go to the list settings page to delete these fields. </ErrorText></Result></Results>

Back to the table of contents