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!

3 Answers 3

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

8
  • Thanks for the answer. However, for now I am stuck with a Bad Request 400. Any idea how to resolve? Dec 9, 2013 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, 2013 at 14:40
  • Arrgghh. Our SharePoint SA changed the authentication mechanism on the SharePoint site. Dec 9, 2013 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, 2013 at 16:10
  • *or generically that the ClientContext has enough permissions (via custom credentials, process account or impersonation)
    – thomius
    Dec 9, 2013 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);
4
  • 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. Dec 9, 2013 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. Dec 9, 2013 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. Dec 9, 2013 at 20:48
  • Hi Niam. I agree. I am going with the CSOM method. However, for references I've posted my working code below. Dec 9, 2013 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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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