0

This issue seems like it should be very easy to resolve, however it has taken hours and makes no sense.

Case:

Custom application page with simple form fields. When the form is filled out by user, it should create a content database and site collection.

Unfortunately I receive access denied.

Code:

using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Administration;
using System.Net.Mail;
using Microsoft.SharePoint.Utilities;
using System.Web;
using System.Text;
using System.Collections.Specialized;
using System.Globalization;
using System.Web.UI.WebControls;

namespace Vision.Layouts.Vision
{
    public partial class CreateSite : LayoutsPageBase
    {
        // security trim the page
        protected override void OnInit(EventArgs e)
        {
            SPWeb web = SPContext.Current.Web;
            if (!web.DoesUserHavePermissions(SPBasePermissions.FullMask))
            {
                SPUtility.Redirect(SPUtility.AccessDeniedPage, SPRedirectFlags.RelativeToLayoutsPage, HttpContext.Current);
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if(!Page.IsPostBack)
            {
                siteTitle.Text = null;
            }
        }

        protected void CreateSite_Click(object sender, EventArgs e)
        {
            if(Page.IsValid)
            {
                SPUtility.ValidateFormDigest();

                using (SmtpClient client = new SmtpClient("emailserver", 25))
                {
                    try
                    {
                        var spsiteTitle = HttpUtility.HtmlEncode(siteTitle.Text);
                        var spsiteUrl = string.Concat(siteManagedPath.SelectedValue, "/", spsiteTitle.Trim().ToLower());
                        var spsiteDescription = HttpUtility.HtmlEncode(siteDescription.Text);

                        // create the site and content database
                        SPSecurity.RunWithElevatedPrivileges(delegate ()
                        {
                            CreateSite(spsiteTitle, spsiteUrl, spsiteDescription);
                        });

                        // set email properties
                        MailAddress fromAddress = new MailAddress("xxxx", "xxxx");
                        MailAddress toAddress = new MailAddress("xxxx");
                        string subject = "New Site Created";
                        string url = string.Concat("xxxx", siteManagedPath.SelectedValue, "/", siteTitle.Text.ToLower());

                        StringBuilder body = new StringBuilder();
                        body.Append("<div style='font-family:Segoe UI,Avenir,Helvetica,sans-serif;font-size:13px;'>");
                        body.Append("<p>New site <a href='" + url + "'>" + spsiteTitle + "</a> was successfully created.</p>");
                        body.Append("<p>For assistance using SharePoint, please visit our help site <a href='xxxx'>xxxx</a>");
                        body.Append("</div>");

                        // compose the message
                        MailMessage message = new MailMessage();
                        message.To.Add(toAddress);
                        message.From = fromAddress;
                        message.Subject = subject;
                        message.IsBodyHtml = true;
                        message.Body = body.ToString();

                        client.Send(message);
                        message.Dispose();
                        Response.Redirect(Request.RawUrl);
                    }
                    catch (Exception error)
                    {
                        trace.Controls.Add(new Literal()
                        {
                            Text = string.Format("<b>Message:</b> {0} <br><br> <b>Source:</b> {1}", error.Message, error.StackTrace)
                        });
                        trace.Attributes.Add("class", "layer stacktrace is-visible");
                    }
                }
            }
        }

        private void CreateSite(string title, string url, string description)
        {
            try
            {
                Uri uri = new Uri("xxxx");
                SPWebApplication webapp = SPWebApplication.Lookup(uri);
                SPContentDatabaseCollection databases = webapp.ContentDatabases;
                var culture = new CultureInfo("en-US", false).TextInfo;

                foreach (var db in databases)
                {
                    var dbname = string.Concat("Content-", culture.ToTitleCase(title.Trim()));

                    if (!db.Name.Equals(dbname))
                    {
                        var contentdb = databases.Add("DB_SERVER", dbname, null, null, 0, 1, 0);
                        contentdb.Update();
                        webapp.Update();

                        uint lcid = 1033;
                        string template = "STS#0";
                        string ownerLogin = "xxxx";
                        string ownerName = "xxxx";
                        string ownerEmail = "xxxx";

                        var newSite = contentdb.Sites.Add(url, title, description, lcid, template, ownerLogin, ownerName, ownerEmail);
                        SPQuota quota = new SPQuota();
                        quota.StorageMaximumLevel = 20000000;
                        quota.StorageWarningLevel = 19000000;
                        newSite.Quota = quota;

                        newSite.RootWeb.Update();
                        contentdb.Update();
                    }
                }
            }
            catch (Exception error)
            {
                trace.Controls.Add(new Literal()
                {
                    Text = string.Format("<b>Message:</b> {0} <br><br> <b>Source:</b> {1}", error.Message, error.StackTrace)
                });
                trace.Attributes.Add("class", "layer stacktrace is-visible");
            }

        }
    }
}

I tried adding this to bypass the SharePoint remote administration security block:

SPWebService service = SPWebService.ContentService;
service.RemoteAdministratorAccessDenied = false;
service.Update();

Doesn't work. Interesting enough, I get Access Denied running the previous block of code.

Nice one, SharePoint.

It looks like the same situation has been posted before, but the solution is a one line answer which helps nobody.

Programmatically create content database in C# (SP 2013)

Somebody out there has a solution for this issue.

  • is your code running under the Farm admin context? – Waqas Sarwar MVP Feb 20 '18 at 21:53
  • The web app pool is running under the farm account identity, so yes. – psdpainter Feb 20 '18 at 22:05
0

Creating content database required higher level permission i.e. db creator and security admin. simply app pool account do not have these permission on the SQL server.

So try to use farm admin account or run the code under farm admin account.

https://social.msdn.microsoft.com/Forums/en-US/53aa56c7-75ef-488f-8077-8907fc4fb051/error-adding-a-content-database-to-a-web-app-programatically?forum=sharepointdevelopmentprevious

|improve this answer|||||
  • The account identity of the app pool is the farm account with db_creator and securityadmin privileges. – psdpainter Feb 20 '18 at 22:11

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.