Id.ValueOf在开发者控制台报错,有效ID仍提示无效(VSCode无此问题)
解决Salesforce开发者控制台中CSV静态资源ID转换的隐藏字符问题
问题情况
你上传了包含大量ID的CSV作为静态资源,在开发者控制台编写代码读取并转换为Id列表时,出现报错:
System.StringException: Invalid id: 0066700000wirvdAAA
但手动将该ID传入Id.ValueOf()能正常运行,且相同代码在VSCode中无异常。尝试过trim()、替换换行/引号等操作,仍无法解决问题,显然是存在看不见的控制字符干扰。
根本原因
大概率是你的CSV文件带有UTF-8 BOM(字节顺序标记)——这是一个藏在文件开头的不可见控制字符,开发者控制台读取时不会自动处理,导致split后的第一行字符串携带该字符,触发ID校验失败。而VSCode会自动忽略BOM,因此运行正常。
解决办法
给你两种实用的处理方案:
方案1:直接移除UTF-8 BOM
获取静态资源内容后,先检查并移除开头的BOM字符:
StaticResource sr = [SELECT body FROM StaticResource WHERE Name = 'MY_RESOURCE' LIMIT 1]; String body = sr.Body.toString(); // 检查并移除UTF-8 BOM标记 if (body.startsWith('\uFEFF')) { body = body.substring(1); } String[] filelines = body.split('\r\n'); List<Id> opps = new List<Id>(); for (String line : filelines) { String cleanId = line.trim(); if (String.isNotBlank(cleanId)) { opps.add(Id.valueOf(cleanId)); } }
方案2:用正则精准提取合法ID
直接匹配Salesforce ID的格式(15或18位字母数字),彻底避开无关字符干扰:
StaticResource sr = [SELECT body FROM StaticResource WHERE Name = 'MY_RESOURCE' LIMIT 1]; String body = sr.Body.toString(); List<Id> opps = new List<Id>(); // 匹配15/18位的Salesforce ID格式 Pattern idPattern = Pattern.compile('[a-zA-Z0-9]{15,18}'); Matcher matcher = idPattern.matcher(body); while (matcher.find()) { opps.add(Id.valueOf(matcher.group())); }
验证BOM问题的方法
可以打印第一行字符串的每个字符编码,确认是否存在编码为65279的字符(即\uFEFF):
String firstLine = filelines[0]; for (Integer i = 0; i < firstLine.length(); i++) { System.debug('位置' + i + ':字符[' + firstLine.charAt(i) + '],编码:' + (int)firstLine.charAt(i)); }
如果输出中出现65279,即可确认是BOM导致的问题,使用方案1即可解决。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

