U9 无授权的模式WebAPI开发的总结

1、无需借助UBF开发平台开发WebAPI给第三方调用。

2、U9 无授权的模式WebAPI开发。

使用Visual Studio开发工具创建一个类库项目,引用以下几个文件:

  • UFSoft.UBF.MVC.dll
  • System.Web.Http.dll(这个文件要引用U9安装包里面的版本,因为现在的开发工具太新,自带的文 件版本高了。)
  • Newtonsoft.Json的版本要匹配,不同的场景,开发工具会有提示
  • 数据库查询需要引用:UFSoft.UBF.Util.DataAccess.dll、UFSoft.UBF.Sys.Database.dll
  • 重写上下文需要引用:UFIDA.U9.CBO.PubSV.dll和UFSoft.UBF.AopFrame.dll(重写上下文用,不管是调用U9的任何方法,都要重写上下文)

新建一个客开接口,命名为:CustomAPIController,类名固定为xxxxxContriller,而且不能有重名,继承的是ApiController。

/// <summary>

/// 无授权的模式

/// 部署配置:dll + xml 复制到 \Portal\ApplicationServer\Libs目录下

/// portal\OpenApiExtend.config 配置文件中添加节点

/// 新建项目时选择"类库(.NET Framework)",注意不是".NET Core"或".NET Standard",

/// 因为U9的依赖库都是基于传统.NET Framework的

/// </summary>

public class CustomAPIController : ApiController

{

/// <summary>

/// 根据供应商编码查询供应商

/// </summary>

/// <param name="input">请求参数(查询参数</param>

/// <returns>供应商列表</returns>

HttpPost

public SupplierQueryResultDTO Query(SupplierQueryInputDTO input)

{

......

}

}

总结了以下几点:

1、设计一个标准返回DTO对象,如下:

//初始化返回DTO的对象(赋默认值)

SupplierQueryResultDTO result = new SupplierQueryResultDTO

{

IsSuccessed = false, //前面2个是标准的写法

ErrMsg = string.Empty,

//需要展现给用户的结果数据(SupplierDTOData就是一个类,用来存储返回供应商数据。)

SupplierList = new List<SupplierDTOData>() *实际上就是一个实体对象,包含所有的要展现给用户的数据字段,返回的是一个JSON集合

};

2、防御性编码,避免空指针异常,或者参数不合法导致的异常

// 参数校验 上下文不能为空!

if (input == null)

throw new Exception("请求参数不能为空");

if (string.IsNullOrEmpty(input.EntCode))

throw new Exception("企业编码不能为空");

if (string.IsNullOrEmpty(input.OrgCode))

throw new Exception("组织编码不能为空");

if (string.IsNullOrEmpty(input.UserCode))

throw new Exception("用户编码不能为空");

3、编写具体的业务逻辑脚本,如提交,审核,查询,打印,导出,...可以用调用U9自带的WebService功能来实现用户需求。也可以自行扩展所需的功能,如与第三方系统的数据交互等应用场景。

// 2. 重写 U9 上下文(无授权模式的核心)

//引用 UFSoft.UBF.AopFrame.dll,使用里面的BPForEngine类

using (BPForEngine bp = new BPForEngine())

{

//要引用这个:UFIDA.U9.CBO.Pub.Controller

ContextDTO cdto = new ContextDTO();//用友自定义的DTO类

cdto.EntCode = input.EntCode; //接收一个请求参数中的相关信息 以下4个都是

cdto.OrgCode = input.OrgCode;

cdto.UserCode = input.UserCode;

cdto.CultureName = "zh-CN";

// ✅ 写入 U9 上下文

cdto.WriteToContext();//重写u9的上下文,关键是此处

// 3. 构造 U9 查询服务 - WebService的调用方式

//有二种方式:1.直接调用U9的服务类,UFIDA.U9.CBO.PubSV 2.通过WebService调用U9的服务类,UFIDA.U9.ISV.Supplier

//可以从ClassView中找到相关的信息

BatchQuerySupplierByDTOSRV srv = new BatchQuerySupplierByDTOSRV();

srv.QuerySupplierDTOs = new List<QuerySupplierDTO>();//U9的标准写法,批量查询的DTO集合

// 标准写法,因为是批量查询,成对要有一个单体的查询条件的DTO

QuerySupplierDTO queryDTO = new QuerySupplierDTO();

queryDTO.Supplier = new CommonArchiveDataDTO

{

Code = input.SupplierCode

};

queryDTO.Org = new CommonArchiveDataDTO

{

Code = Context.LoginOrg.Code

};

srv.QuerySupplierDTOs.Add(queryDTO);

// 4. 执行查询

//UFIDA.U9.ISV.Supplier.dll 里面有一个供应商的SupplierDTO实体类对象,可以用于存储数据,返回数据

List<SupplierDTO> list = srv.Do();//执行查询,返回一个供应商DTO的集合,里面包含了供应商的各种信息

// 5. 结果转换

foreach (var item in list)

{

result.SupplierList.Add(new SupplierDTOData

{

Code = item.Code,

ShortName = item.ShortName,

Org = long.TryParse(item.Org?.Code, out var orgCode) ? orgCode : 0,

StateTaxNo = item.StateTaxNo,

CreatedOn = item.CreatedOn,

CreatedBy = item.CreatedBy,

DescFlexField_PrivateDescSeg2= item.DescFlexField.ContextValue,

DescFlexField_PrivateDescSeg3 = item.DescFlexField.ContextValue

});

}

result.IsSuccessed = true;

result.ErrMsg = "success";

}

4、有二种DTO,一个用户要输入的形参集合(SupplierQueryInputDTO),一个返回的结果集合(见第1点SupplierDTOData)。

/// <summary>

/// 供应商查询输入参数

/// 一个请求中附带的各种查询条件(参数,DTO对象),用于业务逻辑处理组装代码时使用

/// </summary>

public class SupplierQueryInputDTO

{

/// <summary>

/// 企业编码

/// </summary>

public string EntCode { get; set; }// 企业编码

/// <summary>

/// 组织编码

/// </summary>

public string OrgCode { get; set; }// 组织编码

/// <summary>

/// 用户编码

/// </summary>

public string UserCode { get; set; }// 用户编码

/// <summary>

/// 供应商编码(支持模糊可扩展)

/// </summary>

public string SupplierCode { get; set; }// 供应商编码

}
using System;

/// <summary>

/// 供应商实体对象(对应表:U9DB.dbo.CBO_Supplier)

/// 由表结构生成,字段与数据库列一一对应,顺序与建表语句一致

/// </summary>

public class SupplierDTOData

{

public long ID { get; set; }// 主键ID

public DateTime CreatedOn { get; set; }// 创建时间

public string CreatedBy { get; set; }// 创建人

public DateTime ModifiedOn { get; set; }// 最后修改时间

public string ModifiedBy { get; set; }// 最后修改人

public long SysVersion { get; set; }// 系统版本号(乐观锁用)

public long Category { get; set; }// 供应商分类ID

public long Department { get; set; }// 部门ID

public long Purchaser { get; set; }// 采购员ID

public int TradeCategory { get; set; }// 行业分类

public string CorpUnifyCode { get; set; }// 统一社会信用代码

public string StateTaxNo { get; set; }// 国税登记号

public string DistrictTaxNo { get; set; }// 地税登记号

public int State { get; set; }// 状态

....

部署的要点:

  • 生成的xx.dll和xxx.xml放置到..Portal\ApplicationServer\Libs下
  • 在Portal\OpenApiExtend.config文件中手工配置dll文件路径

有一个配置文件,OpenApiExtend.config事例如下:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<configSections>

<section name="MyApi" type="UFSoft.UBF.MVC.Common.MyApi,UFSoft.UBF.MVC"/>

</configSections>

<MyApi

username="LYJ_API" url="\ApplicationServer\Libs\LYJ.U9C.WEBAPI.dll">

</MyApi>

</configuration>

效果如下:

相关推荐
机器学习之心1 小时前
198种组合算法+优化CNN-Transformer+SHAP分析+新数据预测+多输出!
1024程序员节
AI日报派送佬1 小时前
2026年10月24日AI行业日报|OpenAI离线训练前沿模型、Kimi K3.1 Pro上线API、Prism推理引擎开源
人工智能·openai·1024程序员节·ai智能体·kimi·ai日报
zzu123zsw1 小时前
为什么 Python 做 Agent 总在并发中崩溃?拆解 Blockcell 在 Rust 下的 Host-Cell 隔离与自愈状态机
开发语言·python·rust·大模型·ai agent
jiangliushi61 小时前
GPT-6.1 Sol 免费用:Python 读文件报 ‘gbk‘ codec can‘t decode?加一个参数就好
python·编码·1024程序员节
vibecoding771 小时前
Kimi K3.1 Pro 发布:2.8 万亿参数、Terminal-Bench 超 GPT-6 Astra,定价砍到 Opus 5.5 一半
人工智能·1024程序员节
黄俊懿1 小时前
【架构师从入门到进阶】第七章:缓存和存储的优化思路——第一节:缓存概述
数据结构·数据库·分布式·缓存·架构·系统架构·1024程序员节
iCxhust1 小时前
stm32f103c8t6 boot0设置
stm32·单片机·嵌入式硬件·1024程序员节
BullSmall1 小时前
开源 AI 赋能测试技术架构方案
1024程序员节