金蝶云星空插件实战开发-新手入门教程-服务插件-自定义校验方法
阅读对象 :星空系统二次开发新手
需求场景 :在插件开发过程中,实现BOS不容易配置的单据数据校验。实现校验一个单据编号字段必须是11个字符。
开发语言 :C#
开发工具 :Visual Studio 2019
星空版本 :7.6.0
说明:本文前提是开发机已经安装好金蝶云星空系统和金蝶BOS IDE。
星空系统安装部署教程
云星空二次开发基础知识可以浏览以前的文章:
本文是承接“ 金蝶云星空插件实战开发-新手入门教程-服务插件 ”这篇教程。是在这篇教程的基础上做的扩展。
如果想要测试本文的代码,必须顺利完成服务插件的教程。打开服务插件的代码项目,在Visual Studio右侧的“解决方案资源管理器”中邮件点击服务插件工程,新建一个类,类名: PurchaseValidator.cs ,如下图所示:
既然创建的一个类文件,那下面就直接敲代码咯,代码如下:
using System;
using Kingdee.BOS;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.Validation;
namespace Test.K3Cloud.SCM.MyAppPlugin
public class PurchaseValidator : AbstractValidator
/// <summary>
/// 初始化
/// </summary>
/// <param name="validateContext"></param>
/// <param name="ctx"></param>
public override void InitializeConfiguration(ValidateContext validateContext, Context ctx)
base.InitializeConfiguration(validateContext, ctx);
if (validateContext.BusinessInfo != null)
EntityKey = validateContext.BusinessInfo.GetEntity(0).Key;
/// <summary>
/// 自定义校验
/// </summary>
/// <param name="dataEntities"></param>
/// <param name="validateContext"></param>
/// <param name="ctx"></param>
public override void Validate(ExtendedDataEntity[] dataEntities, ValidateContext validateContext, Context ctx)
if (validateContext.IgnoreWarning)
return; //警告已经被用户忽略,就不需要再次执行了
if (dataEntities == null || dataEntities.Length <= 0)
return;
// 循环校验每一个数据包(一个数据包对应一张单据)
foreach (var et in dataEntities)
// 订单编号在单据数据包中的字段名为:BillNo
string billNo = Convert.ToString(et.DataEntity["BillNo"]);
if (billNo.Length != 11)
validateContext.AddError(et, new ValidationErrorInfo(
"BillNo", // 出错的字段Key,可以空
Convert.ToString(et.DataEntity[0]), // 数据包内码,必填,后续操作会据此内码避开此数据包
et.DataEntityIndex, // 出错的数据包在全部数据包中的顺序
et.RowIndex, // 出错的数据行在全部数据行中的顺序,如果校验基于单据头,此为0
"Error 0", // 错误编码,可以任意设定一个字符,主要用于追查错误来源
"数据校验未通过,单据编号必须是11个字符", // 错误的详细提示信息
"单据合法性检查", // 错误的简明提示信息
ErrorLevel.FatalError // 错误级别
自定义校验器类需要继承 AbstractValidator 类。在自定义校验器类中,dataEntities 为客户端传递过来的单据的数据。可以多个单据同时操作,所以这里,单据数据是一个数组。上面代码中 et.DataEntity 是某个单据的数据包。
接下来我们在服务插件中注册自定义校验器。为了方便大家顺利阅读代码,下面将服务插件的完整代码贴出来。如下面代码所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kingdee.BOS;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Interaction;
using Newtonsoft.Json.Linq;
namespace Test.K3Cloud.SCM.MyAppPlugin
public class Class1: AbstractOperationServicePlugIn
// SpensorKey
private const string SpensorKey = "DefaultSpensorKey";
/// <summary>
/// 单据校验。
/// </summary>
/// <param name="e"></param>
public override void OnAddValidators(AddValidatorsEventArgs e)
base.OnAddValidators(e);
var purchaseValidator = new PurchaseValidator();
e.Validators.Add(purchaseValidator); // 注册自定义校验器
public override void EndOperationTransaction(EndOperationTransactionArgs e)
base.EndOperationTransaction(e);
// 当保存订单时
if (FormOperation.OperationName == "保存")
/// 构造错误信息
JArray errMsg = new JArray {
new JValue("01"),
new JValue("这是一条提示信息")
bool ignore = false; // 窗口显示状态,默认不显示
Option.TryGetVariableValue(SpensorKey, out ignore);
if (!ignore && !Option.HasInteractionFlag(SpensorKey))
KDInteractionException ie = ShowErrorMsg(Context, SpensorKey, ignore, errMsg);
throw ie;
/// <summary>
/// 信息提示窗口
/// </summary>
/// <param name="context">上下文对象</param>
/// <param name="spensorKey">窗口标识</param>
/// <param name="ignore">状态</param>
/// <param name="errorMsg">错误信息</param>
/// <returns></returns>
public static KDInteractionException ShowErrorMsg(Context context, string spensorKey, bool ignore, JArray errorMsg)
if (errorMsg.Count() != 2)
return null;
string titleMsg = "代码~|~信息";
string errMsg = "{0}~|~{1}";
K3DisplayerModel model = K3DisplayerModel.Create(context, titleMsg);
model.AddMessage(string.Format(errMsg, errorMsg[0].ToString(), errorMsg[1].ToString()));
model.Option.SetVariableValue(K3DisplayerModel.CST_FormTitle, "单据操作有以下信息出错,需要继续吗?");
model.OKButton.Caption = new LocaleValue("是");
model.CancelButton.Visible = model.OKButton.Visible = true;
model.CancelButton.Caption = new LocaleValue("否");
KDInteractionException ie = new KDInteractionException(spensorKey);
ie.InteractionContext.InteractionFormId = "BOS_K3Displayer";
ie.InteractionContext.K3DisplayerModel = model;