2012年2月15日

记录一个问题的解决方法

症状

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

无法创建新的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.

posted @ 2012-02-15 15:00 中道学友 阅读(42) 评论(0) 编辑

STSADM Sync 命令里的 – Ignoreisactive 标志位

一个同事遇到了一个问题, 一个MOSS 2007站点集里的部分用户的profile不会被sync.

 

最开始的时候因为这个站点集所在的content database被设为了prepare to move. 使用下面的命令修改状态.

stsadm -o preparetomove -contentdb <server name: database name> -site <URL name> –undo

 

之后就发现了部分用户的profile无法被syn的问题.

 

经过研究发现了不能被sync的用户属于没有在网站里添加过任何内容的用户. 他们是inactive的. 如何判断他们是inactive的呢? 可以检查content db里的userinfo表, 看用户行的tp_IsActive, 如果该列为1, 那么是active的.

那么问题就变成了如何让非active用户的profile也被sync.

 

答案是命令STSADM –o sync –ignoreisactive 1, 该标志位并未在Technet的文章Sync: Stsadm operation (Office SharePoint Server)里列出.

 

参考资料

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

STSADM Sync – Ignoreisactive flag

http://blogs.msdn.com/b/ronalg/archive/2010/02/22/stsadm-sync-ignoreisactive-flag.aspx

posted @ 2012-02-15 11:15 中道学友 阅读(26) 评论(0) 编辑

技术追求准确,态度积极向上