从SharePoint列表填充DataGrid时遇PropertyOrFieldNotInitializedException错误求助
嘿,这个问题我之前也踩过坑!你遇到的PropertyOrFieldNotInitializedException本质是SharePoint客户端对象模型(CSOM)的特性导致的——默认情况下,它不会自动加载ListItem的所有属性值,必须显式指定你需要获取的字段,否则访问未被请求的属性就会抛出这个错误。
错误原因拆解
当你直接调用context.Load(collObj)时,CSOM只会加载ListItem对象的基础框架,不会加载具体的字段数据(比如Id、Title或者自定义字段)。只有当你明确告诉它要加载哪些字段,并且执行ExecuteQuery()从服务器拉取数据后,这些字段的值才会被初始化,你才能安全访问。
解决方案步骤
显式声明需要加载的字段
在Load方法里使用Include扩展方法,列出你需要用到的所有字段(包括系统字段和自定义字段)。确保执行查询获取数据
一定要在访问ListItem属性之前调用context.ExecuteQuery(),这一步是触发服务器请求,把你指定的字段数据拉取到本地。
修正后的代码示例
结合你提供的代码片段,调整后的完整代码应该是这样的:
using (ClientContext context = new ClientContext("你的SharePoint站点URL")) { // 获取目标列表 List spList = context.Web.Lists.GetByTitle("你的列表名称"); // 构建查询(这里用全量查询,你可以根据需求修改CAML) CamlQuery query = CamlQuery.CreateAllItemsQuery(); ListItemCollection collObj = spList.GetItems(query); // 关键:显式声明需要加载的字段,替换成你实际要用的字段 context.Load(collObj, items => items.Include( item => item.Id, item => item["Title"], // 系统字段示例 item => item["你的自定义字段内部名称"] // 自定义字段示例 )); // 执行请求,从SharePoint服务器拉取数据 context.ExecuteQuery(); if (collObj.Count != 0) { DataTable dt = new DataTable(); // 对应加载的字段创建DataTable列 dt.Columns.Add(new DataColumn("Id", typeof(int))); dt.Columns.Add(new DataColumn("Title", typeof(string))); dt.Columns.Add(new DataColumn("自定义字段", typeof(string))); foreach (ListItem item in collObj) { DataRow dRow = dt.NewRow(); // 现在访问这些字段就不会报错了 dRow["Id"] = item.Id; dRow["Title"] = item["Title"]?.ToString(); dRow["自定义字段"] = item["你的自定义字段内部名称"]?.ToString(); dt.Rows.Add(dRow); } // 绑定到DataGrid yourDataGridControl.DataSource = dt; yourDataGridControl.DataBind(); } }
额外注意事项
- 字段要用内部名称:自定义字段的显示名称和内部名称可能不一样(比如显示名称是"客户名称",内部名称可能是"Customer_x0020_Name"),一定要用内部名称才能正确获取值。可以在列表设置的字段编辑页面URL里找到内部名称(URL中
Field=后面的部分)。 - 避免加载不必要的字段:如果用
IncludeWithDefaultProperties()可以加载默认字段,但为了性能,最好只加载你实际需要用到的字段。 - 检查ExecuteQuery的时机:必须在遍历ListItem集合、访问字段之前执行
ExecuteQuery(),否则数据还没从服务器拉取,自然会报错。
内容的提问来源于stack exchange,提问作者Joselito Aliño
相关产品推荐
相关产品推荐

