不常见报错
一、调用HiddenApi报错
There is no active transaction. This error is usually caused by custom plug-ins that ignore errors from service calls and continue processing.
汉译:
没有活动事务。此错误通常由忽略服务调用错误并继续处理的自定义插件引起。
简单方式是“重新生成”,看是否编译通过。一般是有语法错误,导致插件并没有上传成功。
其他原因:可以去掉try……catch,使其显示更清晰的报错信息。
二、数组null.Length报错
自定义页面中:
Cannot read properties of undefined (reading ‘length’)
解决方案:
下面是我的处理这种模糊问题的处理思路。(注释排除法)
一、排除 js 内的 所有的xxx.length 的 变量是否是数组类型。
二、排除 html 代码上是否引用过xxx.length 。
如果以上注释了排除还是报错的话。
还需要关注的就是 v-for ,因为代码再执行到 v-for="(item,index) in arry" 这里时,如果arry不是个数组就会导致报错 xxxx.length 找不到,因为渲染的时候会内部运行 for 循环就会用到 xxx.length。这个是不能很快直观的能处理到的隐藏问题。
三、element CheckboxGroup组件没有v-model的时候也会报错。
问题重现:
<el-table-column
prop="new_commerceforms.Name"
label="贸易方式"
sortable
align="center"
width="130"
>
<template slot-scope="scope">
<el-select
v-if="scope.row.isEdit"
v-model="scope.row.new_commerceforms.Value"
@change="new_commerceformsOnchange"
placeholder="请选择"
>
<el-option
v-for="(item,index) in scope.row.new_commerceforms.**Options**"
:key="index"
:label="item.Name"
:value="item.Value"
>
</el-option>
</el-select>
<span v-if="!scope.row.isEdit">{{
scope.row.new_commerceforms.Name
}}</span>
</template>
</el-table-column>
后台写法必须是:PicklistModel写法
三、向数据库插入数据,主键重复报错
System.Exception: 违反了 PRIMARY KEY 约束“PK_new_deliverycarBase”。不能在对象“dbo.new_deliverycarBase”中插入重复键。重复键值为 (5daf6081-2dad-4e08-88b7-0c26a462f1b4)。
解法一:
foreach (var e in ec.Entities)
{
………………
table.Rows.Clear();
foreach (var car in carec.Entities)
{
………………
table.Rows.Add(row1);
}
this.Broker.BatchInsert("new_deliverycarBase", table);
}
说明:在foreach第二次插入数据之前,需要把上一次的 Rows
数据清空,否侧会造成主键重复。
解法二: 正解
foreach (var e in ec.Entities)
{
………………
foreach (var car in carec.Entities)
{
………………
table.Rows.Add(row1);
}
}
this.Broker.BatchInsert("new_deliverycarBase", table);
说明: 累加处理完所有的Rows
数据后,在循环的外面插入数据,就不会造成主键重复了。
未能加载文件或程序集
尝试一:该报错出现在Controller调用的方法中,一般可以尝试去掉Command方法中的try{}catch(){}
尝试二:如果是出现在Command方法中,在某一个调用接口的方法处抛出错误,最大可能是,接口不通导致
正解:Json版本不匹配,或者crm.common版本不匹配等;升级版本或降级。
使用SQL查数据需配置DbDriver
报错1:ConnectionString can not be NULL
报错2:get DbSourceConfigItem error
解决办法:
查找XML的config文件:RekTec.XStudio.Data.DbSourceConfig.xml.config
添加/修改ConnectionString标签
查看标签DbSource里面的值是否与DbSourceConfigItem标签里面的Name属性值对应
案例:
<?xml version="1.0" encoding="utf-8"?>
<DbSourceConfig xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DbSource>**portal**</DbSource>
<ItemList>
<!--Portal 数据库连接字符串-->
<DbSourceConfigItem>
<Name>**portal**</Name>
<DriverType>sqlserver</DriverType>
<ConnectionString>**Password=YTp@ssw0rd;User ID=sa;Initial Catalog=ytcrmdev_MSCRM;Data Source=10.66.227.81**</ConnectionString>
<CommandTimeOut>60</CommandTimeOut>
<ConnectionTimeOut>30</ConnectionTimeOut>
</DbSourceConfigItem>
</ItemList>
</DbSourceConfig>
实例对象位置放错,导致产生重复性数据
数据查出来是两条以上,但接收的值虽然也是两条,但一直都是返回结果的最后一条,且两条数据一模一样 原因在于:在new一个model对象的时候,没有在循环里面,而是放在了外面,从而引发了数据异常。
目标数据:
YT023210903 1 3000.00
YT21096210858 1 900.00
而实际接收到的数据:为重复数据
还可以尝试用去重方法取实验,如果不起作用就可以说明这个问题。
[{
"new_customsinvoiceno": "YT21096210858",
"Tradingway": 1,
"Price": 900.0000,
"new_parentname": "new_customsclearance",
"new_entityId": "750D68F1-9A0B-EC11-A140-005056A4763A"
}, {
"new_customsinvoiceno": "YT21096210858",
"Tradingway": 1,
"Price": 900.0000,
"new_parentname": "new_customsclearance",
"new_entityId": "750D68F1-9A0B-EC11-A140-005056A4763A"
}]
解决方案:
foreach (var item in vehicleGroup)
{
FileAttachmentModel file = new FileAttachmentModel(); //必须放在循环内部,放在外部每循环一遍相当于替换一遍
file.new_customsinvoiceno = item.new_customsinvoiceno;
file.Tradingway = item.new_tradingway;
file.Price = Math.Round(item.Price, 2);
file.new_parentname = entityName;
file.new_entityId = entityId;
invoicenoList.Add(item.new_customsinvoiceno);
fileAttachmentModels.Add(file);
}
总结:
- 大多数情况下,实例化对象都必须放在循环里面。
Vue时间组件选择时间为UTC时间
如这种格式:2021/11/29T16:00:00 或者:11/29/2021 16:00:00
后端时间需要取本地时间,加8小时即可。
DateTime time = new DateTime();
bool a = DateTime.TryParse(model.new_plantime, out time);
if (a)
{
shipplan["new_plantime"] = time.ToLocalTime();
}
Log.DebugMsg("传入参数时间:" + model.new_plantime);
Log.DebugMsg("输出参数时间:" + time.ToString("yyyy-MM-dd hh:mm:ss"));
Log.DebugMsg("处理后时间ToUniversalTime:" + time.ToUniversalTime().ToLocalTime().ToString("yyyy-MM-dd hh:mm:ss"));
Log.DebugMsg("处理后时间ToLocalTime:" + time.ToLocalTime().ToString("yyyy-MM-dd hh:mm:ss"));
传入参数时间:11/29/2021 16:00:00
输出参数时间:2021-11-29 04:00:00
处理后时间ToUniversalTime:2021-11-29 04:00:00
处理后时间ToLocalTime:2021-11-30 12:00:00
SQL查CRM的时间字段少8小时
处理办法如下:
DATEADD(HH,8,new_time) --加8小时
CONVERT(varchar(12), DATEADD(HH, 8, new_date), 111 ) --去掉时分秒 2021/01/12
CONVERT(varchar(10), dateadd(HH, 8, dc.new_shipmentdate), 120) --2021-01-12
--new_time为时间字段,涉及到海外,上面的方法不能用了
--UTC时间转本地时间:
DATEADD(hour, DATEDIFF(hour,GETUTCDATE(),GETDATE()), new_time) --加8h
--本地时间转UTC时间:
DATEADD(hour, DATEDIFF(hour,GETDATE(),GETUTCDATE()), new_time)
操作流程中输入参数未添加报错
2021-11-07T13:26:28.846 plugin Error 值不能为 null。
参数名: value
程序在此处报错
NotificationFilterModel result = JsonConvert.DeserializeObject<NotificationFilterModel>(Content.Get(ExecutionContext));
使用RibbonBox时
使用Ribbonbox自定义工具时无法加载解决方案
报错信息如下:
解决方案[ZGJ_ _sIn_ flowtool]的ribbon创建失败: Error: 方法"DynamicClass.lambda method(System.Runtime.CompilerServices.Closure)"尝试访问方法"Microsof.Xrm.Sdk.Client.OrganizationServiceContext.CreateSequentialGuid0”失败。
解决办法:
选择实体的时候,把【✓】全部去掉,最后选择【否】即可。
切忌删除某些东西以保留一个目标实体,虽然看起来行,但其实不可行。
邮件提醒在消息中无法显示
可能原因如下:
代码没有报错的前提下
- 由于默认标题字符串长度为100,内容字符串长度为1000,明细中也同样如此; 当超出字符串最大限制的时候,则消息就无法显示,需手动调整长度。 在服务器中的log文件夹查看时,会出现以下报错信息:
2021-12-06 16:00:00.008 执行jobdc8e7461-0954-ec11-a13e-005056a43d65
2021-12-06 16:00:22.566 A validation error occurred. The length of the 'new_content' attribute of the 'new_notification' entity exceeded the maximum allowed length of '1000'.
邮件发送两遍处理方法:
方法一:登录服务器,重启异步服务;
方法二: 修改插件异步改为同步;
- 消息提醒默认为异步执行,可以尝试将异步改为同步,如果不行就可能是服务器异步执行有问题 插件注册步骤位置: (Assembly)RekTec.Crm.Plugin.Notification | (Plugin)RekTec.Crm.Plugin.Notification.new_remind_task_monitor | (Step)RekTec.Crm.Plugin.Remind(QGWJBGTJ_001):To Update new_liquidationattchange 默认: Asynchronous(异步) Server 改为: Synchronous(同步) Server
- 消息提醒默认为异步执行,可以尝试将异步改为同步,如果不行就可能是服务器异步执行有问题 插件注册步骤位置: (Assembly)RekTec.Crm.Plugin.Notification | (Plugin)RekTec.Crm.Plugin.Notification.new_remind_task_monitor | (Step)RekTec.Crm.Plugin.Remind(QGWJBGTJ_001):To Update new_liquidationattchange 默认: Asynchronous(异步) Server 改为: Synchronous(同步) Server
代码执行速度过慢问题:
自定义自动编号代码执行速度过慢问题
优化方案:
将**组织服务**的查询、更新数据库形式,改为**SQL**执行,速度将提升数倍不止。
解释:
组织服务处理数据库时,同时也会涉及到【权限】的控制,以及还会【触发Plugin】等,使得在循环遍历更新数据库时,
会严重拖慢程序的执行效率,因此不建议使用组织服务。
因为字段值带有空格问题。
因为导入数据的时候字段值带有空格而查询不到数据。
如果是后台代码处理数据,可以考虑加上去除前后空格方法Trim()。
单据停用时报错
签核处理及签核处理步骤停用—代码控制出现的报错
情景一:正常理解及操作,直接更改为停用
代码示例
Entity crf=new Entity("new_flowapprovalcrf", crfid);
crf["statecode"]=1;
OrganizationService.Update(crf);
删除时报错提示:
大致意思:此状态码在指定状态码中无效。
推断:写法不对,根据后面结论发现:状态描述字段也需要赋值
情景二:更改停用正确方法,常用,但可能并不通用
代码示例
SetStateRequest stepRequest = new SetStateRequest()
{
EntityMoniker = new EntityReference("new_flowapprovalcrf", crfid),
State = new OptionSetValue(1),//可用=0,停用=1
Status = new OptionSetValue(2),
//(状态描述)可用=1,停用=2
};
OrganizationServiceAdmin.Execute(stepRequest);
未注意到列表值报错:
大致意思:2不是实体(new_flowapprovalcrf)中有效状态码。
推断:可能不存在。
情景三:获取到了列表值,但与状态不匹配报错
代码示例
SetStateRequest crfRequest = new SetStateRequest()
{
EntityMoniker = new EntityReference("new_flowapprovalcrf", crfid),
State = new OptionSetValue(1),//Active=0,Inactive=1
Status = new OptionSetValue(5), //正确的是:把5改为6或7
//(Active)待签核=4,已签核=5; (Inactive)待签核==6,已签核=7
};
OrganizationServiceAdmin.Execute(crfRequest);
列表值与状态不匹配报错:
大致意思:5不是Inactive状态代码中的有效状态码
推断:可能不匹配。
注册插件时报错常见解决思路
是否接入了客户那边的VPN。
是否发生了重命名操作,是的话,需要手动取消原有已注册的插件(只取消发生重命名的文件即可),然后重新注册即可。
不间断空格
读取xml文件时,名称不能以“ ”字符(十六进制值 0x20)开头
//正确格式
<attribute name='new_money' alias='AMOUNT' aggregate='sum' />
//含特殊空格,错误格式
<attribute name="new_money" alias="money" aggregate="sum"/>
解决方法:
NotePad++ 调成XML格式,通过观察颜色来判断。 删除它们中间的特殊空格即可。
- 正确
- 错误:
不间断空格
NBSP:“**Non-Breaking Space**
” ,不间断空格
也称为: no-break space,non-breakable space (NBSP), hard space(硬空格), or fixed space
在HTML中,被编码为 或  ,宽度和普通空格一致。
在 Unicode 码点为 U+00A0 , 命名为Narrow No-Break Space
在 js 中是 \xA0
NBSP 是常用的编程和网页创建的行,不打破空间上的程序或文档的空间。
特性
- 禁止自动换行
- 禁止合并空白字符
在SGML、HTML、TEX与LATEX,把连续的空白字符(如空格符、换行符、tab符等)视作一个空格字符。
不间断空格最重要的作用就是 换行时不被打断:
比如:Mr Green , 你肯定不希望看到换行时被打断的
Mr
Green.
又或者速度 12 m/s, 如果变成这样:
12
m/s.
而是即使有空格,换行后,空格前后两个词 也出现在同一行
多行文本有最大数量限制
往多行文本插入数据的时候,一定要注意一下这个数据量的大小与多行文本最大数量之间的关系,若数据量>大于限制量,则插入失败。
多行文本的数量取值范围:0 ~ 1048576
默认2000
组织服务查询有限制,最多5000条
QueryExpression account = new QueryExpression("account");
account.ColumnSet.AddColumns("accountid", "new_invoicetelephone");
account.Criteria.AddCondition("statecode", ConditionOperator.Equal, 0);
var accountList = this.service.RetrieveMultiple(account);
Console.WriteLine(accountList.Entities.Count);
//客户主档数据
string sql = @"SELECT accountid,new_invoicetelephone,new_invoceadress,accountcategorycode
FROM account
WHERE statecode=0 and new_filestatus=2";
DataTable dt = this.crmBroker.Query(sql);
Console.WriteLine("===================================");
Console.WriteLine($"即将初始化【{dt.Rows.Count}】条数据");
Console.WriteLine("===================================");
Console.ReadLine();