5

I am currently trying to write a Dynamics CRM 2011 plugin that creates a new SharePoint 2010 site (within an existing site collection) for every account that is created. I have the code for creating a library, which uses the following methods:

private static ClientContext CreateSharePointConnection()
        {
            try
            {
                Uri spSiteUrl = new Uri(Constants.SharePointSiteName);
                using (ClientContext spcontext = new ClientContext(spSiteUrl))
                {
                    spcontext.Credentials
                        = new System.Net.NetworkCredential(Constants.UserName
                            , Constants.Password, Constants.DomainName);
                    return spcontext;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("SharePointMethods.CreateSharePointConnection (General Exception: "
                    + ex.Message + ")");
            }
        }

private static void CreateDocumentLibrary(ClientContext _clientContext
            , string _documentLibraryName, string _documentLibraryDescription)
        {
            try
            {
                Web web = _clientContext.Web;
                _clientContext.Load(web);
                _clientContext.ExecuteQuery();
                ListCreationInformation lci = new ListCreationInformation();
                lci.Title = _documentLibraryName;
                lci.Description = _documentLibraryDescription;
                lci.TemplateType = 101;
                List newDocumentLibrary = web.Lists.Add(lci);
                newDocumentLibrary.ContentTypesEnabled = true;
                newDocumentLibrary.Update();
                _clientContext.ExecuteQuery();
            }
            catch (Exception ex)
            {
                throw new Exception("SharePointMethods.CreateDocumentLibrary('" + _documentLibraryName
                    + "') (General Exception: " + ex.Message + ")");
            }
        }

So I would like to write a method CreateSite instead of CreateDocumentLibrary. However, all examples I can find on the web for programmatically creating a Site are using SPSite, SPWeb, etc. Something like this:

private static void CreateSite(string _siteName, string _siteDescription)
{
    try
    {
        SPSite site = new SPSite(Constants.SharePointSiteName);
        SPWeb web = site.OpenWeb();
        SPWebCollection wc = web.Webs;
        string siteTemplate = web.WebTemplate;
        wc.Add(Constants.SharePointSiteName, _siteName, _siteDescription, 1043, siteTemplate, true, false);
    }
    catch (Exception ex)
    {
        throw new Exception("SharePointMethods.CreateSite('" + _siteName
            + "') (General Exception: " + ex.Message + ")");
    }
}

However this is NOT a solution for my problem, because the SPSite, SPWeb, etc. only work on the local machine and I want to create a Site from a remote (in my case CRM) server. Anyone got an idea how to solve this.

PS: Code might still contain memory leaks, so please be carful when you use it for production purposes!

6
Web web = clientContext.Web;
var subWebInfo = new WebCreationInformation
{
    Description = "",
    Language = 1033,
    Title = "Sub Site",
    Url = "subsite",
    UseSamePermissionsAsParentSite = true,
    WebTemplate = "STS#0"
};
Web subWeb = web.Webs.Add(subWebInfo);
clientContext.Load(subWeb);
clientContext.ExecuteQuery();

Works also without specifying the WebTemplate. Out-of-the-box web templates: http://blogs.technet.com/b/praveenh/archive/2013/04/04/get-a-list-of-web-templates-and-ids-in-a-sharepoint-site.aspx

Using a custom template as {Guid}#TemplateName https://stackoverflow.com/questions/3240967/sharepoint-2010-create-site-from-code-using-custom-site-template

List available custom templates using CSOM: http://yeshagrawal.blogspot.in/2013/06/sharepoint-2013-get-all-site-templates.html

Language codes (if language packs are installed): http://technet.microsoft.com/en-us/library/ff463597.aspx

  • Thanks for the answer. However, for now I am stuck with a Bad Request 400. Any idea how to resolve? – Martijn Burger Dec 9 '13 at 10:37
  • Can you run other CSOM / does the problem occur only with the above code? Also try to first ExecuteQuery on the selected ClientContext Web, and see if that works fine. Can you see more information in the ULS logs of the SP server? – thomius Dec 9 '13 at 14:40
  • Arrgghh. Our SharePoint SA changed the authentication mechanism on the SharePoint site. – Martijn Burger Dec 9 '13 at 15:56
  • ok. does it work now? so if it's Windows/ntlm you could ensure enough permissions rights to the top level site collection for CRM plugin process account (so SP allows you to create the subsite). – thomius Dec 9 '13 at 16:10
  • *or generically that the ClientContext has enough permissions (via custom credentials, process account or impersonation) – thomius Dec 9 '13 at 16:17
2

Another way is by using Meetings.asmx service

After you initialize a new instance of the service and set up the credentials you can call

XmlNode xnode= myService.CreateWorkspace("siteName", "siteTemplateName", culture, timeZoneInf);
  • Hi Naim, thanks for the solution. However, because this is a plugin in Dynamics CRM, I prefer the solution from thomius, because it does not require setting up webservices in the .config of the CRM server. – Martijn Burger Dec 9 '13 at 10:45
  • Hi Niam, I tested your solution. First I had to use System.Xml.Linq.Xelement instead of System.Xml.XmlNode. Further, I want to create a subsite in a "sub" sitecollection. Although I am calling the webservice on http://<mysite>/<mysitecollection>/ the site is created on http://<mysite>/ and not in the site collection. – Martijn Burger Dec 9 '13 at 13:36
  • I have used this webservice without problems in the past. First I have used it with MOSS 2007 (there was no CSOM at that time), and later also with SP 2010. Since you want to avoid the use of the webservcie I think the CSOM way will work as well. – Naim Murati Dec 9 '13 at 20:48
  • Hi Niam. I agree. I am going with the CSOM method. However, for references I've posted my working code below. – Martijn Burger Dec 9 '13 at 21:34
1

Here's the complete code I used based on Naim's solution. Code is working, however, because this solution needs to edit the web.config this is not preferable for a CRM plugin:

private static void CreateSiteViaWebservice(string _siteName)
{
    try
    {
        using (MeetingsService.MeetingsSoapClient proxy = new MeetingsService.MeetingsSoapClient())
        {
            proxy.ClientCredentials.Windows.ClientCredential
                = new System.Net.NetworkCredential(Constants.UserName
                    , Constants.Password, Constants.DomainName);
            proxy.ClientCredentials.Windows.AllowedImpersonationLevel
                = System.Security.Principal.TokenImpersonationLevel.Impersonation;
            MeetingsService.TimeZoneInf tz = new MeetingsService.TimeZoneInf();
            tz.standardDate = new MeetingsService.SysTime();
            tz.daylightDate = new MeetingsService.SysTime();
            proxy.CreateWorkspace(_siteName, Constants.TemplateName, Constants.Lcid, tz);
        }
    }
    catch (Exception ex)
    {
        throw new Exception("SharePointMethods.CreateSite('" + _siteName
            + "') (General Exception: " + ex.Message + ")");
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.