.NET Framework下DataGridView绑定DataTable出现未指定多余列问题
问题原因
SharePoint Client Object Model 返回的ListItem.FieldValues会包含大量内置系统字段(比如你遇到的_ModerationStatus、_Level、ScopeId等),这些是列表默认自带的隐藏字段——哪怕你在CAML的ViewFields里指定了仅返回特定字段,FieldValues里依然会包含这些系统字段。你代码里直接遍历collListItem[0].FieldValues.Keys创建DataTable列,自然会把这些额外字段也加进去。
解决方法
方案1:手动添加需要的列(最可靠)
直接在DataTable里创建你需要的Ref和Name列,不要遍历所有FieldValues的Key,从根源避免引入额外列:
private void button1_Click(object sender, EventArgs e) { string siteUrl = ConfigurationManager.AppSettings["SiteUrl"]; string clientID = ConfigurationManager.AppSettings["ClientId"]; string clientSecret = ConfigurationManager.AppSettings["ClientSecret"]; using (ClientContext cc = new AuthenticationManager().GetACSAppOnlyContext(siteUrl, clientID, clientSecret)) { Web site = cc.Web; List targetList = site.Lists.GetByTitle("ListOne"); DataTable dtData = new DataTable(); // 手动添加需要的列,替换原遍历FieldValues的逻辑 dtData.Columns.Add("Ref"); dtData.Columns.Add("Name"); CamlQuery query = new CamlQuery(); // 修正CAML语法:FieldRef的Name属性必须加引号 query.ViewXml = @"<View> <Query><Where><Contains><FieldRef Name='Name' /><Value Type='Text'>House</Value> </Contains></Where></Query> <ViewFields> <FieldRef Name='Ref' /> <FieldRef Name='Name' /> </ViewFields> </View>"; ListItemCollection collListItem = targetList.GetItems(query); cc.Load(collListItem); cc.ExecuteQuery(); foreach (var item in collListItem) { DataRow dr = dtData.NewRow(); dr["Ref"] = item["Ref"]; dr["Name"] = item["Name"]; dtData.Rows.Add(dr); } dgvTest.DataSource = dtData; } }
方案2:动态指定需要的字段(适合需扩展的场景)
如果后续可能需要添加更多字段,可以先定义需要的字段列表,再基于这个列表创建列和赋值:
// 定义需要的字段列表 List<string> requiredFields = new List<string> { "Ref", "Name" }; DataTable dtData = new DataTable(); // 基于列表创建列 foreach (var field in requiredFields) { dtData.Columns.Add(field); } // 填充数据时遍历列表赋值 foreach (var item in collListItem) { DataRow dr = dtData.NewRow(); foreach (var field in requiredFields) { dr[field] = item[field]; } dtData.Rows.Add(dr); }
方案3:过滤系统字段(不推荐,可能有遗漏)
如果想保留动态列但过滤系统字段,可以通过字段名前缀判断(大部分系统字段以下划线开头),但这种方式可能漏掉一些非下划线开头的系统字段:
foreach (var field in collListItem[0].FieldValues.Keys.Where(k => !k.StartsWith("_"))) { dtData.Columns.Add(field); }
另外注意:你原代码里的CAML存在语法错误——FieldRef Name=Ref缺少引号,必须改成FieldRef Name='Ref',否则可能导致CAML解析失败。
内容的提问来源于stack exchange,提问作者CGarden
相关产品推荐
相关产品推荐

