- Get the template name and ID for a web site:
(Get-SPWeb http://website) | select WebTemplate, WebTemplateID
A list of templates names and ID's can be found here: http://technet.microsoft.com/en-us/library/ff607979(v=office.14).aspx.
Friday, April 11, 2014
My SharePoint PowerShell Scripts
Thursday, April 10, 2014
How to Install SharePoint 2013 Project Templates on Visual Studio 2012
- Download and install Web Platform Installer: http://www.microsoft.com/web/downloads/platform.aspx.
- Close all VS instances or the setup will fail.
- On the Web PI select "Microsoft Office Developer Tools for Visual Studio 2012".
Monday, March 24, 2014
SharePoint 2013: Configure user profile synchronization service
- Follow the article "Synchronize user and group profiles in SharePoint Server 2013" (http://technet.microsoft.com/en-us/library/ee721049(v=office.15).aspx). Notice that the synchronization account must be Farm Admin, and local admin on the box running the UPSS instance.
- Use ADSI Edit on the DC to give "Replicate Directory Changes" permission to the synchronization account on the container where your users are.
- My test domain had no Exchange or other similar mail server program, so the AD attribute "proxyAddress" was blank. By default SharePoint loads an user e-mail address from this attribute, so I had to remap SharePoint "Work E-Mail" property to the "mail" attribute on AD (which I already had filled). Then run a full synchronization (an incremental one did not load the values).
GB
Wednesday, November 13, 2013
Saving InfoPath form back to subfolder in SharePoint library
public void FormEvents_Submit(object sender, SubmitEventArgs e)
{
// Retrieves reference to the form in the SharePoint library based on its URL
SPListItem item = SPContext.Current.Web.GetListItem(this.Uri);
// Saves the form. There must be a connection on the form named “SaveFile”, pointing to the
// SharePoint library. In the following code the connection generates the file name, but if the file
// name must be generated at run-time, it can be set through FileSubmitConnection.FileName
FileSubmitConnection spConnection = (FileSubmitConnection)this.DataConnections["SaveFile"];
spConnection.FolderUrl = item.Web.Url + item.File.ParentFolder.ServerRelativeUrl;
spConnection.Execute();
e.CancelableArgs.Cancel = false; // Tells InfoPath that form submit was ok
}
Friday, December 23, 2011
Queue names restrictions on Azure Storage
We got the exception “One of the request inputs is out of range” using a queue to link web and worker roles on Azure. Of course my little prof-of-concept test with code copy-and-pasted from the Azure Tranning Kit ran ok, but the (almost) same code on my app did not. After some time I noticed that the exception was generated when I used upper-case letters on the queue name. Well, the rules for naming queues on Azure are here, but basically they are:
- Names can be made of letters, digits and the dash char (-).
- First and last chars must be letters ou digits. Consecutive dashes are not allowed.
- All letters must be lower case. (Come on, man. You have this kind of restriction and it’s not documented on the API help? Put it in the CloudQueueClient constructor, or in CloudQueueClient.GetQueueReference(), which receives the name of the queue, or at least in CloudQueue.CreateIfNotExists(), since this method creates the queue… :-P)
- The queue name length must be between 3 and 63 chars.
Wednesday, July 20, 2011
ReportViewer: Another Reason to “Sys.ArgumentNullException: Value cannot be null. Parameter name: panelsCreated[..]”
If you are stuck with a blank screen when using the ReportViewer control that ships with Visual Studio 2010, check if you provided values for all the parameters in the report. We created a report using {CTRL+C CTRL+V} on an existing report, and the second report used only 3 of the 4 parameters on the original report. We did not provide any value to the last parameter, and it had no default value configured, so the ReportViewer rendered a blank panel on the web form, and generated the following JavaScript error:
Sys.ArgumentNullException: Value cannot be null. Parameter name: panelsCreated[1]
When we edited the report's RDLC file (I could not find the "Report Parameters" menu option that should be under the “Report” menu in Visual Studio, so I opened the RDLC file using Visual Studio XML Editor), and took off the unused parameter defition, the ReportViewer rendered ok. Thanks to this post for pointing me to the right direction.
Wednesday, October 13, 2010
Azure Tables Error Messages
Azure Table Storage (ATS) is a REST-basead data access mechanism, and REST is based on HTTP. So, makes sense that ATS data access errors are returned as HTTP errors. But some translation is needed to understand those errors.
1. DataServiceRequestException and DataServiceClientException exceptions
When a data access error occurs in ATS, the exception returned usually is from DataServiceRequestException class, being the error message “An error ocurred while processing this request”. This exception encapsulates a more specific DataServiceClientException exception, that contains a XML document on the Message property describing the error:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code>EntityAlreadyExists</code>
<message xml:lang="pt-BR">The specified entity already exists.</message>
</error>The value on the <code> element needs to be interpreted considering what the application was doing when the error ocurred. For example, the code InvalidInput is generated if you are trying to save an entity that has a property of an unsupported data type; OR if you are trying to update an entity that has no concurrency control information. Almost the same, right? ;-)
2. Error codes an possible causes
Following are the HTTP error code that we’ve bumped into, and what the application was trying do do when the error ocurred.
Error Code
(value on <code> element)Possible Causes ConditionNotMet - Concurrency error. The app read some entity; when trying to modify or delete the entity, it had already been modified by a command from another data context. EntityAlreadyExists - Primary key violation. The app is trying to insert an entity, but there’s an entity on the table with the same values for PartitionKey and RowKey properties on the entity being inserted. InternalError - Use of unsupported Linq operators on ATS. (We found this one trying to recover rows that had a string property starting with some value. There’s no string support for like, >, <, and neither string.StartsWith() – the one that generated the error. You have to use string.CompareTo() – :-P) InvalidInput - Storing an entity that has properties of types not supported by ATS.
- Updating an entity that was attached to the context (TableServiceContext.AttachTo()), but has null on it’s ETag property.
- Linq queries on a table with no structure defined. We received this error when trying to query a table that had just been created; if you insert some entities, even if you erase all the entities on table later, it seems that the table holds the entity structure and you can use it on Linq queries.
- Linq queries using anonymous types. The workaround was to make the query return the “whole” entity, and build a second query using anonmymous types on the data returned by ATS.
- Batch save operation (SaveChanges(SaveOptions.Batch)) with 2 or more entities having the same Partion and Row Keys.ResourceNotFound - Linq query that returns no entitites using equality conditions on PartitionKey and RowKey (where entity.PartitionKey == “…” && entity.RowKey == “…”). (Queries with conditions using other attributes return a 0-sized list)
- Concurrency error. The app read some entity; when trying to modify or delete the entity, it had already been deleted by a command from another data context.
- Linq query on a table that does not exist on ATS.TableAlreadyExists Found on calls to CloudTableClient.CreateTablesFromModel(). It seems that concurrent calls to this method may end up generating this exception. We placed a call to CreateTablesFromModel() on the data access context static constructor. When we raised the number of role instances to 2, one of them started ok, and the other one generated the exception. TableBeingDeleted Same as TableAlreadyExists above. OutOfRangeInput Generated when saving an entity with an uninitialized DateTime property. The minimum allowed value for a DateTime property on ATS is Jan 01, 1601, and an uninitialized DateTime in C# holds Jan 01, year 1. We didn’t detected it on tests against DevStorage because it changes dates before Jan 01, 1753 to Jan 01, 1753, but ATS does not.
3. How to extract the HTTP error code from DataServiceClientException objects
The code is based on an enum that has members named exactly as the error codes returned by ATS:
public enum ATSError
{
EntityAlreadyExists,
ConditionNotMet,
InvalidInput,
ResourceNotFound,
Unknown // This one is the "generic" error code
}The following method extracts the error code from the XML returned by ATS, and converts it on the correspondent ATSError enum value:
/// <summary>
/// Translates an ATS exception to one of the ATSErrors values.
/// </summary>
/// <param name="error">Exception returned by ATS.</param>
/// <returns></returns>
public static ATSError ExtractATSError(Exception e)
{
// Searches for a DataServiceClientException exception
while (!(e is System.Data.Services.Client.DataServiceClientException) && (e != null))
e = e.InnerException;
if (e == null) return ATSError.Unknown;// At this point "e" contains a DataServiceClientException object,
// and the Message property contains a valid XML document describing the error
ATSError code;
try
{
XmlDocument xml = new XmlDocument();
xml.LoadXml(e.Message);
// The XML document uses namespace http://schemas.microsoft.com/ado/2007/08/dataservices/metadata, so
// we have to use a XmlNamespaceManager to represent this namespace
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(xml.NameTable);
namespaceManager.AddNamespace("n", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
// Retrieves the "<code>" element
string s = xml.SelectSingleNode("/n:error/n:code", namespaceManager).InnerText;
// Converts the element value to the corresponding ATSError value
code = (ATSError)Enum.Parse(typeof(ATSError), s);
}
catch
{
code = ATSError.Unknown;
}
return code;
}And that’s it. If you bump into another error code, just add the corresponding member on the ATSError enum, so that the ExtractATSError() method will recognize it.

