You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 01:39:40