记录一个问题的解决方法

症状

======================

无法创建新的web application (CA > Application Management > Create or extend Web application > Create a new Web application)

报错的stack:

Object reference not set to an instance of an object. at Microsoft.SharePoint.ApplicationPages.GlobalAdminPageBase.get_DefaultContentDatabaseName()
at Microsoft.SharePoint.ApplicationPages.ExtendVirtualServerPage.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

无法配置default database (CA > Operations > Default Database Server)

Object reference not set to an instance of an object. at Microsoft.SharePoint.ApplicationPages.DefaultContentDatabasePage.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

经过看Dump的步骤排查, 发现SPWebService的DefaultDatabaseInstance属性丢失了. 于是写了下面的代码进行修复尝试:

static void Main(string[] args)
{

    SPFarm ofarm = SPFarm.Local;
 
    //Get SPWebService Object
    SPWebService oservice = ofarm.Services.GetValue<SPWebService>();
 
    //Verify if the current SPDatabaseServiceInstance object is null
    SPDatabaseServiceInstance oinstance = oservice.DefaultDatabaseInstance;
 

    if (oservice.DefaultDatabaseInstance == null)
    {
        Console.WriteLine("Notice!!! SPDatabaseServiceInstance is null.");
 
        //Get DB Server SPServer object
        SPServerCollection servers = SPFarm.Local.Servers;
        SPServer oServer1 = servers["sql"]; //Replace it with our DB server name.
        ofarm.Servers.Ensure(oServer1);
 
        //Get SPDatabaseService object, we will use it as argument to create new SPDatabaseServiceInstance
        SPDatabaseService oDBService = ofarm.Services.GetValue<SPDatabaseService>("");
 
        //Create new SPDatabaseServiceInstance object, and verify it.
        SPDatabaseServiceInstance onewinstance = new SPDatabaseServiceInstance("MSSQLSERVER", oServer1, oDBService);
        oServer1.ServiceInstances.Ensure(onewinstance);
 
        //Fix the issue by assign SPDatabaseServiceInstance object to DefaultDatabaseInstance.
        oservice.DefaultDatabaseInstance = onewinstance;
        oservice.Update();
}

第二个症状解决了, 页面可以打开了. 但是在后续的测试中, 发现了其他的问题, 报错Unknown Error.

19:59.3

w3wp.exe (0x0E78)                      

0x0D28

Windows SharePoint Services  

Database                     

5586

Critical

Unknown SQL Exception 87 occured. Additional error information from SQL Server is included below.  A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 25 - Connection string is not valid)

 

后来, 我的同事Adam解决了这个问题. 方法还是使用Object Model对SPWebService的DefaultDatabaseInstance属性进行赋值.

但是不能用New的对象, 应该使用SharePoint服务器场中已经存在的对象.

对Config DB中的对象进行查询, 寻找到类型为Microsoft.SharePoint.Administration.SPDatabaseServiceInstance的对象. 注意, 如果场中有多个DB服务器的话, 需要选择寄存这Config DB的那个DB服务器.

使用下面的语句对config DB进行查询, 得到一个ID. 把这个ID作为参数传给下面的代码:

private static void Main(string[] args)
{
    string g = args[0];
    SPWebService service = SPFarm.get_Local().get_Services().GetValue<SPWebService>();
    SPDatabaseServiceInstance instance = SPFarm.get_Local().GetObject(new Guid(g));
    service.set_DefaultDatabaseInstance(instance);
    service.Update();
    Console.WriteLine("The current content web service's default database is changed to {0}", g);
}

结末的教训是:

===================

当SharePoint中某个对象的某个属性丢失的时候, 如果要通过Object Model对其赋值的话, 那么需要小心.

该属性如果是个简单类型, 比如整型, 或字符串, 那么可以直接赋掉.

如果是个对象, 那么极有可能需要用一个场中已经存在了的对象进行赋值. 我们手动创建的对象很可能缺少这样或那样的metadata.

原文地址:https://www.cnblogs.com/awpatp/p/2352653.html